usebeeline 0.0.36 → 0.0.37
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/dist/usebeeline.mjs +282 -119
- package/package.json +1 -1
package/dist/usebeeline.mjs
CHANGED
|
@@ -309,10 +309,10 @@ __export(self_update_exports, {
|
|
|
309
309
|
});
|
|
310
310
|
import { createHash as createHash2 } from "node:crypto";
|
|
311
311
|
import { constants as fsConstants } from "node:fs";
|
|
312
|
-
import { access, chmod as chmod3, lstat as lstat2, mkdir as
|
|
312
|
+
import { access, chmod as chmod3, lstat as lstat2, mkdir as mkdir9, open, readFile as readFile4, rename as rename3, rm as rm4, symlink as symlink2, writeFile as writeFile6 } from "node:fs/promises";
|
|
313
313
|
import { spawn as spawn4 } from "node:child_process";
|
|
314
314
|
import { homedir as homedir9 } from "node:os";
|
|
315
|
-
import { dirname as dirname8, join as
|
|
315
|
+
import { dirname as dirname8, join as join6, resolve as resolve14 } from "node:path";
|
|
316
316
|
function anchorLayout(rawLibDir) {
|
|
317
317
|
const libDir = resolve14(rawLibDir);
|
|
318
318
|
const segments = libDir.split(/[/\\]/);
|
|
@@ -353,7 +353,7 @@ function hostPlatformKey() {
|
|
|
353
353
|
return `${os}-${arch}`;
|
|
354
354
|
}
|
|
355
355
|
function bundleJsonCandidates(bundleDir) {
|
|
356
|
-
return [
|
|
356
|
+
return [join6(bundleDir, "lib", "beeline", "bundle.json"), join6(bundleDir, "bundle.json")];
|
|
357
357
|
}
|
|
358
358
|
async function readBundleJson(bundleDir) {
|
|
359
359
|
let raw;
|
|
@@ -377,7 +377,7 @@ async function readBundleJson(bundleDir) {
|
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
function updateStatePath(layout) {
|
|
380
|
-
return
|
|
380
|
+
return join6(layout.releasesRoot, ".state", "update-state.json");
|
|
381
381
|
}
|
|
382
382
|
async function readUpdateState(layout) {
|
|
383
383
|
try {
|
|
@@ -387,8 +387,8 @@ async function readUpdateState(layout) {
|
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
389
|
async function writeUpdateState(layout, state) {
|
|
390
|
-
await
|
|
391
|
-
await
|
|
390
|
+
await mkdir9(join6(layout.releasesRoot, ".state"), { recursive: true });
|
|
391
|
+
await writeFile6(updateStatePath(layout), `${JSON.stringify(state, null, 2)}
|
|
392
392
|
`, "utf8");
|
|
393
393
|
}
|
|
394
394
|
async function readInstalledBundleIdentity(layout, _state = {}) {
|
|
@@ -469,7 +469,7 @@ function run(command, args, timeoutMs) {
|
|
|
469
469
|
});
|
|
470
470
|
}
|
|
471
471
|
function entrypointCandidates(bundleDir) {
|
|
472
|
-
return [
|
|
472
|
+
return [join6(bundleDir, BUNDLE_ENTRYPOINT), join6(bundleDir, "beeline-cli.mjs")];
|
|
473
473
|
}
|
|
474
474
|
async function resolveBundleEntrypoint(bundleDir) {
|
|
475
475
|
for (const candidate of entrypointCandidates(bundleDir)) {
|
|
@@ -491,8 +491,8 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
491
491
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
492
492
|
const log = opts.logger ?? ((line) => console.log(`[body] self-update: ${line}`));
|
|
493
493
|
const releaseId = sanitizeReleaseId(published.commit ?? published.version ?? `release-${Date.now()}`);
|
|
494
|
-
const releaseDir =
|
|
495
|
-
const okMarker =
|
|
494
|
+
const releaseDir = join6(layout.releasesRoot, releaseId);
|
|
495
|
+
const okMarker = join6(releaseDir, ".stage-ok");
|
|
496
496
|
let previouslyVerified = false;
|
|
497
497
|
try {
|
|
498
498
|
const recorded = await readFile4(okMarker, "utf8");
|
|
@@ -501,8 +501,8 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
501
501
|
previouslyVerified = true;
|
|
502
502
|
} catch {
|
|
503
503
|
}
|
|
504
|
-
await
|
|
505
|
-
const tempArchive =
|
|
504
|
+
await mkdir9(releaseDir, { recursive: true });
|
|
505
|
+
const tempArchive = join6(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
|
|
506
506
|
try {
|
|
507
507
|
log(`downloading ${published.file}`);
|
|
508
508
|
const response = await fetchImpl(archiveUrlFor(manifestUrl, published.file), {
|
|
@@ -522,7 +522,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
522
522
|
if (actual !== published.sha256.toLowerCase()) {
|
|
523
523
|
throw new Error(`checksum mismatch for ${published.file}: expected ${published.sha256}, got ${actual} \u2014 aborting without touching the installed bundle`);
|
|
524
524
|
}
|
|
525
|
-
await
|
|
525
|
+
await writeFile6(tempArchive, Buffer.concat(chunks), { mode: 384 });
|
|
526
526
|
const entries = (await new Promise((resolveList, rejectList) => {
|
|
527
527
|
const child = spawn4("tar", ["-tzf", tempArchive], { stdio: ["ignore", "pipe", "inherit"] });
|
|
528
528
|
let out = "";
|
|
@@ -542,18 +542,18 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
542
542
|
throw new Error(`extracting bundle failed: ${extract2.stderr}`);
|
|
543
543
|
for (const relative3 of requiredBundlePaths()) {
|
|
544
544
|
try {
|
|
545
|
-
await access(
|
|
545
|
+
await access(join6(releaseDir, relative3), fsConstants.F_OK);
|
|
546
546
|
} catch {
|
|
547
547
|
throw new Error(`staged bundle is missing ${relative3}`);
|
|
548
548
|
}
|
|
549
549
|
}
|
|
550
550
|
if (opts.smokeTestCli !== false) {
|
|
551
|
-
const probe = await run(process.execPath, [
|
|
551
|
+
const probe = await run(process.execPath, [join6(releaseDir, BUNDLE_ENTRYPOINT), "--version"], 6e4);
|
|
552
552
|
if (probe.status !== 0) {
|
|
553
553
|
throw new Error(`staged bundle failed its startup smoke test (--version exited ${probe.status})${probe.stderr ? `: ${probe.stderr.trim()}` : ""}`);
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
|
-
await
|
|
556
|
+
await writeFile6(okMarker, `${published.sha256}
|
|
557
557
|
`, "utf8");
|
|
558
558
|
log(`staged release ${releaseId} (sha256 verified)`);
|
|
559
559
|
return releaseId;
|
|
@@ -581,26 +581,26 @@ function forwarderScript(tool) {
|
|
|
581
581
|
}
|
|
582
582
|
async function replaceFile(path, contents, mode) {
|
|
583
583
|
const temp = `${path}.new-${process.pid}`;
|
|
584
|
-
await
|
|
584
|
+
await writeFile6(temp, contents, { mode });
|
|
585
585
|
await chmod3(temp, mode);
|
|
586
586
|
await rename3(temp, path);
|
|
587
587
|
}
|
|
588
588
|
async function activateRelease(layout, releaseId) {
|
|
589
|
-
const releaseDir =
|
|
590
|
-
await access(
|
|
591
|
-
await
|
|
592
|
-
await
|
|
589
|
+
const releaseDir = join6(layout.releasesRoot, releaseId);
|
|
590
|
+
await access(join6(releaseDir, BUNDLE_ENTRYPOINT), fsConstants.F_OK);
|
|
591
|
+
await mkdir9(layout.releasesRoot, { recursive: true });
|
|
592
|
+
await mkdir9(layout.binDir, { recursive: true });
|
|
593
593
|
let previousReleaseId = await activeReleaseId(layout);
|
|
594
594
|
const kind = await pathKind(layout.libDir);
|
|
595
595
|
if (kind === "directory") {
|
|
596
596
|
const legacyIdentity = await readBundleJson(layout.libDir);
|
|
597
597
|
const legacyId = sanitizeReleaseId(legacyIdentity?.commit ?? legacyIdentity?.version ?? `legacy-${Date.now()}`);
|
|
598
|
-
const legacyDir =
|
|
598
|
+
const legacyDir = join6(layout.releasesRoot, legacyId);
|
|
599
599
|
try {
|
|
600
600
|
await access(legacyDir, fsConstants.F_OK);
|
|
601
601
|
previousReleaseId = `${legacyId}-${Date.now()}`;
|
|
602
|
-
await rename3(layout.libDir,
|
|
603
|
-
await normalizeLegacyBundleShape(
|
|
602
|
+
await rename3(layout.libDir, join6(layout.releasesRoot, previousReleaseId));
|
|
603
|
+
await normalizeLegacyBundleShape(join6(layout.releasesRoot, previousReleaseId));
|
|
604
604
|
} catch {
|
|
605
605
|
await rename3(layout.libDir, legacyDir);
|
|
606
606
|
await normalizeLegacyBundleShape(legacyDir);
|
|
@@ -609,18 +609,18 @@ async function activateRelease(layout, releaseId) {
|
|
|
609
609
|
}
|
|
610
610
|
const tempLink = `${layout.libDir}.new-${process.pid}`;
|
|
611
611
|
await rm4(tempLink, { force: true });
|
|
612
|
-
await symlink2(
|
|
612
|
+
await symlink2(join6("beeline-releases", releaseId), tempLink);
|
|
613
613
|
await rename3(tempLink, layout.libDir);
|
|
614
614
|
await fsyncDir(dirname8(layout.libDir));
|
|
615
615
|
await writeBinForwarders(layout, releaseDir);
|
|
616
616
|
return { previousReleaseId };
|
|
617
617
|
}
|
|
618
618
|
async function normalizeLegacyBundleShape(bundleDir) {
|
|
619
|
-
const innerLib =
|
|
619
|
+
const innerLib = join6(bundleDir, "lib", "beeline");
|
|
620
620
|
let anyFlat = false;
|
|
621
621
|
for (const name of LEGACY_FLAT_BUNDLE_FILES) {
|
|
622
622
|
try {
|
|
623
|
-
await access(
|
|
623
|
+
await access(join6(bundleDir, name), fsConstants.F_OK);
|
|
624
624
|
anyFlat = true;
|
|
625
625
|
break;
|
|
626
626
|
} catch {
|
|
@@ -628,31 +628,31 @@ async function normalizeLegacyBundleShape(bundleDir) {
|
|
|
628
628
|
}
|
|
629
629
|
if (!anyFlat)
|
|
630
630
|
return;
|
|
631
|
-
await
|
|
631
|
+
await mkdir9(innerLib, { recursive: true });
|
|
632
632
|
for (const name of LEGACY_FLAT_BUNDLE_FILES) {
|
|
633
633
|
try {
|
|
634
|
-
await access(
|
|
634
|
+
await access(join6(innerLib, name), fsConstants.F_OK);
|
|
635
635
|
continue;
|
|
636
636
|
} catch {
|
|
637
637
|
}
|
|
638
|
-
await rename3(
|
|
638
|
+
await rename3(join6(bundleDir, name), join6(innerLib, name)).catch(() => void 0);
|
|
639
639
|
}
|
|
640
640
|
}
|
|
641
641
|
async function writeBinForwarders(layout, activeBundleRoot) {
|
|
642
642
|
for (const tool of FORWARDER_TOOLS) {
|
|
643
|
-
const target =
|
|
643
|
+
const target = join6(activeBundleRoot, "bin", tool);
|
|
644
644
|
try {
|
|
645
645
|
await access(target, fsConstants.X_OK);
|
|
646
646
|
} catch {
|
|
647
647
|
continue;
|
|
648
648
|
}
|
|
649
|
-
await replaceFile(
|
|
649
|
+
await replaceFile(join6(layout.binDir, tool), forwarderScript(tool), 493);
|
|
650
650
|
}
|
|
651
651
|
}
|
|
652
652
|
async function repairInstallForwarders(layout, opts = {}) {
|
|
653
653
|
if (await pathKind(layout.libDir) !== "symlink")
|
|
654
654
|
return false;
|
|
655
|
-
const forwarderPath =
|
|
655
|
+
const forwarderPath = join6(layout.binDir, "beeline");
|
|
656
656
|
let current;
|
|
657
657
|
try {
|
|
658
658
|
current = await readFile4(forwarderPath, "utf8");
|
|
@@ -661,25 +661,25 @@ async function repairInstallForwarders(layout, opts = {}) {
|
|
|
661
661
|
}
|
|
662
662
|
if (current === forwarderScript("beeline"))
|
|
663
663
|
return false;
|
|
664
|
-
await
|
|
664
|
+
await mkdir9(layout.binDir, { recursive: true });
|
|
665
665
|
await writeBinForwarders(layout, layout.libDir);
|
|
666
666
|
opts.logger?.(`[body] self-update: repaired <prefix>/bin forwarders to follow the active-bundle anchor (${layout.libDir})`);
|
|
667
667
|
return true;
|
|
668
668
|
}
|
|
669
669
|
async function rollbackToPreviousRelease(layout, previousReleaseId) {
|
|
670
|
-
const releaseDir =
|
|
670
|
+
const releaseDir = join6(layout.releasesRoot, previousReleaseId);
|
|
671
671
|
const entrypoint = await resolveBundleEntrypoint(releaseDir);
|
|
672
672
|
if (!entrypoint) {
|
|
673
673
|
throw new Error(`release ${previousReleaseId} has no runnable CLI entrypoint`);
|
|
674
674
|
}
|
|
675
675
|
const tempLink = `${layout.libDir}.rollback-${process.pid}`;
|
|
676
676
|
await rm4(tempLink, { force: true });
|
|
677
|
-
await symlink2(
|
|
677
|
+
await symlink2(join6("beeline-releases", previousReleaseId), tempLink);
|
|
678
678
|
await rename3(tempLink, layout.libDir);
|
|
679
679
|
await fsyncDir(dirname8(layout.libDir));
|
|
680
680
|
}
|
|
681
681
|
function updateAttemptPath(layout) {
|
|
682
|
-
return
|
|
682
|
+
return join6(layout.releasesRoot, ".state", "update-attempt.json");
|
|
683
683
|
}
|
|
684
684
|
async function readUpdateAttempt(layout) {
|
|
685
685
|
try {
|
|
@@ -693,10 +693,10 @@ async function readUpdateAttempt(layout) {
|
|
|
693
693
|
}
|
|
694
694
|
}
|
|
695
695
|
async function writeUpdateAttempt(layout, record2) {
|
|
696
|
-
await
|
|
696
|
+
await mkdir9(join6(layout.releasesRoot, ".state"), { recursive: true });
|
|
697
697
|
const path = updateAttemptPath(layout);
|
|
698
698
|
const staged = `${path}.${process.pid}.tmp`;
|
|
699
|
-
await
|
|
699
|
+
await writeFile6(staged, `${JSON.stringify(record2, null, 2)}
|
|
700
700
|
`, { mode: 384 });
|
|
701
701
|
await rename3(staged, path);
|
|
702
702
|
}
|
|
@@ -956,7 +956,7 @@ var init_self_update = __esm({
|
|
|
956
956
|
|
|
957
957
|
// apps/body/dist/cli.js
|
|
958
958
|
import { dirname as dirname13, resolve as resolve21 } from "node:path";
|
|
959
|
-
import { readFile as readFile9, unlink as unlink3, writeFile as
|
|
959
|
+
import { readFile as readFile9, unlink as unlink3, writeFile as writeFile12 } from "node:fs/promises";
|
|
960
960
|
import { stdin as stdin4, stdout as stdout5 } from "node:process";
|
|
961
961
|
|
|
962
962
|
// node_modules/@clack/core/dist/index.mjs
|
|
@@ -2954,6 +2954,12 @@ function cornerAutonomyModeCandidates(agentCommand) {
|
|
|
2954
2954
|
return [];
|
|
2955
2955
|
return ["agent", "edit", "code"];
|
|
2956
2956
|
}
|
|
2957
|
+
function roomModeCandidates(agentCommand, options = {}) {
|
|
2958
|
+
if (options.osSandbox && agentCommand && /(^|[/\\])codex-acp(\.[a-z]+)?$/i.test(agentCommand)) {
|
|
2959
|
+
return ["agent-full-access"];
|
|
2960
|
+
}
|
|
2961
|
+
return ["read-only", "readonly"];
|
|
2962
|
+
}
|
|
2957
2963
|
|
|
2958
2964
|
// apps/body/dist/harness-tool-scope.js
|
|
2959
2965
|
var CLAUDE_TOOL_SCOPE_SETTINGS = { disableClaudeAiConnectors: true };
|
|
@@ -3268,6 +3274,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
3268
3274
|
sessionCommands = /* @__PURE__ */ new Map();
|
|
3269
3275
|
supportsStandardSteering = false;
|
|
3270
3276
|
supportsSessionLoading = false;
|
|
3277
|
+
supportsImagePrompts = false;
|
|
3271
3278
|
alive = false;
|
|
3272
3279
|
/** Bounded tail of recent stderr, so a spawn/exit failure's rejection text
|
|
3273
3280
|
* carries the real reason (e.g. a harness's own "missing API key" notice)
|
|
@@ -3280,6 +3287,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
3280
3287
|
agentCwd;
|
|
3281
3288
|
inheritProcessEnv;
|
|
3282
3289
|
autoApprove;
|
|
3290
|
+
osSandbox;
|
|
3283
3291
|
permissionHandler;
|
|
3284
3292
|
permissionAllowlist;
|
|
3285
3293
|
constructor(opts) {
|
|
@@ -3295,6 +3303,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
3295
3303
|
this.agentCwd = opts.agentCwd;
|
|
3296
3304
|
this.inheritProcessEnv = opts.inheritProcessEnv ?? process.env.BUZZY_BODY_AGENT_ENV_INHERIT === "1";
|
|
3297
3305
|
this.autoApprove = opts.autoApprovePermissions ?? true;
|
|
3306
|
+
this.osSandbox = opts.osSandbox ?? false;
|
|
3298
3307
|
this.permissionHandler = opts.permissionHandler;
|
|
3299
3308
|
this.permissionAllowlist = opts.permissionAllowlist;
|
|
3300
3309
|
}
|
|
@@ -3354,6 +3363,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
3354
3363
|
this.supportsStandardSteering = steering?.supported === true;
|
|
3355
3364
|
const agentCapabilities = initResult.agentCapabilities;
|
|
3356
3365
|
this.supportsSessionLoading = agentCapabilities?.loadSession === true;
|
|
3366
|
+
this.supportsImagePrompts = agentCapabilities?.promptCapabilities?.image === true;
|
|
3357
3367
|
this.emit("initialized", initResult);
|
|
3358
3368
|
this.notify("notifications/initialized", {});
|
|
3359
3369
|
}
|
|
@@ -3400,6 +3410,10 @@ var AcpClient = class extends EventEmitter {
|
|
|
3400
3410
|
canLoadSession() {
|
|
3401
3411
|
return this.supportsSessionLoading;
|
|
3402
3412
|
}
|
|
3413
|
+
/** Whether this live ACP process accepts `image` prompt blocks (`promptCapabilities.image`). */
|
|
3414
|
+
canPromptWithImages() {
|
|
3415
|
+
return this.supportsImagePrompts;
|
|
3416
|
+
}
|
|
3403
3417
|
async sessionNew(opts) {
|
|
3404
3418
|
const params = {
|
|
3405
3419
|
cwd: opts.cwd,
|
|
@@ -3459,7 +3473,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
3459
3473
|
if (!mode)
|
|
3460
3474
|
return;
|
|
3461
3475
|
const modes = raw.modes;
|
|
3462
|
-
const candidates = mode === "readonly" ?
|
|
3476
|
+
const candidates = mode === "readonly" ? roomModeCandidates(this.agentLabel, { osSandbox: this.osSandbox }) : cornerAutonomyModeCandidates(this.agentLabel);
|
|
3463
3477
|
const target = modes?.availableModes?.find((candidate) => candidate.id && candidates.includes(candidate.id))?.id;
|
|
3464
3478
|
if (!target || modes?.currentModeId === target)
|
|
3465
3479
|
return;
|
|
@@ -3506,7 +3520,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
3506
3520
|
try {
|
|
3507
3521
|
const result = await this.request("session/prompt", {
|
|
3508
3522
|
sessionId,
|
|
3509
|
-
prompt: [{ type: "text", text: text2 }]
|
|
3523
|
+
prompt: typeof text2 === "string" ? [{ type: "text", text: text2 }] : [...text2]
|
|
3510
3524
|
}, timeoutMs, (id) => {
|
|
3511
3525
|
requestId = id;
|
|
3512
3526
|
});
|
|
@@ -3874,6 +3888,18 @@ function advertisedChoiceId(choice) {
|
|
|
3874
3888
|
return choice.value;
|
|
3875
3889
|
return void 0;
|
|
3876
3890
|
}
|
|
3891
|
+
function sortModelChoicesNewestFirst(choices) {
|
|
3892
|
+
return choices.map((choice, index) => ({ choice, index })).sort((left, right) => {
|
|
3893
|
+
const leftParts = left.choice.id.match(/\d+/g)?.map(Number) ?? [];
|
|
3894
|
+
const rightParts = right.choice.id.match(/\d+/g)?.map(Number) ?? [];
|
|
3895
|
+
for (let index = 0; index < Math.max(leftParts.length, rightParts.length); index += 1) {
|
|
3896
|
+
const delta = (rightParts[index] ?? -1) - (leftParts[index] ?? -1);
|
|
3897
|
+
if (delta !== 0)
|
|
3898
|
+
return delta;
|
|
3899
|
+
}
|
|
3900
|
+
return left.index - right.index;
|
|
3901
|
+
}).map(({ choice }) => choice);
|
|
3902
|
+
}
|
|
3877
3903
|
function parseAdvertisedConfigOptions(raw, preferredModelId, includeLaunchEffort = false) {
|
|
3878
3904
|
const configOptions = raw?.configOptions;
|
|
3879
3905
|
const result = [];
|
|
@@ -3903,7 +3929,7 @@ function parseAdvertisedConfigOptions(raw, preferredModelId, includeLaunchEffort
|
|
|
3903
3929
|
id,
|
|
3904
3930
|
category,
|
|
3905
3931
|
...typeof record2.currentValue === "string" ? { currentValue: record2.currentValue } : {},
|
|
3906
|
-
options: choices
|
|
3932
|
+
options: category === "model" ? sortModelChoicesNewestFirst(choices) : choices
|
|
3907
3933
|
});
|
|
3908
3934
|
}
|
|
3909
3935
|
const models = raw?.models;
|
|
@@ -3929,7 +3955,7 @@ function parseAdvertisedConfigOptions(raw, preferredModelId, includeLaunchEffort
|
|
|
3929
3955
|
id: GROK_SESSION_MODEL_AXIS_ID,
|
|
3930
3956
|
category: "model",
|
|
3931
3957
|
...currentModelId ? { currentValue: currentModelId } : {},
|
|
3932
|
-
options: modelChoices
|
|
3958
|
+
options: sortModelChoicesNewestFirst(modelChoices)
|
|
3933
3959
|
});
|
|
3934
3960
|
}
|
|
3935
3961
|
const effortModelId = preferredModelId ?? currentModelId;
|
|
@@ -4214,14 +4240,15 @@ async function applyRuntimeModelPreflight(config, agent, selection, validate = v
|
|
|
4214
4240
|
import { execFile as execFile3 } from "node:child_process";
|
|
4215
4241
|
import { createHash } from "node:crypto";
|
|
4216
4242
|
import { existsSync as existsSync4, mkdirSync } from "node:fs";
|
|
4217
|
-
import { mkdir as
|
|
4243
|
+
import { mkdir as mkdir6, rm as rm3 } from "node:fs/promises";
|
|
4218
4244
|
import { dirname as dirname4, resolve as resolve10 } from "node:path";
|
|
4219
4245
|
import { promisify as promisify3 } from "node:util";
|
|
4220
4246
|
|
|
4221
4247
|
// apps/body/dist/monolith-corner-turn.js
|
|
4222
4248
|
import { execFile as execFile2 } from "node:child_process";
|
|
4223
|
-
import { mkdir as
|
|
4249
|
+
import { mkdir as mkdir4 } from "node:fs/promises";
|
|
4224
4250
|
import { homedir as homedir5 } from "node:os";
|
|
4251
|
+
import { join as join4 } from "node:path";
|
|
4225
4252
|
import { promisify as promisify2 } from "node:util";
|
|
4226
4253
|
|
|
4227
4254
|
// apps/body/dist/agent-home.js
|
|
@@ -4241,9 +4268,10 @@ var BEELINE_ROOM_CAPABILITIES = [
|
|
|
4241
4268
|
"Tag another agent only when you need something from them: a question, a handoff, a task. Never tag to acknowledge, agree, or say you are ready. If nothing is actionable, do not reply.",
|
|
4242
4269
|
"Tag the user only when you need a decision or input, or when the task they asked for is finished. Never tag for progress, acknowledgement, or questions the transcript already answers.",
|
|
4243
4270
|
"Every MCP server mounted into this session is approved tool by tool - use operator and host tools freely; the read-only filesystem sandbox is the boundary, not a tool list. Network web search is enabled.",
|
|
4271
|
+
"Files and photos people share are downloaded for you: read them at the local path named in the prompt (photos may also arrive inline); never fetch the reference URL.",
|
|
4244
4272
|
"To send a file, call beeline-agent attach_file with a path inside your checkout; it is attached to your reply.",
|
|
4245
4273
|
"To run something later or repeatedly, call beeline-agent create_schedule (interval in minutes or a 5-field cron, optional maxRuns); list_schedules / delete_schedule manage them.",
|
|
4246
|
-
"When repository work is needed, you MUST call beeline-agent open_corner with a
|
|
4274
|
+
"When repository work is needed, you MUST call beeline-agent open_corner with a complete objective of no more than 24 words. The host-governed call is the only way to start write work.",
|
|
4247
4275
|
"Never claim an action or reply happened unless the prompt or a tool result proves it."
|
|
4248
4276
|
].join(" ");
|
|
4249
4277
|
var BEELINE_DM_CAPABILITIES = [
|
|
@@ -4251,6 +4279,7 @@ var BEELINE_DM_CAPABILITIES = [
|
|
|
4251
4279
|
"This Room is strictly conversational: there is no repository binding and no corner can be opened from here.",
|
|
4252
4280
|
"The repository filesystem is read-only in this session.",
|
|
4253
4281
|
"Every MCP server mounted into this session is approved tool by tool - use operator and host tools freely; the read-only filesystem sandbox is the boundary, not a tool list. Network web search is enabled.",
|
|
4282
|
+
"Files and photos people share are downloaded for you: read them at the local path named in the prompt (photos may also arrive inline); never fetch the reference URL.",
|
|
4254
4283
|
"To send a file, call beeline-agent attach_file with a path inside your checkout; it is attached to your reply.",
|
|
4255
4284
|
"Tag the person only when you need a decision or input, or when the task they asked for is finished.",
|
|
4256
4285
|
"Never claim an action or reply happened unless the prompt or a tool result proves it."
|
|
@@ -4494,6 +4523,39 @@ var PI_CUSTOM_MODEL_CONFIG = {
|
|
|
4494
4523
|
source: ".pi/agent/models.json",
|
|
4495
4524
|
target: "models.json"
|
|
4496
4525
|
};
|
|
4526
|
+
var OPENROUTER_RELIABLE_PROVIDERS = ["deepinfra", "novita"];
|
|
4527
|
+
function withReliableOpenRouterRouting(value) {
|
|
4528
|
+
const root = value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
|
|
4529
|
+
const routing = {
|
|
4530
|
+
only: [...OPENROUTER_RELIABLE_PROVIDERS],
|
|
4531
|
+
order: [...OPENROUTER_RELIABLE_PROVIDERS],
|
|
4532
|
+
allow_fallbacks: false,
|
|
4533
|
+
require_parameters: true
|
|
4534
|
+
};
|
|
4535
|
+
if (Array.isArray(root.providers)) {
|
|
4536
|
+
const providers2 = root.providers.map((provider) => provider && typeof provider === "object" ? { ...provider } : provider);
|
|
4537
|
+
const index = providers2.findIndex((provider) => provider && typeof provider === "object" && provider.name === "openrouter");
|
|
4538
|
+
const current2 = index >= 0 ? providers2[index] : { name: "openrouter" };
|
|
4539
|
+
const compat2 = current2.compat && typeof current2.compat === "object" && !Array.isArray(current2.compat) ? { ...current2.compat } : {};
|
|
4540
|
+
current2.compat = { ...compat2, openRouterRouting: routing };
|
|
4541
|
+
if (index >= 0)
|
|
4542
|
+
providers2[index] = current2;
|
|
4543
|
+
else
|
|
4544
|
+
providers2.push(current2);
|
|
4545
|
+
root.providers = providers2;
|
|
4546
|
+
return root;
|
|
4547
|
+
}
|
|
4548
|
+
const providers = root.providers && typeof root.providers === "object" ? { ...root.providers } : {};
|
|
4549
|
+
const current = providers.openrouter && typeof providers.openrouter === "object" && !Array.isArray(providers.openrouter) ? { ...providers.openrouter } : {};
|
|
4550
|
+
const compat = current.compat && typeof current.compat === "object" && !Array.isArray(current.compat) ? { ...current.compat } : {};
|
|
4551
|
+
current.compat = {
|
|
4552
|
+
...compat,
|
|
4553
|
+
openRouterRouting: routing
|
|
4554
|
+
};
|
|
4555
|
+
providers.openrouter = current;
|
|
4556
|
+
root.providers = providers;
|
|
4557
|
+
return root;
|
|
4558
|
+
}
|
|
4497
4559
|
var CODEX_ROOM_AGENT_LOCKDOWN_TOML = "[agents]\nenabled = false\n";
|
|
4498
4560
|
var CODEX_ROOM_WEB_SEARCH_TOML = "[features]\nstandalone_web_search = true\n";
|
|
4499
4561
|
var HOME_SUBDIRS = ["user", "claude", "codex", "grok", "pi", "state", "cache", "tmp"];
|
|
@@ -4593,7 +4655,8 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed) {
|
|
|
4593
4655
|
try {
|
|
4594
4656
|
const sourceStats = await lstat(source).catch(() => void 0);
|
|
4595
4657
|
if (!sourceStats) {
|
|
4596
|
-
await
|
|
4658
|
+
await writeIsolatedHarnessFile(target, `${JSON.stringify(withReliableOpenRouterRouting({}), null, 2)}
|
|
4659
|
+
`);
|
|
4597
4660
|
return;
|
|
4598
4661
|
}
|
|
4599
4662
|
if (!sourceStats.isFile() || sourceStats.isSymbolicLink() || sourceStats.nlink !== 1) {
|
|
@@ -4603,7 +4666,9 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed) {
|
|
|
4603
4666
|
if (resolvedSource !== source) {
|
|
4604
4667
|
throw new AgentHomeSecurityError(`Pi custom model config resolves through a link: ${source}`);
|
|
4605
4668
|
}
|
|
4606
|
-
|
|
4669
|
+
const sourceValue = JSON.parse(readFileSync4(resolvedSource, "utf8"));
|
|
4670
|
+
await writeIsolatedHarnessFile(target, `${JSON.stringify(withReliableOpenRouterRouting(sourceValue), null, 2)}
|
|
4671
|
+
`);
|
|
4607
4672
|
} catch (error) {
|
|
4608
4673
|
await unlink(target).catch(() => void 0);
|
|
4609
4674
|
if (failClosed)
|
|
@@ -4829,6 +4894,88 @@ function harnessStateDirsFromEnv(env) {
|
|
|
4829
4894
|
return { stateDirs, ...tmp ? { tmpDir: resolve6(tmp) } : {} };
|
|
4830
4895
|
}
|
|
4831
4896
|
|
|
4897
|
+
// apps/body/dist/attachment-delivery.js
|
|
4898
|
+
import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
|
|
4899
|
+
import { basename as basename4, extname, join as join2 } from "node:path";
|
|
4900
|
+
var MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
|
|
4901
|
+
var FETCH_TIMEOUT_MS = 3e4;
|
|
4902
|
+
function safeFileName(attachment, index, taken) {
|
|
4903
|
+
const raw = basename4(attachment.name ?? "").replace(/[^\w.-]+/g, "_").replace(/^\.+/, "");
|
|
4904
|
+
let name = raw || `attachment-${index + 1}`;
|
|
4905
|
+
if (taken.has(name)) {
|
|
4906
|
+
const ext = extname(name);
|
|
4907
|
+
name = `${name.slice(0, name.length - ext.length)}-${index + 1}${ext}`;
|
|
4908
|
+
}
|
|
4909
|
+
taken.add(name);
|
|
4910
|
+
return name;
|
|
4911
|
+
}
|
|
4912
|
+
async function deliverAttachments(attachments, dir, fetchImpl = fetch) {
|
|
4913
|
+
if (!attachments.length)
|
|
4914
|
+
return [];
|
|
4915
|
+
const taken = /* @__PURE__ */ new Set();
|
|
4916
|
+
await mkdir2(dir, { recursive: true });
|
|
4917
|
+
return Promise.all(attachments.map(async (attachment, index) => {
|
|
4918
|
+
const tooLarge = (bytes) => ({
|
|
4919
|
+
attachment,
|
|
4920
|
+
reason: `skipped: ${bytes} bytes exceeds the ${MAX_ATTACHMENT_BYTES}-byte limit`
|
|
4921
|
+
});
|
|
4922
|
+
if (attachment.size && attachment.size > MAX_ATTACHMENT_BYTES)
|
|
4923
|
+
return tooLarge(attachment.size);
|
|
4924
|
+
try {
|
|
4925
|
+
const response = await fetchImpl(attachment.url, {
|
|
4926
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
4927
|
+
});
|
|
4928
|
+
if (!response.ok)
|
|
4929
|
+
throw new Error(`HTTP ${response.status}`);
|
|
4930
|
+
const declared = Number(response.headers.get("content-length") ?? 0);
|
|
4931
|
+
if (declared > MAX_ATTACHMENT_BYTES)
|
|
4932
|
+
return tooLarge(declared);
|
|
4933
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
4934
|
+
if (bytes.length > MAX_ATTACHMENT_BYTES)
|
|
4935
|
+
return tooLarge(bytes.length);
|
|
4936
|
+
const path = join2(dir, safeFileName(attachment, index, taken));
|
|
4937
|
+
await writeFile2(path, bytes);
|
|
4938
|
+
const mimeType = attachment.mimeType ?? response.headers.get("content-type") ?? "";
|
|
4939
|
+
return {
|
|
4940
|
+
attachment,
|
|
4941
|
+
path,
|
|
4942
|
+
...mimeType.startsWith("image/") ? { image: { data: bytes.toString("base64"), mimeType } } : {}
|
|
4943
|
+
};
|
|
4944
|
+
} catch (error) {
|
|
4945
|
+
return {
|
|
4946
|
+
attachment,
|
|
4947
|
+
reason: `download failed: ${error instanceof Error ? error.message : String(error)}`
|
|
4948
|
+
};
|
|
4949
|
+
}
|
|
4950
|
+
}));
|
|
4951
|
+
}
|
|
4952
|
+
function withoutImageData(delivered) {
|
|
4953
|
+
return delivered.map(({ image: _image, ...rest }) => rest);
|
|
4954
|
+
}
|
|
4955
|
+
function attachmentPromptLines(attachments, delivered) {
|
|
4956
|
+
if (!attachments.length)
|
|
4957
|
+
return [];
|
|
4958
|
+
const byUrl = new Map(delivered?.map((entry) => [entry.attachment.url, entry]) ?? []);
|
|
4959
|
+
return [
|
|
4960
|
+
"Attachments shared with this message (read the local file; the trailing URL is only a reference, do not download it):",
|
|
4961
|
+
...attachments.map((attachment) => {
|
|
4962
|
+
const kind = attachment.mimeType?.startsWith("image/") ? "image" : "file";
|
|
4963
|
+
const metadata = [attachment.mimeType, attachment.size ? `${attachment.size} bytes` : ""].filter(Boolean).join(", ");
|
|
4964
|
+
const entry = byUrl.get(attachment.url);
|
|
4965
|
+
const location = entry?.path ? `local file ${entry.path}` : entry?.reason ?? "no local copy in this session";
|
|
4966
|
+
return `- ${kind}: ${attachment.name ?? "attachment"}${metadata ? ` (${metadata})` : ""}: ${location} (source ${attachment.url})`;
|
|
4967
|
+
})
|
|
4968
|
+
];
|
|
4969
|
+
}
|
|
4970
|
+
function attachmentImageBlocks(delivered, harnessAcceptsImages) {
|
|
4971
|
+
if (!harnessAcceptsImages)
|
|
4972
|
+
return [];
|
|
4973
|
+
return delivered.flatMap((entry) => entry.image ? [{ type: "image", data: entry.image.data, mimeType: entry.image.mimeType }] : []);
|
|
4974
|
+
}
|
|
4975
|
+
function promptWithImages(text2, images) {
|
|
4976
|
+
return images.length ? [{ type: "text", text: text2 }, ...images] : text2;
|
|
4977
|
+
}
|
|
4978
|
+
|
|
4832
4979
|
// apps/body/dist/reply-sanitizer.js
|
|
4833
4980
|
var CODEX_NOTICE = /^(?:⚠(?:️)?\s*)?(?:warning|notice):\s*(?:skill|tool|plugin) descriptions?\b.*\b(?:context budget|budget limit)\b/i;
|
|
4834
4981
|
var CODEX_CONTINUATION = /^(?:codex can still (?:see|access|read)|(?:use|open|read)\s+\S*skill\.md\b)/i;
|
|
@@ -5311,7 +5458,7 @@ function detectBwrapSandbox(options = {}) {
|
|
|
5311
5458
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
5312
5459
|
import { execFile } from "node:child_process";
|
|
5313
5460
|
import { closeSync, openSync } from "node:fs";
|
|
5314
|
-
import { mkdir as
|
|
5461
|
+
import { mkdir as mkdir3, readFile, readdir as readdir2, rename as rename2, stat, writeFile as writeFile3 } from "node:fs/promises";
|
|
5315
5462
|
import { homedir as homedir4 } from "node:os";
|
|
5316
5463
|
import { dirname as dirname3, resolve as resolve9 } from "node:path";
|
|
5317
5464
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -9701,7 +9848,7 @@ function alphabet(letters) {
|
|
|
9701
9848
|
};
|
|
9702
9849
|
}
|
|
9703
9850
|
// @__NO_SIDE_EFFECTS__
|
|
9704
|
-
function
|
|
9851
|
+
function join3(separator = "") {
|
|
9705
9852
|
astr("join", separator);
|
|
9706
9853
|
return {
|
|
9707
9854
|
encode: (from) => {
|
|
@@ -9831,8 +9978,8 @@ var base64 = hasBase64Builtin ? {
|
|
|
9831
9978
|
decode(s) {
|
|
9832
9979
|
return decodeBase64Builtin(s, false);
|
|
9833
9980
|
}
|
|
9834
|
-
} : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */
|
|
9835
|
-
var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */
|
|
9981
|
+
} : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join3(""));
|
|
9982
|
+
var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join3(""));
|
|
9836
9983
|
var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
9837
9984
|
function bech32Polymod(pre) {
|
|
9838
9985
|
const b = pre >> 25;
|
|
@@ -13888,9 +14035,9 @@ function runtimeAgentCommand(runtime) {
|
|
|
13888
14035
|
}
|
|
13889
14036
|
async function writeRuntimeRecord(runtime) {
|
|
13890
14037
|
const path = runtimeConfigPath(runtime.supervisorRoot, runtime.agent.publicKey);
|
|
13891
|
-
await
|
|
14038
|
+
await mkdir3(dirname3(path), { recursive: true, mode: 448 });
|
|
13892
14039
|
const staged = `${path}.${process.pid}.tmp`;
|
|
13893
|
-
await
|
|
14040
|
+
await writeFile3(staged, `${JSON.stringify(runtime, null, 2)}
|
|
13894
14041
|
`, { mode: 384 });
|
|
13895
14042
|
await rename2(staged, path);
|
|
13896
14043
|
return path;
|
|
@@ -14029,7 +14176,7 @@ async function stopRuntimeDaemon(path, opts = {}) {
|
|
|
14029
14176
|
}
|
|
14030
14177
|
async function launchRuntimeDaemon(configPath, opts = {}) {
|
|
14031
14178
|
const directory = dirname3(configPath);
|
|
14032
|
-
await
|
|
14179
|
+
await mkdir3(directory, { recursive: true, mode: 448 });
|
|
14033
14180
|
const foreground = opts.foreground === true;
|
|
14034
14181
|
const output = foreground ? "inherit" : openSync(resolve9(directory, "daemon.log"), "a", 384);
|
|
14035
14182
|
const entrypoint = opts.entrypoint ?? process.argv[1];
|
|
@@ -14053,7 +14200,7 @@ async function launchRuntimeDaemon(configPath, opts = {}) {
|
|
|
14053
14200
|
async function removeAgentRuntime(runtime) {
|
|
14054
14201
|
const source = runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey);
|
|
14055
14202
|
const deletedRoot = resolve9(runtime.supervisorRoot, "beeline", "deleted-runtimes");
|
|
14056
|
-
await
|
|
14203
|
+
await mkdir3(deletedRoot, { recursive: true, mode: 448 });
|
|
14057
14204
|
const target = resolve9(deletedRoot, `${runtime.agent.publicKey}-${Date.now()}`);
|
|
14058
14205
|
await rename2(source, target);
|
|
14059
14206
|
return target;
|
|
@@ -14206,6 +14353,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
14206
14353
|
forcedStop = false;
|
|
14207
14354
|
draftTail = Promise.resolve();
|
|
14208
14355
|
activityTail = Promise.resolve();
|
|
14356
|
+
/** Session scratch directory attachments are downloaded into (`TMPDIR/beeline-attachments`). */
|
|
14357
|
+
attachmentDir;
|
|
14209
14358
|
constructor(options) {
|
|
14210
14359
|
this.options = options;
|
|
14211
14360
|
this.agent = runtimeIdentity(options.runtime.agent);
|
|
@@ -14243,7 +14392,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
14243
14392
|
}),
|
|
14244
14393
|
this.roster()
|
|
14245
14394
|
]);
|
|
14246
|
-
await
|
|
14395
|
+
await mkdir4(this.options.worktreePath, { recursive: true });
|
|
14247
14396
|
const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
|
|
14248
14397
|
root: this.options.config.agentHomeRoot,
|
|
14249
14398
|
sharedSkills: this.options.config.sharedSkills ?? [],
|
|
@@ -14264,8 +14413,9 @@ var MonolithCornerTurnLoop = class {
|
|
|
14264
14413
|
}, selection);
|
|
14265
14414
|
const operatorHome = this.options.config.operatorHome ?? homedir5();
|
|
14266
14415
|
const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
|
|
14416
|
+
this.attachmentDir = tmpDir ? join4(tmpDir, "beeline-attachments") : void 0;
|
|
14267
14417
|
const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
|
|
14268
|
-
await Promise.all(homeStateDirs.map((dir) =>
|
|
14418
|
+
await Promise.all(homeStateDirs.map((dir) => mkdir4(dir, { recursive: true })));
|
|
14269
14419
|
const spawnCommand = wrapAgentCommand({
|
|
14270
14420
|
bwrapPath: this.options.config.bwrapPath,
|
|
14271
14421
|
spec: {
|
|
@@ -14330,6 +14480,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
14330
14480
|
"Work normally with the full coding tools. Commit and push only this feature branch. Use gh to open its pull request.",
|
|
14331
14481
|
"PR-opening turn rule: as soon as a pull request exists, print its full GitHub URL as your final response and end the turn immediately. Do not call pr_checks_status in that same turn and do not wait for checks inside it. Then stay idle until a later corner fact or human message starts another turn.",
|
|
14332
14482
|
'Never merge because local tests pass or because gh reports passing checks. On a later turn triggered by a server-posted checks-passed note, call beeline-agent pr_checks_status. Merge only when it returns checks="passed", held=false, and approvalPending=false.',
|
|
14483
|
+
"Merge the PR yourself only after the checks-passed event shows every check green; if any check failed or is still running, say exactly which and stop - never merge red.",
|
|
14333
14484
|
"If any human in this corner says hold or do not merge, do not merge until a later human explicitly resumes it.",
|
|
14334
14485
|
"Do not tag the user when a corner turn finishes: the server posts the merge summary card and its push already cover completion. Tag a human only mid-turn, and only when you need a decision or input.",
|
|
14335
14486
|
"A human approval in the app asks the server to merge. When approval is pending, wait for the server close request instead of racing it with gh. If checks passed, no hold exists, and no approval is pending, merge the pull request yourself with gh.",
|
|
@@ -14355,7 +14506,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
14355
14506
|
}
|
|
14356
14507
|
};
|
|
14357
14508
|
}
|
|
14358
|
-
async prompt(requestId, trigger) {
|
|
14509
|
+
async prompt(requestId, trigger, attachments = []) {
|
|
14359
14510
|
const { api, cornerId } = this.options;
|
|
14360
14511
|
await api.execute("postAgentTurnReceipt", {
|
|
14361
14512
|
agentId: this.agent.publicKey,
|
|
@@ -14369,9 +14520,10 @@ var MonolithCornerTurnLoop = class {
|
|
|
14369
14520
|
if (this.forcedStop)
|
|
14370
14521
|
throw new Error("corner turn stopped for daemon handoff");
|
|
14371
14522
|
this.busy = true;
|
|
14372
|
-
const [conversation, roster] = await Promise.all([
|
|
14523
|
+
const [conversation, roster, delivered] = await Promise.all([
|
|
14373
14524
|
api.execute("getRoomConversation", { roomId: cornerId, limit: 200 }),
|
|
14374
|
-
this.roster()
|
|
14525
|
+
this.roster(),
|
|
14526
|
+
this.attachmentDir && attachments.length ? deliverAttachments(attachments, join4(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([])
|
|
14375
14527
|
]);
|
|
14376
14528
|
const names = new Map(roster.members.map((member) => [member.identityId, member.name]));
|
|
14377
14529
|
const transcript = conversation.items.slice(-120).map((message) => `${names.get(message.authorId) ?? "Beeline"} [${message.type}]: ${message.body}`).join("\n");
|
|
@@ -14381,8 +14533,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
14381
14533
|
${this.options.objective}`,
|
|
14382
14534
|
transcript ? `Corner transcript:
|
|
14383
14535
|
${transcript}` : "",
|
|
14384
|
-
`Newest trigger:
|
|
14385
|
-
${trigger}`,
|
|
14536
|
+
[`Newest trigger:
|
|
14537
|
+
${trigger}`, ...attachmentPromptLines(attachments, delivered)].join("\n"),
|
|
14386
14538
|
"Continue the objective. Obey the PR checks and human hold rules in your session instructions.",
|
|
14387
14539
|
MAINTAIN_ASSIGNED_IDENTITY_DIRECTIVE
|
|
14388
14540
|
].filter(Boolean).join("\n\n");
|
|
@@ -14439,7 +14591,7 @@ ${trigger}`,
|
|
|
14439
14591
|
});
|
|
14440
14592
|
});
|
|
14441
14593
|
};
|
|
14442
|
-
const result = await this.client.sessionPrompt(sessionId, prompt, 12e4, (_delta, full) => {
|
|
14594
|
+
const result = await this.client.sessionPrompt(sessionId, promptWithImages(prompt, attachmentImageBlocks(delivered, this.client.canPromptWithImages())), 12e4, (_delta, full) => {
|
|
14443
14595
|
postNarrationSegments(full);
|
|
14444
14596
|
this.draftTail = this.draftTail.catch(() => void 0).then(() => api.execute("postAgentDraft", {
|
|
14445
14597
|
agentId: this.agent.publicKey,
|
|
@@ -14533,7 +14685,7 @@ ${pullRequest}`,
|
|
|
14533
14685
|
});
|
|
14534
14686
|
if (!authority.member || authority.principalKind !== "human")
|
|
14535
14687
|
continue;
|
|
14536
|
-
await this.prompt(item.id, item.body);
|
|
14688
|
+
await this.prompt(item.id, item.body, item.attachments);
|
|
14537
14689
|
pollWithoutWait = true;
|
|
14538
14690
|
continue;
|
|
14539
14691
|
}
|
|
@@ -14574,8 +14726,9 @@ async function wait(ms, signal) {
|
|
|
14574
14726
|
}
|
|
14575
14727
|
|
|
14576
14728
|
// apps/body/dist/monolith-room-turn.js
|
|
14577
|
-
import { mkdir as
|
|
14729
|
+
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
14578
14730
|
import { homedir as homedir6 } from "node:os";
|
|
14731
|
+
import { join as join5 } from "node:path";
|
|
14579
14732
|
|
|
14580
14733
|
// packages/api-contract/dist/scheduled-prompts.js
|
|
14581
14734
|
var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
|
|
@@ -14641,6 +14794,10 @@ var MonolithRoomTurnLoop = class {
|
|
|
14641
14794
|
draftTail = Promise.resolve();
|
|
14642
14795
|
activeTurn;
|
|
14643
14796
|
queuedTurns = [];
|
|
14797
|
+
/** Session scratch directory attachments are downloaded into (`TMPDIR/beeline-attachments`). */
|
|
14798
|
+
attachmentDir;
|
|
14799
|
+
/** Local copies already delivered this session, by message id, so transcript renders reuse them. */
|
|
14800
|
+
deliveredAttachments = /* @__PURE__ */ new Map();
|
|
14644
14801
|
constructor(options) {
|
|
14645
14802
|
this.options = options;
|
|
14646
14803
|
this.agent = runtimeIdentity(options.runtime.agent);
|
|
@@ -14667,6 +14824,17 @@ var MonolithRoomTurnLoop = class {
|
|
|
14667
14824
|
workspaceId: this.options.workspaceId
|
|
14668
14825
|
});
|
|
14669
14826
|
}
|
|
14827
|
+
/** Download a message's attachments into the session scratch directory once. */
|
|
14828
|
+
async deliver(item) {
|
|
14829
|
+
if (!item.attachments.length || !this.attachmentDir)
|
|
14830
|
+
return [];
|
|
14831
|
+
const cached = this.deliveredAttachments.get(item.id);
|
|
14832
|
+
if (cached)
|
|
14833
|
+
return cached;
|
|
14834
|
+
const delivered = await deliverAttachments(item.attachments, join5(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl);
|
|
14835
|
+
this.deliveredAttachments.set(item.id, withoutImageData(delivered));
|
|
14836
|
+
return delivered;
|
|
14837
|
+
}
|
|
14670
14838
|
async activate() {
|
|
14671
14839
|
if (this.client?.isAlive && this.sessionId)
|
|
14672
14840
|
return this.sessionId;
|
|
@@ -14679,7 +14847,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
14679
14847
|
this.options.api.execute("getRoomRepositoryState", { roomId: this.options.roomId })
|
|
14680
14848
|
]);
|
|
14681
14849
|
const directMessage = Array.isArray(repositoryState.directParticipants) && repositoryState.directParticipants.length === 2;
|
|
14682
|
-
await
|
|
14850
|
+
await mkdir5(this.options.cwd, { recursive: true });
|
|
14683
14851
|
const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
|
|
14684
14852
|
root: this.options.config.agentHomeRoot,
|
|
14685
14853
|
sharedSkills: this.options.config.sharedSkills ?? [],
|
|
@@ -14695,8 +14863,9 @@ var MonolithRoomTurnLoop = class {
|
|
|
14695
14863
|
}, selection);
|
|
14696
14864
|
const operatorHome = this.options.config.operatorHome ?? homedir6();
|
|
14697
14865
|
const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
|
|
14866
|
+
this.attachmentDir = tmpDir ? join5(tmpDir, "beeline-attachments") : void 0;
|
|
14698
14867
|
const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
|
|
14699
|
-
await Promise.all(homeStateDirs.map((dir) =>
|
|
14868
|
+
await Promise.all(homeStateDirs.map((dir) => mkdir5(dir, { recursive: true })));
|
|
14700
14869
|
const spawnCommand = wrapAgentCommand({
|
|
14701
14870
|
bwrapPath: this.options.config.bwrapPath,
|
|
14702
14871
|
spec: {
|
|
@@ -14716,6 +14885,9 @@ var MonolithRoomTurnLoop = class {
|
|
|
14716
14885
|
agentEnv,
|
|
14717
14886
|
agentCwd: this.options.cwd,
|
|
14718
14887
|
agentLabel: command,
|
|
14888
|
+
// `bwrapPath` is set only when `detectBwrapSandbox` passed its self-test
|
|
14889
|
+
// (`config.ts`), which is exactly when `wrapAgentCommand` above wraps.
|
|
14890
|
+
osSandbox: Boolean(this.options.config.bwrapPath),
|
|
14719
14891
|
autoApprovePermissions: false,
|
|
14720
14892
|
permissionAllowlist: isRoomMcpPermissionRequest
|
|
14721
14893
|
};
|
|
@@ -14796,11 +14968,11 @@ var MonolithRoomTurnLoop = class {
|
|
|
14796
14968
|
active.steers.push(item);
|
|
14797
14969
|
active.steerTail = active.steerTail.catch(() => void 0).then(async () => {
|
|
14798
14970
|
try {
|
|
14799
|
-
const roster = await this.roster();
|
|
14971
|
+
const [roster, delivered] = await Promise.all([this.roster(), this.deliver(item)]);
|
|
14800
14972
|
const author = roster.members.find((member) => member.identityId === item.authorId)?.name ?? item.authorId.slice(0, 12);
|
|
14801
14973
|
await this.client.sessionSteer(this.sessionId, [
|
|
14802
14974
|
`Human steer received while the current turn is running from ${author}:`,
|
|
14803
|
-
roomMessagePrompt("", item.body, item.attachments),
|
|
14975
|
+
roomMessagePrompt("", item.body, item.attachments, delivered),
|
|
14804
14976
|
"Adjust the current work now. Keep the original request and earlier messages as context."
|
|
14805
14977
|
].join("\n\n"));
|
|
14806
14978
|
} catch (error) {
|
|
@@ -14829,18 +15001,19 @@ var MonolithRoomTurnLoop = class {
|
|
|
14829
15001
|
activity: [{ kind: "thinking", title: "Working", status: "in_progress" }]
|
|
14830
15002
|
});
|
|
14831
15003
|
await this.options.scheduler.run(this.options.roomId, this.lifecycle(), async () => {
|
|
14832
|
-
const [conversation, roster] = await Promise.all([
|
|
15004
|
+
const [conversation, roster, delivered] = await Promise.all([
|
|
14833
15005
|
api.execute("getRoomConversation", { roomId: this.options.roomId, limit: 200 }),
|
|
14834
|
-
this.roster()
|
|
15006
|
+
this.roster(),
|
|
15007
|
+
this.deliver(item)
|
|
14835
15008
|
]);
|
|
14836
15009
|
const names = new Map(roster.members.map((member) => [member.identityId, member.name]));
|
|
14837
|
-
const transcript = conversation.items.filter((message) => message.type === "message" && message.id !== item.id && !active.steers.some((steerItem) => steerItem.id === message.id)).slice(-80).map((message) => roomMessagePrompt(names.get(message.authorId) ?? message.authorId.slice(0, 12), message.body, message.attachments)).join("\n");
|
|
15010
|
+
const transcript = conversation.items.filter((message) => message.type === "message" && message.id !== item.id && !active.steers.some((steerItem) => steerItem.id === message.id)).slice(-80).map((message) => roomMessagePrompt(names.get(message.authorId) ?? message.authorId.slice(0, 12), message.body, message.attachments, this.deliveredAttachments.get(message.id))).join("\n");
|
|
14838
15011
|
const prompt = [
|
|
14839
15012
|
this.turnInstructionPrefix,
|
|
14840
15013
|
transcript ? `Room conversation so far:
|
|
14841
15014
|
${transcript}` : "",
|
|
14842
15015
|
`Newest message from ${isScheduledPrompt(item, this.agent.publicKey) ? SCHEDULE_SCHEDULER_NAME : names.get(item.authorId) ?? item.authorId.slice(0, 12)}:`,
|
|
14843
|
-
roomMessagePrompt("", item.body, item.attachments),
|
|
15016
|
+
roomMessagePrompt("", item.body, item.attachments, delivered),
|
|
14844
15017
|
[
|
|
14845
15018
|
"Write only the substantive Room message you want the human to read.",
|
|
14846
15019
|
"Do not repeat or paraphrase these instructions.",
|
|
@@ -14850,7 +15023,7 @@ ${transcript}` : "",
|
|
|
14850
15023
|
].filter(Boolean).join("\n\n");
|
|
14851
15024
|
const sessionId = this.sessionId;
|
|
14852
15025
|
const turnId = item.id;
|
|
14853
|
-
let nextPrompt = prompt;
|
|
15026
|
+
let nextPrompt = promptWithImages(prompt, attachmentImageBlocks(delivered, this.client.canPromptWithImages()));
|
|
14854
15027
|
let result;
|
|
14855
15028
|
for (; ; ) {
|
|
14856
15029
|
let promptError;
|
|
@@ -14884,7 +15057,7 @@ ${transcript}` : "",
|
|
|
14884
15057
|
"The previous run was cancelled because its harness could not accept every live steer.",
|
|
14885
15058
|
"Resume the same turn. Keep the original request and everything that happened before it was cancelled.",
|
|
14886
15059
|
"Human messages that arrived after the original request, in transcript order:",
|
|
14887
|
-
...active.steers.map((steerItem) => roomMessagePrompt(steerItem.authorId.slice(0, 12), steerItem.body, steerItem.attachments)),
|
|
15060
|
+
...active.steers.map((steerItem) => roomMessagePrompt(steerItem.authorId.slice(0, 12), steerItem.body, steerItem.attachments, this.deliveredAttachments.get(steerItem.id))),
|
|
14888
15061
|
"Continue now and answer the updated request without erasing the earlier context."
|
|
14889
15062
|
].join("\n\n");
|
|
14890
15063
|
}
|
|
@@ -15004,20 +15177,10 @@ ${transcript}` : "",
|
|
|
15004
15177
|
}
|
|
15005
15178
|
}
|
|
15006
15179
|
};
|
|
15007
|
-
function roomMessagePrompt(author, body, attachments) {
|
|
15180
|
+
function roomMessagePrompt(author, body, attachments, delivered) {
|
|
15008
15181
|
const message = body.trim() || "(shared attachments)";
|
|
15009
15182
|
const rendered = author ? `${author}: ${message}` : message;
|
|
15010
|
-
|
|
15011
|
-
return rendered;
|
|
15012
|
-
return [
|
|
15013
|
-
rendered,
|
|
15014
|
-
"Attachments available to this turn (use the capability URL when the task requires the file):",
|
|
15015
|
-
...attachments.map((attachment) => {
|
|
15016
|
-
const kind = attachment.mimeType?.startsWith("image/") ? "image" : "file";
|
|
15017
|
-
const metadata = [attachment.mimeType, attachment.size ? `${attachment.size} bytes` : ""].filter(Boolean).join(", ");
|
|
15018
|
-
return `- ${kind}: ${attachment.name ?? "attachment"}${metadata ? ` (${metadata})` : ""}: ${attachment.url}`;
|
|
15019
|
-
})
|
|
15020
|
-
].join("\n");
|
|
15183
|
+
return [rendered, ...attachmentPromptLines(attachments, delivered)].join("\n");
|
|
15021
15184
|
}
|
|
15022
15185
|
async function wait2(ms, signal) {
|
|
15023
15186
|
if (signal?.aborted)
|
|
@@ -15617,7 +15780,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
15617
15780
|
const targetBranch = repository.targetBranch || "main";
|
|
15618
15781
|
const checkoutId = createHash("sha256").update(`${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
|
|
15619
15782
|
const path = resolve10(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
|
|
15620
|
-
await
|
|
15783
|
+
await mkdir6(dirname4(path), { recursive: true, mode: 448 });
|
|
15621
15784
|
const token = remote.startsWith("https://github.com/") ? await this.options.daemonApi.execute("getRoomGitHubToken", { roomId }) : void 0;
|
|
15622
15785
|
const env = token ? githubGitEnv(token.token) : process.env;
|
|
15623
15786
|
if (!existsSync4(resolve10(path, ".git"))) {
|
|
@@ -15740,8 +15903,8 @@ var RoomRuntimeCoordinator = class {
|
|
|
15740
15903
|
const repositoryHash = createHash("sha256").update(remote).digest("hex").slice(0, 24);
|
|
15741
15904
|
const gitCommonDir = resolve10(this.runtime.supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
|
|
15742
15905
|
const path = resolve10(this.runtime.supervisorRoot, "beeline", "corners", input.cornerId);
|
|
15743
|
-
await
|
|
15744
|
-
await
|
|
15906
|
+
await mkdir6(dirname4(gitCommonDir), { recursive: true, mode: 448 });
|
|
15907
|
+
await mkdir6(dirname4(path), { recursive: true, mode: 448 });
|
|
15745
15908
|
const authEnv = githubGitEnv(input.token);
|
|
15746
15909
|
if (!existsSync4(resolve10(gitCommonDir, "HEAD"))) {
|
|
15747
15910
|
await execFileAsync3("git", ["clone", "--bare", remote, gitCommonDir], {
|
|
@@ -16068,7 +16231,7 @@ var import_picocolors = __toESM(require_picocolors(), 1);
|
|
|
16068
16231
|
|
|
16069
16232
|
// apps/body/dist/systemd.js
|
|
16070
16233
|
import { execFile as execFile4 } from "node:child_process";
|
|
16071
|
-
import { mkdir as
|
|
16234
|
+
import { mkdir as mkdir7, readFile as readFile2, writeFile as writeFile4 } from "node:fs/promises";
|
|
16072
16235
|
import { homedir as homedir7 } from "node:os";
|
|
16073
16236
|
import { dirname as dirname5, resolve as resolve12 } from "node:path";
|
|
16074
16237
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
@@ -16141,8 +16304,8 @@ async function installAgentService(publicKey, options = {}) {
|
|
|
16141
16304
|
const content = agentServiceUnit();
|
|
16142
16305
|
const existing = await readFile2(path, "utf8").catch(() => "");
|
|
16143
16306
|
if (existing !== content) {
|
|
16144
|
-
await
|
|
16145
|
-
await
|
|
16307
|
+
await mkdir7(dirname5(path), { recursive: true, mode: 448 });
|
|
16308
|
+
await writeFile4(path, content, { mode: 384 });
|
|
16146
16309
|
}
|
|
16147
16310
|
const run2 = options.run ?? runSystemctl;
|
|
16148
16311
|
await run2(["daemon-reload"]);
|
|
@@ -16297,7 +16460,7 @@ async function runStartCommand(args, interactiveUi) {
|
|
|
16297
16460
|
// apps/body/dist/connect-command.js
|
|
16298
16461
|
import { spawn as spawn5 } from "node:child_process";
|
|
16299
16462
|
import { createHash as createHash3 } from "node:crypto";
|
|
16300
|
-
import { chmod as chmod4, mkdir as
|
|
16463
|
+
import { chmod as chmod4, mkdir as mkdir10, readFile as readFile5, unlink as unlink2, writeFile as writeFile7 } from "node:fs/promises";
|
|
16301
16464
|
import { dirname as dirname9, resolve as resolve15 } from "node:path";
|
|
16302
16465
|
import { stdin as stdin3, stdout as stdout4 } from "node:process";
|
|
16303
16466
|
|
|
@@ -16609,7 +16772,7 @@ async function pairDevice(grant, options = {}) {
|
|
|
16609
16772
|
}
|
|
16610
16773
|
|
|
16611
16774
|
// apps/body/dist/provider-key-store.js
|
|
16612
|
-
import { chmod as chmod2, mkdir as
|
|
16775
|
+
import { chmod as chmod2, mkdir as mkdir8, readFile as readFile3, writeFile as writeFile5 } from "node:fs/promises";
|
|
16613
16776
|
import { homedir as homedir8 } from "node:os";
|
|
16614
16777
|
import { dirname as dirname7, resolve as resolve13 } from "node:path";
|
|
16615
16778
|
var PROVIDER_KEY_ENV_VARS = {
|
|
@@ -16645,8 +16808,8 @@ async function readSavedProviderKey(provider, env = process.env) {
|
|
|
16645
16808
|
async function saveProviderKey(provider, key, env = process.env) {
|
|
16646
16809
|
const path = providerKeyStorePath(env);
|
|
16647
16810
|
const store = { ...await readProviderKeyStore(env), [provider]: key };
|
|
16648
|
-
await
|
|
16649
|
-
await
|
|
16811
|
+
await mkdir8(dirname7(path), { recursive: true, mode: 448 });
|
|
16812
|
+
await writeFile5(path, `${JSON.stringify(store, null, 2)}
|
|
16650
16813
|
`, { mode: 384 });
|
|
16651
16814
|
await chmod2(path, 384);
|
|
16652
16815
|
}
|
|
@@ -16929,8 +17092,8 @@ function providerEnvironment(selection) {
|
|
|
16929
17092
|
};
|
|
16930
17093
|
}
|
|
16931
17094
|
async function writePrivateJson(path, value) {
|
|
16932
|
-
await
|
|
16933
|
-
await
|
|
17095
|
+
await mkdir10(dirname9(path), { recursive: true, mode: 448 });
|
|
17096
|
+
await writeFile7(path, `${JSON.stringify(value, null, 2)}
|
|
16934
17097
|
`, { mode: 384 });
|
|
16935
17098
|
await chmod4(path, 384);
|
|
16936
17099
|
}
|
|
@@ -16939,9 +17102,9 @@ async function writeProviderEnv(selection, agentPubkey) {
|
|
|
16939
17102
|
if (Object.keys(values).length === 0)
|
|
16940
17103
|
return void 0;
|
|
16941
17104
|
const path = resolve15(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
|
|
16942
|
-
await
|
|
17105
|
+
await mkdir10(dirname9(path), { recursive: true, mode: 448 });
|
|
16943
17106
|
const contents = Object.entries(values).map(([key, value]) => `${key}=${JSON.stringify(value)}`).join("\n");
|
|
16944
|
-
await
|
|
17107
|
+
await writeFile7(path, `${contents}
|
|
16945
17108
|
`, { mode: 384 });
|
|
16946
17109
|
await chmod4(path, 384);
|
|
16947
17110
|
return path;
|
|
@@ -17064,11 +17227,11 @@ init_self_update_manifest();
|
|
|
17064
17227
|
// apps/body/dist/managed-update.js
|
|
17065
17228
|
init_self_update();
|
|
17066
17229
|
import { spawn as spawn6 } from "node:child_process";
|
|
17067
|
-
import { mkdir as
|
|
17230
|
+
import { mkdir as mkdir12, rm as rm5, stat as stat2, writeFile as writeFile9 } from "node:fs/promises";
|
|
17068
17231
|
import { dirname as dirname11, resolve as resolve17 } from "node:path";
|
|
17069
17232
|
|
|
17070
17233
|
// apps/body/dist/update-rollback-alert.js
|
|
17071
|
-
import { mkdir as
|
|
17234
|
+
import { mkdir as mkdir11, readFile as readFile6, rename as rename4, writeFile as writeFile8 } from "node:fs/promises";
|
|
17072
17235
|
import { dirname as dirname10, resolve as resolve16 } from "node:path";
|
|
17073
17236
|
function updateRollbackAlertPath(runtimeDir) {
|
|
17074
17237
|
return resolve16(runtimeDir, "update-rollback-alert.json");
|
|
@@ -17076,8 +17239,8 @@ function updateRollbackAlertPath(runtimeDir) {
|
|
|
17076
17239
|
async function writeAlert(runtimeDir, alert) {
|
|
17077
17240
|
const path = updateRollbackAlertPath(runtimeDir);
|
|
17078
17241
|
const staged = `${path}.${process.pid}.tmp`;
|
|
17079
|
-
await
|
|
17080
|
-
await
|
|
17242
|
+
await mkdir11(dirname10(path), { recursive: true });
|
|
17243
|
+
await writeFile8(staged, `${JSON.stringify(alert, null, 2)}
|
|
17081
17244
|
`, { mode: 384 });
|
|
17082
17245
|
await rename4(staged, path);
|
|
17083
17246
|
}
|
|
@@ -17116,11 +17279,11 @@ async function withInstallLock(layout, work, options = {}) {
|
|
|
17116
17279
|
const now2 = options.now ?? Date.now;
|
|
17117
17280
|
const lock = resolve17(layout.releasesRoot, ".state", "install.lock");
|
|
17118
17281
|
const deadline = now2() + (options.waitMs ?? 1e4);
|
|
17119
|
-
await
|
|
17282
|
+
await mkdir12(dirname11(lock), { recursive: true });
|
|
17120
17283
|
for (; ; ) {
|
|
17121
17284
|
try {
|
|
17122
|
-
await
|
|
17123
|
-
await
|
|
17285
|
+
await mkdir12(lock);
|
|
17286
|
+
await writeFile9(resolve17(lock, "owner"), `${process.pid}
|
|
17124
17287
|
${now2()}
|
|
17125
17288
|
`, "utf8");
|
|
17126
17289
|
break;
|
|
@@ -17451,7 +17614,7 @@ async function proveLoadedReleaseReady(layout, runtimeDir, loadedRelease, option
|
|
|
17451
17614
|
});
|
|
17452
17615
|
if (!accepted)
|
|
17453
17616
|
return false;
|
|
17454
|
-
await
|
|
17617
|
+
await writeFile9(resolve17(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
|
|
17455
17618
|
readyAt: (options.now ?? Date.now)(),
|
|
17456
17619
|
loadedRelease,
|
|
17457
17620
|
functionalProof: options.functionalProof
|
|
@@ -17656,7 +17819,7 @@ async function runUpdateCommand(args) {
|
|
|
17656
17819
|
init_self_update();
|
|
17657
17820
|
|
|
17658
17821
|
// apps/body/dist/daemon-failure.js
|
|
17659
|
-
import { mkdir as
|
|
17822
|
+
import { mkdir as mkdir13, readFile as readFile7, rename as rename5, rm as rm6, writeFile as writeFile10 } from "node:fs/promises";
|
|
17660
17823
|
import { dirname as dirname12, resolve as resolve18 } from "node:path";
|
|
17661
17824
|
var DAEMON_FAILURE_LIMIT = 3;
|
|
17662
17825
|
var DAEMON_FAILURE_WINDOW_MS = 5 * 6e4;
|
|
@@ -17677,8 +17840,8 @@ async function readFailureRecord(runtimeDir) {
|
|
|
17677
17840
|
async function writeFailureRecord(runtimeDir, record2) {
|
|
17678
17841
|
const path = daemonFailurePath(runtimeDir);
|
|
17679
17842
|
const staged = `${path}.${process.pid}.tmp`;
|
|
17680
|
-
await
|
|
17681
|
-
await
|
|
17843
|
+
await mkdir13(dirname12(path), { recursive: true, mode: 448 });
|
|
17844
|
+
await writeFile10(staged, `${JSON.stringify(record2, null, 2)}
|
|
17682
17845
|
`, { mode: 384 });
|
|
17683
17846
|
await rename5(staged, path);
|
|
17684
17847
|
}
|
|
@@ -17700,7 +17863,7 @@ async function clearDaemonStartFailures(runtimeDir) {
|
|
|
17700
17863
|
}
|
|
17701
17864
|
|
|
17702
17865
|
// apps/body/dist/update-functional-probe.js
|
|
17703
|
-
import { mkdir as
|
|
17866
|
+
import { mkdir as mkdir14, rm as rm7 } from "node:fs/promises";
|
|
17704
17867
|
import { homedir as homedir10 } from "node:os";
|
|
17705
17868
|
import { resolve as resolve19 } from "node:path";
|
|
17706
17869
|
var UPDATE_PROBE_SESSION_TIMEOUT_MS = 1e4;
|
|
@@ -17728,7 +17891,7 @@ async function runUpdateFunctionalProbe(input) {
|
|
|
17728
17891
|
const cwd = resolve19(root, "checkout");
|
|
17729
17892
|
const homeRoot = resolve19(root, "agent-home");
|
|
17730
17893
|
await rm7(root, { recursive: true, force: true });
|
|
17731
|
-
await
|
|
17894
|
+
await mkdir14(cwd, { recursive: true, mode: 448 });
|
|
17732
17895
|
let client;
|
|
17733
17896
|
try {
|
|
17734
17897
|
const agentEnv = {
|
|
@@ -17754,7 +17917,7 @@ async function runUpdateFunctionalProbe(input) {
|
|
|
17754
17917
|
const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
|
|
17755
17918
|
const operatorHome = input.config.operatorHome ?? homedir10();
|
|
17756
17919
|
const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
|
|
17757
|
-
await Promise.all(homeStateDirs.map((dir) =>
|
|
17920
|
+
await Promise.all(homeStateDirs.map((dir) => mkdir14(dir, { recursive: true })));
|
|
17758
17921
|
spawnCommand = wrapAgentCommand({
|
|
17759
17922
|
bwrapPath: input.config.bwrapPath,
|
|
17760
17923
|
spec: {
|
|
@@ -17818,7 +17981,7 @@ async function runUpdateFunctionalProbe(input) {
|
|
|
17818
17981
|
}
|
|
17819
17982
|
|
|
17820
17983
|
// apps/body/dist/release-status.js
|
|
17821
|
-
import { readFile as readFile8, readdir as readdir3, rename as rename6, writeFile as
|
|
17984
|
+
import { readFile as readFile8, readdir as readdir3, rename as rename6, writeFile as writeFile11 } from "node:fs/promises";
|
|
17822
17985
|
import { resolve as resolve20 } from "node:path";
|
|
17823
17986
|
var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
|
|
17824
17987
|
var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
|
|
@@ -17838,7 +18001,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
|
|
|
17838
18001
|
};
|
|
17839
18002
|
const target = resolve20(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
|
|
17840
18003
|
const temporary = `${target}.${status.pid}.tmp`;
|
|
17841
|
-
await
|
|
18004
|
+
await writeFile11(temporary, `${JSON.stringify(status, null, 2)}
|
|
17842
18005
|
`, { mode: 384 });
|
|
17843
18006
|
await rename6(temporary, target);
|
|
17844
18007
|
return status;
|
|
@@ -17891,7 +18054,7 @@ async function runStoredDaemon(pathOrPointer) {
|
|
|
17891
18054
|
runtime = activated.runtime;
|
|
17892
18055
|
const daemonApi = activated.client;
|
|
17893
18056
|
const agent = runtimeAgentCommand(runtime);
|
|
17894
|
-
await
|
|
18057
|
+
await writeFile12(resolve21(dirname13(configPath), "daemon.pid"), `${process.pid}
|
|
17895
18058
|
`, { mode: 384 });
|
|
17896
18059
|
const env = {
|
|
17897
18060
|
...process.env,
|