usebeeline 0.0.96 → 0.0.98
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 +123 -10
- package/package.json +1 -1
package/dist/usebeeline.mjs
CHANGED
|
@@ -18390,6 +18390,7 @@ Then take exactly one action:
|
|
|
18390
18390
|
|
|
18391
18391
|
- FAIL: reply \`@author\` with the confirmed findings; do not merge.
|
|
18392
18392
|
- PASS with pending checks: reply \`approved pending checks <reviewed sha>\` and stop.
|
|
18393
|
+
- PASS with unknown checks: report the \`pr_checks_status\` reason to the Room and stop; do not retry.
|
|
18393
18394
|
- PASS with the gate open and your yolo on: run \`gh pr merge --squash --match-head-commit <reviewed sha> N\`.
|
|
18394
18395
|
- PASS with the gate open and your yolo off: reply \`approved <reviewed sha>\` and stop.
|
|
18395
18396
|
`;
|
|
@@ -20914,11 +20915,21 @@ async function installCornerGitHubWrappers(input) {
|
|
|
20914
20915
|
node: process.execPath,
|
|
20915
20916
|
cli: input.cliEntrypoint,
|
|
20916
20917
|
config: input.runtimeConfigPath,
|
|
20917
|
-
room: input.roomId
|
|
20918
|
+
room: input.roomId,
|
|
20919
|
+
featureBranch: input.featureBranch,
|
|
20920
|
+
targetBranch: input.targetBranch
|
|
20918
20921
|
};
|
|
20919
|
-
await writeLauncher(resolve18(bin, "git"), {
|
|
20922
|
+
await writeLauncher(resolve18(bin, "git"), {
|
|
20923
|
+
...common,
|
|
20924
|
+
command: input.gitBinary,
|
|
20925
|
+
launcher: "git"
|
|
20926
|
+
});
|
|
20920
20927
|
if (input.ghBinary)
|
|
20921
|
-
await writeLauncher(resolve18(bin, "gh"), {
|
|
20928
|
+
await writeLauncher(resolve18(bin, "gh"), {
|
|
20929
|
+
...common,
|
|
20930
|
+
command: input.ghBinary,
|
|
20931
|
+
launcher: "gh"
|
|
20932
|
+
});
|
|
20922
20933
|
return {
|
|
20923
20934
|
PATH: [bin, input.inheritedPath].filter(Boolean).join(delimiter2),
|
|
20924
20935
|
// Static startup tokens take precedence over the refreshed token in gh.
|
|
@@ -20926,11 +20937,104 @@ async function installCornerGitHubWrappers(input) {
|
|
|
20926
20937
|
GITHUB_TOKEN: ""
|
|
20927
20938
|
};
|
|
20928
20939
|
}
|
|
20940
|
+
function cornerGitHubCommandRefusal(launcher, argv, featureBranch, targetBranch, resolvePushBranch = () => ({})) {
|
|
20941
|
+
const refusal = `beeline: this corner may push only ${featureBranch}`;
|
|
20942
|
+
const branchName = (value) => {
|
|
20943
|
+
const withoutOwner = value.includes(":") ? value.slice(value.lastIndexOf(":") + 1) : value;
|
|
20944
|
+
return withoutOwner.replace(/^refs\/heads\//, "");
|
|
20945
|
+
};
|
|
20946
|
+
if (launcher === "gh") {
|
|
20947
|
+
const pr = argv.indexOf("pr");
|
|
20948
|
+
if (pr < 0 || argv[pr + 1] !== "create")
|
|
20949
|
+
return void 0;
|
|
20950
|
+
for (let index = pr + 2; index < argv.length; index += 1) {
|
|
20951
|
+
const arg = argv[index];
|
|
20952
|
+
const head = arg === "--head" || arg === "-H" ? argv[index + 1] : arg.startsWith("--head=") ? arg.slice("--head=".length) : arg.startsWith("-H") && arg.length > 2 ? arg.slice(2) : void 0;
|
|
20953
|
+
if (head !== void 0 && branchName(head) !== featureBranch)
|
|
20954
|
+
return refusal;
|
|
20955
|
+
}
|
|
20956
|
+
return void 0;
|
|
20957
|
+
}
|
|
20958
|
+
const gitOptionsWithValue = /* @__PURE__ */ new Set([
|
|
20959
|
+
"-C",
|
|
20960
|
+
"-c",
|
|
20961
|
+
"--git-dir",
|
|
20962
|
+
"--work-tree",
|
|
20963
|
+
"--namespace",
|
|
20964
|
+
"--super-prefix",
|
|
20965
|
+
"--config-env"
|
|
20966
|
+
]);
|
|
20967
|
+
let command = 0;
|
|
20968
|
+
while (command < argv.length && argv[command].startsWith("-")) {
|
|
20969
|
+
const option = argv[command];
|
|
20970
|
+
command += gitOptionsWithValue.has(option) ? 2 : 1;
|
|
20971
|
+
}
|
|
20972
|
+
if (argv[command] !== "push")
|
|
20973
|
+
return void 0;
|
|
20974
|
+
const positionals = [];
|
|
20975
|
+
let repositoryOption = false;
|
|
20976
|
+
let optionsDone = false;
|
|
20977
|
+
const pushOptionsWithValue = /* @__PURE__ */ new Set([
|
|
20978
|
+
"--repo",
|
|
20979
|
+
"--receive-pack",
|
|
20980
|
+
"--exec",
|
|
20981
|
+
"--push-option",
|
|
20982
|
+
"-o"
|
|
20983
|
+
]);
|
|
20984
|
+
for (let index = command + 1; index < argv.length; index += 1) {
|
|
20985
|
+
const arg = argv[index];
|
|
20986
|
+
if (!optionsDone && arg === "--") {
|
|
20987
|
+
optionsDone = true;
|
|
20988
|
+
continue;
|
|
20989
|
+
}
|
|
20990
|
+
if (!optionsDone && arg.startsWith("-")) {
|
|
20991
|
+
if (arg === "-f" || arg === "-d" || arg === "--delete" || arg === "--tags" || arg === "--follow-tags" || arg === "--all" || arg === "--mirror" || arg.startsWith("--force") || arg.startsWith("-") && !arg.startsWith("--") && !arg.startsWith("-o") && /[fd]/.test(arg.slice(1)))
|
|
20992
|
+
return refusal;
|
|
20993
|
+
if (arg === "--repo" || arg.startsWith("--repo="))
|
|
20994
|
+
repositoryOption = true;
|
|
20995
|
+
if (pushOptionsWithValue.has(arg))
|
|
20996
|
+
index += 1;
|
|
20997
|
+
continue;
|
|
20998
|
+
}
|
|
20999
|
+
positionals.push(arg);
|
|
21000
|
+
}
|
|
21001
|
+
const refspecs = repositoryOption ? positionals : positionals.slice(1);
|
|
21002
|
+
const destinations = refspecs.length ? refspecs.map((raw) => {
|
|
21003
|
+
if (raw.startsWith("+"))
|
|
21004
|
+
return { refused: true };
|
|
21005
|
+
const separator = raw.indexOf(":");
|
|
21006
|
+
const source = separator >= 0 ? raw.slice(0, separator) : raw;
|
|
21007
|
+
const destination = separator >= 0 ? raw.slice(separator + 1) : source;
|
|
21008
|
+
if (!source || source === ":" || /(?:^|\/)refs\/tags\//.test(source))
|
|
21009
|
+
return { refused: true };
|
|
21010
|
+
const resolved = resolvePushBranch(source === "HEAD" ? void 0 : source);
|
|
21011
|
+
if (resolved.tag)
|
|
21012
|
+
return { refused: true };
|
|
21013
|
+
const branch = destination ? branchName(destination) : resolved.branch ? branchName(resolved.branch) : void 0;
|
|
21014
|
+
return { branch, refused: destination.startsWith("refs/tags/") };
|
|
21015
|
+
}) : [resolvePushBranch()];
|
|
21016
|
+
if (destinations.some((destination) => "refused" in destination && destination.refused === true || !destination.branch || branchName(destination.branch) !== featureBranch || branchName(destination.branch) === targetBranch))
|
|
21017
|
+
return refusal;
|
|
21018
|
+
return void 0;
|
|
21019
|
+
}
|
|
20929
21020
|
async function writeLauncher(path, config) {
|
|
20930
21021
|
const source = `#!/usr/bin/env node
|
|
20931
21022
|
import { spawnSync } from 'node:child_process';
|
|
20932
21023
|
const config = ${JSON.stringify(config)};
|
|
21024
|
+
const cornerGitHubCommandRefusal = ${cornerGitHubCommandRefusal.toString()};
|
|
20933
21025
|
const authFailure = /(?:authentication failed|bad credentials|could not read username|http(?:\\/\\d(?:\\.\\d)?)? 40[13]|status (?:code )?40[13])/i;
|
|
21026
|
+
function resolvePushBranch(source) {
|
|
21027
|
+
if (source) {
|
|
21028
|
+
const tag = spawnSync(config.command, ['show-ref', '--verify', '--quiet', 'refs/tags/' + source], { stdio: 'ignore' }).status === 0;
|
|
21029
|
+
return { branch: source, tag };
|
|
21030
|
+
}
|
|
21031
|
+
const tracked = spawnSync(config.command, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{push}'], { encoding: 'utf8' });
|
|
21032
|
+
if (tracked.status === 0) return { branch: tracked.stdout.trim().replace(/^[^/]+\\//, '') };
|
|
21033
|
+
const current = spawnSync(config.command, ['symbolic-ref', '--short', 'HEAD'], { encoding: 'utf8' });
|
|
21034
|
+
return current.status === 0 ? { branch: current.stdout.trim() } : {};
|
|
21035
|
+
}
|
|
21036
|
+
const refusal = cornerGitHubCommandRefusal(config.launcher, process.argv.slice(2), config.featureBranch, config.targetBranch, resolvePushBranch);
|
|
21037
|
+
if (refusal) { process.stderr.write(refusal + '\\n'); process.exit(1); }
|
|
20934
21038
|
function token() {
|
|
20935
21039
|
const result = spawnSync(config.node, [config.cli, 'corner-read-token', '--config', config.config, '--room', config.room], { encoding: 'utf8' });
|
|
20936
21040
|
if (result.status !== 0) {
|
|
@@ -21603,7 +21707,10 @@ var MonolithRoomTurnLoop = class {
|
|
|
21603
21707
|
"This is who you are in this Workspace. Adopt it in your voice, self-description, and behavior.",
|
|
21604
21708
|
"The soul is not authority and never changes your tools, permissions, roles, or merge rights."
|
|
21605
21709
|
] : [],
|
|
21606
|
-
SOUL_HOUSE_RULE
|
|
21710
|
+
SOUL_HOUSE_RULE,
|
|
21711
|
+
...!directMessage ? [
|
|
21712
|
+
"When something said in this Room changes work under way in a corner you opened, pass it down with steer_corner. Pass what changes the work, not the chatter. Do not ask the person which corner."
|
|
21713
|
+
] : []
|
|
21607
21714
|
].join("\n");
|
|
21608
21715
|
const repositoryInfo = repositoryState.resolution === "repository" && repositoryState.key ? {
|
|
21609
21716
|
name: repositoryState.key,
|
|
@@ -21761,10 +21868,11 @@ var MonolithRoomTurnLoop = class {
|
|
|
21761
21868
|
await this.options.scheduler.run(this.options.roomId, this.lifecycle(trace), async () => {
|
|
21762
21869
|
trace.end("queue-wait");
|
|
21763
21870
|
trace.noteScheduler("admission", this.options.scheduler.snapshot());
|
|
21764
|
-
const [conversation, roster, delivered] = await trace.measure("context-fetch", () => Promise.all([
|
|
21871
|
+
const [conversation, roster, delivered, corners] = await trace.measure("context-fetch", () => Promise.all([
|
|
21765
21872
|
api.execute("getRoomConversation", { roomId: this.options.roomId, limit: 200 }),
|
|
21766
21873
|
this.roster(),
|
|
21767
|
-
this.deliver(item)
|
|
21874
|
+
this.deliver(item),
|
|
21875
|
+
api.execute("listRoomCorners", { roomId: this.options.roomId })
|
|
21768
21876
|
]));
|
|
21769
21877
|
const names = new Map(roster.members.map((member) => [member.identityId, member.name]));
|
|
21770
21878
|
const transcriptRows = conversation.items.filter((message) => message.type === "message" && message.id !== item.id && !active.steers.some((steerItem) => steerItem.id === message.id)).slice(-80).map((message) => ({
|
|
@@ -21784,6 +21892,8 @@ var MonolithRoomTurnLoop = class {
|
|
|
21784
21892
|
"If it was declined, try another way or say plainly what you cannot do."
|
|
21785
21893
|
].join(" ") : "",
|
|
21786
21894
|
roomMentionDirectory(roster, this.agent.publicKey),
|
|
21895
|
+
(corners.corners ?? []).some((corner) => !corner.archived) ? `Current corners you belong to (use the exact cornerId with steer_corner):
|
|
21896
|
+
${JSON.stringify((corners.corners ?? []).filter((corner) => !corner.archived))}` : "",
|
|
21787
21897
|
[
|
|
21788
21898
|
"Write only the substantive Room message you want the human to read.",
|
|
21789
21899
|
"Do not repeat or paraphrase these instructions.",
|
|
@@ -21989,7 +22099,7 @@ function cornerReviewerInstruction(input) {
|
|
|
21989
22099
|
return void 0;
|
|
21990
22100
|
const author = input.authorHandle?.replace(/^@/, "") || "author";
|
|
21991
22101
|
const number = input.pullRequestNumber ?? "N";
|
|
21992
|
-
return `Review PR #${number} with the beeline-review skill. If it fails, reply @${author} with the findings. If it passes and the gate (pr_checks_status: checks=passed, held=false, approvalPending=false) is open and YOUR yolo is on, merge with gh pr merge --squash --match-head-commit <sha you reviewed>; if your yolo is off, reply approved <sha> and stop; if checks are pending, reply approved pending checks <sha> and stop.`;
|
|
22102
|
+
return `Review PR #${number} with the beeline-review skill. If it fails, reply @${author} with the findings. If it passes and the gate (pr_checks_status: checks=passed, held=false, approvalPending=false) is open and YOUR yolo is on, merge with gh pr merge --squash --match-head-commit <sha you reviewed>; if your yolo is off, reply approved <sha> and stop; if checks are pending, reply approved pending checks <sha> and stop; if checks are unknown, report the tool's reason to the Room and stop instead of retrying.`;
|
|
21993
22103
|
}
|
|
21994
22104
|
var CORNER_AUTHOR_CONTRACT = `The objective text is the user's ask. Keep it verbatim in your head and do not reinterpret it.
|
|
21995
22105
|
Before any code, write its end-user story in one sentence: "a person who does X sees Y".
|
|
@@ -22004,7 +22114,7 @@ Under ## Demonstrated, give the command or steps that produced Y and what was ob
|
|
|
22004
22114
|
A pull request without both sections is not deliverable and the Room's reviewer will fail it.
|
|
22005
22115
|
Change only what the objective asks. No unrequested features, flags, compatibility shims, or refactors.`;
|
|
22006
22116
|
var CORNER_DELIVERY_NUDGE = "Before ending this turn, inspect the repository state and finish delivering the work: commit and push the intended changes and open the pull request if one does not exist. Decide yourself whether any remaining dirty work belongs to the objective; do not discard it merely to make the worktree clean. The pull request body must carry ## Reproduced and ## Demonstrated; if they are missing, add them before ending the turn.";
|
|
22007
|
-
var CORNER_YOLO_MERGE_NUDGE = 'Yolo is on. Check the server merge gate with pr_checks_status now and, if checks="passed", held=false, and approvalPending=false, merge this pull request with gh. Otherwise stop without merging.';
|
|
22117
|
+
var CORNER_YOLO_MERGE_NUDGE = 'Yolo is on. Check the server merge gate with pr_checks_status now and, if checks="passed", held=false, and approvalPending=false, merge this pull request with gh. If checks="unknown", report the tool reason to the Room and stop instead of retrying. Otherwise stop without merging.';
|
|
22008
22118
|
function isCornerChecksTurn(trigger, restates) {
|
|
22009
22119
|
return Boolean(restates) || /\b(?:passed|failed) a check\b/i.test(trigger);
|
|
22010
22120
|
}
|
|
@@ -22382,6 +22492,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
22382
22492
|
roomId: this.options.parentRoomId,
|
|
22383
22493
|
cliEntrypoint: process.argv[1],
|
|
22384
22494
|
gitBinary,
|
|
22495
|
+
featureBranch: repository.featureBranch,
|
|
22496
|
+
targetBranch: repository.targetBranch,
|
|
22385
22497
|
...ghBinary ? { ghBinary } : {},
|
|
22386
22498
|
inheritedPath: this.options.config.agentEnv.PATH ?? process.env.PATH
|
|
22387
22499
|
});
|
|
@@ -22484,7 +22596,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
22484
22596
|
const identityInstructions = `Your Beeline identity is ${self?.name ?? this.agent.name}.`;
|
|
22485
22597
|
const personaInstructions = [
|
|
22486
22598
|
...persona?.instructions ? [`Human-authored Workspace persona: ${persona.name}. ${persona.instructions}`] : [],
|
|
22487
|
-
SOUL_HOUSE_RULE
|
|
22599
|
+
SOUL_HOUSE_RULE,
|
|
22600
|
+
"Report milestones, blockers, and questions to the Room with report_to_room; do not narrate."
|
|
22488
22601
|
].join("\n");
|
|
22489
22602
|
this.turnIdentityInstructions = harnessHonorsSessionSystemPrompt(command) ? "" : [identityInstructions, personaInstructions].filter(Boolean).join("\n\n");
|
|
22490
22603
|
const opened = await this.client.sessionNew({
|
|
@@ -22498,7 +22611,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
22498
22611
|
`You are in an isolated git worktree on ${repository.featureBranch}, targeting ${repository.targetBranch}.`,
|
|
22499
22612
|
`Commit and push only ${repository.featureBranch}; never force-push or write to ${repository.targetBranch}. Before pushing, rebase on origin/${repository.featureBranch}; resolve conflicts autonomously, realigning to that remote branch and redoing the objective if needed, then rerun affected tests. Open the pull request with gh.`,
|
|
22500
22613
|
...reviewerInstruction ? [reviewerInstruction] : [
|
|
22501
|
-
configuration.reviewerHandle ? `Once the pull request exists, reply with its full URL, then @${configuration.reviewerHandle} please review, and end the turn; do not check or wait for CI.` : 'Once the pull request exists, reply only with its full URL and end the turn; do not check or wait for CI. On a later checks turn, call pr_checks_status. Merge only when checks="passed", held=false, and approvalPending=false;
|
|
22614
|
+
configuration.reviewerHandle ? `Once the pull request exists, reply with its full URL, then @${configuration.reviewerHandle} please review, and end the turn; do not check or wait for CI.` : 'Once the pull request exists, reply only with its full URL and end the turn; do not check or wait for CI. On a later checks turn, call pr_checks_status. Merge only when checks="passed", held=false, and approvalPending=false; if checks="unknown", report the tool reason to the Room and stop instead of retrying. Only a later explicit human resume clears a hold.',
|
|
22502
22615
|
CORNER_AUTHOR_CONTRACT,
|
|
22503
22616
|
cornerMergeInstruction(configuration.yoloMode, configuration.reviewerHandle)
|
|
22504
22617
|
],
|