usebeeline 0.1.1 → 0.1.2

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.
Files changed (2) hide show
  1. package/dist/usebeeline.mjs +135 -131
  2. package/package.json +1 -1
@@ -14385,7 +14385,7 @@ var require_websocket = __commonJS({
14385
14385
  var http = __require("http");
14386
14386
  var net2 = __require("net");
14387
14387
  var tls = __require("tls");
14388
- var { randomBytes: randomBytes8, createHash: createHash13 } = __require("crypto");
14388
+ var { randomBytes: randomBytes8, createHash: createHash14 } = __require("crypto");
14389
14389
  var { Duplex, Readable } = __require("stream");
14390
14390
  var { URL: URL2 } = __require("url");
14391
14391
  var PerMessageDeflate2 = require_permessage_deflate();
@@ -15053,7 +15053,7 @@ var require_websocket = __commonJS({
15053
15053
  abortHandshake(websocket, socket, "Invalid Upgrade header");
15054
15054
  return;
15055
15055
  }
15056
- const digest = createHash13("sha1").update(key + GUID).digest("base64");
15056
+ const digest = createHash14("sha1").update(key + GUID).digest("base64");
15057
15057
  if (res.headers["sec-websocket-accept"] !== digest) {
15058
15058
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
15059
15059
  return;
@@ -15422,7 +15422,7 @@ var require_websocket_server = __commonJS({
15422
15422
  var EventEmitter2 = __require("events");
15423
15423
  var http = __require("http");
15424
15424
  var { Duplex } = __require("stream");
15425
- var { createHash: createHash13 } = __require("crypto");
15425
+ var { createHash: createHash14 } = __require("crypto");
15426
15426
  var extension2 = require_extension();
15427
15427
  var PerMessageDeflate2 = require_permessage_deflate();
15428
15428
  var subprotocol2 = require_subprotocol();
@@ -15729,7 +15729,7 @@ var require_websocket_server = __commonJS({
15729
15729
  );
15730
15730
  }
15731
15731
  if (this._state > RUNNING) return abortHandshake(socket, 503);
15732
- const digest = createHash13("sha1").update(key + GUID).digest("base64");
15732
+ const digest = createHash14("sha1").update(key + GUID).digest("base64");
15733
15733
  const headers = [
15734
15734
  "HTTP/1.1 101 Switching Protocols",
15735
15735
  "Upgrade: websocket",
@@ -27226,19 +27226,6 @@ var WORKFLOW_TIMEOUT_SECONDS_MAX = 30 * 24 * 60 * 60;
27226
27226
  var WEIGHT_TIER_RULE_PATTERN_MAX_LENGTH = 32;
27227
27227
  var RULE_PATTERN_SHAPE = new RegExp(`^[a-z0-9*.-]{1,${WEIGHT_TIER_RULE_PATTERN_MAX_LENGTH}}$`);
27228
27228
 
27229
- // packages/api-contract/dist/feedback.js
27230
- var FEEDBACK_AGENT_CATEGORIES = [
27231
- "simpler_path",
27232
- "contradiction",
27233
- "tooling_gap",
27234
- "context_gap",
27235
- "bug"
27236
- ];
27237
- var FEEDBACK_CATEGORIES = [
27238
- ...FEEDBACK_AGENT_CATEGORIES,
27239
- "human_report"
27240
- ];
27241
-
27242
27229
  // apps/body/dist/transient-provider-error.js
27243
27230
  var TRANSIENT_PATTERNS = [
27244
27231
  /\b429\b/,
@@ -31385,7 +31372,7 @@ async function activateDaemonTransport(path, fetchImpl = fetch) {
31385
31372
 
31386
31373
  // apps/body/dist/room-runtime.js
31387
31374
  import { execFile as execFile12 } from "node:child_process";
31388
- import { createHash as createHash10 } from "node:crypto";
31375
+ import { createHash as createHash11 } from "node:crypto";
31389
31376
  import { existsSync as existsSync8, mkdirSync as mkdirSync3 } from "node:fs";
31390
31377
  import { mkdir as mkdir20, readdir as readdir8, realpath as realpath2, rm as rm9 } from "node:fs/promises";
31391
31378
  import { dirname as dirname19, relative as relative3, resolve as resolve29, sep as sep2 } from "node:path";
@@ -32901,7 +32888,7 @@ async function runServerCommandIntake(options) {
32901
32888
 
32902
32889
  // apps/body/dist/monolith-corner-turn.js
32903
32890
  import { execFile as execFile11 } from "node:child_process";
32904
- import { createHash as createHash9 } from "node:crypto";
32891
+ import { createHash as createHash10 } from "node:crypto";
32905
32892
  import { mkdir as mkdir18, readFile as readFile20, writeFile as writeFile14 } from "node:fs/promises";
32906
32893
  import { homedir as homedir14, hostname } from "node:os";
32907
32894
  import { dirname as dirname17, join as join14, resolve as resolve28 } from "node:path";
@@ -33909,7 +33896,7 @@ When the mock needs a real product photo, do not draw an SVG stand-in. Call beel
33909
33896
  function beelineReviewSkillMarkdown(releaseId) {
33910
33897
  return `---
33911
33898
  name: beeline-review
33912
- description: Review a corner pull request against verbatim human intent, every current criterion, and the Beeline merge gate.
33899
+ description: Review a corner pull request against the brief's spec, its checklist, the approval quote, and the Beeline merge gate.
33913
33900
  ---
33914
33901
 
33915
33902
  <!-- beeline-release: ${releaseId} -->
@@ -33927,26 +33914,26 @@ Follow these steps in order. Do not skip or reorder them.
33927
33914
  - When a checkout is needed, create a temporary detached worktree, install an EXIT trap that removes it with \`git worktree remove --force\` and deletes its temporary directory, and run every command there. Cleanup is mandatory on PASS, FAIL, and command error.
33928
33915
  - Review and test only the recorded revision. If the head moves, clean up the scratch worktree and start over.
33929
33916
 
33930
- ## 2. P0 - HUMAN INTENT AND CRITERIA FULFILLED, DEMONSTRATED
33917
+ ## 2. P0 - SPEC AND CHECKLIST FULFILLED, DEMONSTRATED
33931
33918
 
33932
- Read the server-assigned brief and its current revision, including every required file. Quote every verbatim human-intent entry with its source message ID before considering the short objective. The verbatim intent plus current numbered criteria are product truth; the short objective is navigation-only text and the PR description cannot add, remove, or narrow scope. If a required file is unavailable, or the revision changes during review, refuse approval and describe what is missing. A requirement may become out of scope only through a new human-authorized brief revision; reviewer discretion, implementation difficulty, and silence never remove it. A passing narrow test does not prove a broader requirement. Review a deliberate human choice as written, even if it is unusual.
33919
+ Read the server-assigned brief and its current revision, including every required file. Quote the approval with its message ID and approver before considering the short objective. The spec's checklist is the scope, and the approval quote is the human's own words: it wins any conflict with the spec. The short objective is navigation-only text and the PR description cannot add, remove, or narrow scope. A revision with no recorded approval is reviewed against its spec alone. If a required file is unavailable, or the revision changes during review, refuse approval and describe what is missing. A requirement may become out of scope only through a new human-authorized brief revision; reviewer discretion, implementation difficulty, and silence never remove it. A passing narrow test does not prove a broader requirement. Review a deliberate human choice as written, even if it is unusual.
33933
33920
 
33934
- Before general correctness, produce a criterion ledger in brief order. List every current criterion ID exactly once as met, unmet, unverified, or out of scope, followed by concrete evidence. Any missing, unmet, or unverified criterion blocks PASS. Out of scope is valid only when the current revision itself records the human-authorized removal.
33921
+ Before general correctness, produce a checklist ledger in spec order. List every checklist line exactly once as met, unmet, unverified, or out of scope, followed by concrete evidence. Any missing, unmet, or unverified line blocks PASS. Out of scope is valid only when the current revision itself records the human-authorized removal.
33935
33922
 
33936
33923
  Before judging the implementation, independently repeat the two judgment legs from request triage:
33937
33924
 
33938
33925
  - **Work warranted:** For a bug, reproduce the reported behavior on the target branch. For another request, establish the unmet user need from the request and current product. Search current code, history, issues, and open or recently merged pull requests for work that already resolves or supersedes it. Treat title similarity only as a candidate, not proof of duplication. FAIL confirmed duplicate or obsolete work.
33939
33926
  - **Desirable:** Check repository-owned goals, invariants, architecture, and established product behavior. Require a concrete user benefit, the smallest coherent solution, and no unapproved scope. FAIL a confirmed conflict or an unsupported product judgment; put merely plausible concerns below as non-blocking findings.
33940
33927
 
33941
- - Quote the verbatim human intent, with message IDs, exactly as stored. Do not quote the short objective as product truth.
33942
- - Derive the end-user story from that intent and the current criteria in one sentence: \`a user who does X sees Y\`.
33928
+ - Quote the approval text, with its message ID, exactly as stored. Do not quote the short objective as product truth.
33929
+ - Derive the end-user story from the spec and the approval quote in one sentence: \`a user who does X sees Y\`.
33943
33930
  - Make Y happen against the built PR head: run the app or affected service and perform X.
33944
33931
  - If no interactive surface is reachable, run the narrowest test or script that exercises the exact user path and prints the observable Y.
33945
33932
  - Record the command and the observed Y.
33946
33933
  - A unit test of an inner function, a log line, \`the code looks right\`, or any other proxy does not count.
33947
33934
  - If the user-visible Y cannot be produced, FAIL now. Nothing below can rescue the review.
33948
33935
  - For a bug, if a \`Reproduction <id>\` was recorded, quote it, re-run that exact user path on the PR head, and record that the wrong result is gone. FAIL if that proof does not name the identifier, even when other tests pass. If none was obtained, require the proof to say so plainly and show the regression instead; do not fail the review for a missing identifier.
33949
- - State whether the diff fulfills the authoritative intent and every current criterion without unapproved scope.
33936
+ - State whether the diff meets every checklist line and the approval quote without unapproved scope.
33950
33937
 
33951
33938
  ## 3. Empirical pass second
33952
33939
 
@@ -33955,7 +33942,7 @@ Use record_validation_stage for each assessed stage, naming the current brief re
33955
33942
  Only the author may report final_authorization as passed, after pr_checks_status reports checks passed and mergeAllowed true for the current head; the server then merges that head. A reviewer's approval or a passed stage row alone is not the composite gate.
33956
33943
 
33957
33944
  - Run the repository typecheck and tests touched by the diff.
33958
- - If the intent or a criterion names a user path, exercise that path.
33945
+ - If the spec or the approval quote names a user path, exercise that path.
33959
33946
  - Record every command and exit code.
33960
33947
  - A review with no executed command is invalid and must FAIL.
33961
33948
 
@@ -33971,9 +33958,9 @@ Only the author may report final_authorization as passed, after pr_checks_status
33971
33958
 
33972
33959
  ## 6. Bloat guard
33973
33960
 
33974
- - Compare net lines with the authoritative intent, current criteria, and typed non-goals.
33961
+ - Compare net lines with the spec, its checklist and non-goals, and the approval quote.
33975
33962
  - FAIL backwards-compatibility shims, dual paths, feature flags, or abstractions with one caller.
33976
- - FAIL machinery the authoritative intent and current criteria did not ask for.
33963
+ - FAIL machinery the spec and the approval quote did not ask for.
33977
33964
 
33978
33965
  ## 7. Security and data
33979
33966
 
@@ -33982,10 +33969,10 @@ Only the author may report final_authorization as passed, after pr_checks_status
33982
33969
  ## 8. Gate and verdict
33983
33970
 
33984
33971
  - Review the exact green head named in your reviewer instruction. If the head moved, do not approve it.
33985
- - Re-read the assigned brief revision before the verdict. A repair changes the head and invalidates affected evidence; a requirement correction invalidates the relevant verdict even if code did not change. Keep product-completeness findings (missing or contradicted intent/criteria) separate from engineering findings (correctness, security, maintainability, tests). Give every confirmed finding a stable ID that survives rereview, affected criterion IDs or \`engineering\`, location, severity, evidence, and repair disposition. Reuse the same ID until that finding is resolved. Mechanical repairs return to the author; ask a human only for a genuinely unresolved product choice. Do not run a nested validation pipeline or push the author's branch.
33972
+ - Re-read the assigned brief revision before the verdict. A repair changes the head and invalidates affected evidence; a requirement correction invalidates the relevant verdict even if code did not change. Keep product-completeness findings (a missing or contradicted checklist line or approval quote) separate from engineering findings (correctness, security, maintainability, tests). Give every confirmed finding a stable ID that survives rereview, the affected checklist line or \`engineering\`, location, severity, evidence, and repair disposition. Reuse the same ID until that finding is resolved. Mechanical repairs return to the author; ask a human only for a genuinely unresolved product choice. Do not run a nested validation pipeline or push the author's branch.
33986
33973
  - Always use this exact verdict shape:
33987
33974
 
33988
- \`verbatim human intent quoted with source message IDs:\`
33975
+ \`approval quoted with its message ID:\`
33989
33976
  \`user story:\`
33990
33977
  \`work warranted evidence:\`
33991
33978
  \`desirability evidence:\`
@@ -33993,8 +33980,8 @@ Only the author may report final_authorization as passed, after pr_checks_status
33993
33980
  \`proof of that reproduction (or none obtained + regression):\`
33994
33981
  \`how Y was demonstrated (or FAIL):\`
33995
33982
  \`commands run + results:\`
33996
- \`brief revision and hash:\`
33997
- \`criterion ledger (every current ID + status + evidence):\`
33983
+ \`brief revision:\`
33984
+ \`checklist ledger (every checklist line + status + evidence):\`
33998
33985
  \`validation stages and evidence:\`
33999
33986
  \`product-completeness findings (block):\`
34000
33987
  \`engineering findings (block):\`
@@ -34019,20 +34006,22 @@ description: Prepare or revise a durable corner assignment from Room decisions b
34019
34006
 
34020
34007
  # Durable corner brief
34021
34008
 
34022
- Create an assignment a fresh session can execute without the parent transcript. The typed outer contract is mandatory for repository and research work:
34009
+ Create an assignment a fresh session can execute without the parent transcript. A brief has three parts:
34023
34010
 
34024
- - \`intentVerbatim[]\`: exact human words plus each Room message ID. Copy snapshots exactly; never substitute a summary.
34025
- - \`buildSpec\`: agent-authored Markdown implementation guidance.
34026
- - \`criteria[]\`: observable acceptance criteria with stable numbered IDs such as AC-1. Retain IDs across revisions; do not renumber unaffected criteria.
34027
- - \`nonGoals[]\`: explicit exclusions.
34028
- - \`references[]\`: each reference or mock with a label, description, optional object ID, and authority label. An optional or agent-generated mock is not styling authority unless a human made it so.
34029
- - \`approvalBasis\`: either the initiating human command when it already settled the exact material scope, or the exact later human answer that settled a specific unresolved choice or requested brief slice.
34011
+ - \`spec\`: one Markdown doc you write, with these headings:
34012
+ - \`## Intent\`: the human's own words, quoted exactly, each with its Room message ID. Never substitute a summary.
34013
+ - \`## Checklist\`: observable done items, one per line. Keep unaffected lines as they are across revisions.
34014
+ - \`## Non-goals\`: explicit exclusions.
34015
+ - \`## References\`: each reference or mock with what it is and whose call it is. An optional or agent-generated mock is not styling authority unless a human made it so.
34016
+ Add implementation guidance under further headings when it helps.
34017
+ - files (\`attachments\`): the Room files the worker needs, each with its purpose and whether it is required.
34018
+ - \`approval\`: one human Room message ID. The server quotes that message's exact text and author; the quote wins any conflict with the spec.
34030
34019
 
34031
- Do not infer approval from silence, assent to different prose, or the mere existence of a plan. Keep agent recommendations labelled as recommendations. Do not promote a plausible UX detail, algorithm, failure message, or extra test into a requirement merely because it sounds helpful.
34020
+ Do not infer approval from silence, assent to different prose, or the mere existence of a plan. Keep agent recommendations labelled as recommendations. Do not promote a plausible UX detail, algorithm, failure message, or extra test into a checklist item merely because it sounds helpful.
34032
34021
 
34033
34022
  ## Compact path for a settled small fix
34034
34023
 
34035
- Use this when the requested behavior, touched surface, exclusions, and proof are already obvious. Inspect the narrow current behavior, write the exact intent snapshot, a short build spec, stable observable criteria, non-goals, references, and the initiating-command approval basis. Dispatch without a proposal/go ceremony. \u201CChange the message action label from Remove to Delete; leave confirmation and accessibility wording unchanged\u201D needs the visible-label criterion and both exclusions, not another confirmation question.
34024
+ Use this when the requested behavior, touched surface, exclusions, and proof are already obvious. Inspect the narrow current behavior, write a short spec (quoted intent, observable checklist, non-goals, references), and use the initiating command as the approval. Dispatch without a proposal/go ceremony. \u201CChange the message action label from Remove to Delete; leave confirmation and accessibility wording unchanged\u201D needs the visible-label checklist line and both exclusions, not another confirmation question.
34036
34025
 
34037
34026
  ## Complex-work planning loop
34038
34027
 
@@ -34040,15 +34029,15 @@ Use this default-on loop when work crosses components, changes architecture or a
34040
34029
 
34041
34030
  ### 1. Scope and current state
34042
34031
 
34043
- - Collect every relevant human message, including corrections; later corrections supersede only what they explicitly change. Preserve their exact text and IDs in \`intentVerbatim\`.
34032
+ - Collect every relevant human message, including corrections; later corrections supersede only what they explicitly change. Quote their exact text and IDs under \`## Intent\`.
34044
34033
  - Inspect current code, data contracts, tests, recent related work, repository invariants, and existing behavior. State what exists, what is missing, and what is deliberately out of scope.
34045
34034
  - Separate facts, human decisions, agent recommendations, and unresolved choices.
34046
34035
 
34047
34036
  ### 2. User stories and product boundary
34048
34037
 
34049
34038
  - Write the actor/action/observable-result stories.
34050
- - Map each story to one or more stable criterion IDs and explicit non-goals.
34051
- - If one unresolved choice would materially change behavior, scope, irreversible effects, or the intended result, present only that choice or the affected brief slice to the human. Record the exact answer message in \`approvalBasis\`. Never treat no answer as approval.
34039
+ - Map each story to one or more checklist lines and explicit non-goals.
34040
+ - If one unresolved choice would materially change behavior, scope, irreversible effects, or the intended result, present only that choice or the affected brief slice to the human. Use the answering message as the \`approval\`. Never treat no answer as approval.
34052
34041
 
34053
34042
  ### 3. Architecture and data flow
34054
34043
 
@@ -34059,29 +34048,29 @@ Use this default-on loop when work crosses components, changes architecture or a
34059
34048
  ### 4. Failure modes and test map
34060
34049
 
34061
34050
  - Enumerate missing/stale data, retries, concurrency, partial failure, authorization failure, rollback, and boundary-specific hazards that apply.
34062
- - Build an acceptance map from every criterion ID to its proof boundary: unit, integration, device/browser, server authorization, migration, or live harness. No criterion may be left without planned evidence.
34051
+ - Map every checklist line to its proof boundary: unit, integration, device/browser, server authorization, migration, or live harness. No line may be left without planned evidence.
34063
34052
 
34064
34053
  ### 5. Mocks and references
34065
34054
 
34066
34055
  - When a visual or interaction decision needs eyes, create and post one self-contained mock using the using-beeline mock procedure.
34067
- - A mock/file posted with \`post_artifact\` in this planning turn is added automatically to the brief attachment manifest; do not manually copy its object ID. Still add a typed reference explaining its authority. Existing human-posted files must be named explicitly in attachments.
34056
+ - A mock/file posted with \`post_artifact\` in this planning turn is added automatically to the brief attachment manifest; do not manually copy its object ID. Still list it under \`## References\` with whose call it is. Existing human-posted files must be named explicitly in attachments.
34068
34057
 
34069
34058
  ### 6. Implementation tasks
34070
34059
 
34071
- - Synthesize ordered, independently verifiable tasks. For each task name the affected boundary, criterion IDs, expected files/components, failure handling, and proof.
34072
- - Keep the build spec actionable, not a transcript summary.
34060
+ - Synthesize ordered, independently verifiable tasks. For each task name the affected boundary, checklist lines, expected files/components, failure handling, and proof.
34061
+ - Keep the spec actionable, not a transcript summary.
34073
34062
 
34074
34063
  ### 7. Bounded adversarial second read (default on)
34075
34064
 
34076
- - Spend one pass, bounded to the drafted scope, trying to disprove completeness: find a missing story, authority mismatch, unhandled failure, criterion without proof, mock ambiguity, accidental scope expansion, or task-order hazard.
34065
+ - Spend one pass, bounded to the drafted scope, trying to disprove completeness: find a missing story, authority mismatch, unhandled failure, checklist line without proof, mock ambiguity, accidental scope expansion, or task-order hazard.
34077
34066
  - Return findings to the planning agent and repair the draft. Escalate only a genuinely material product choice to the human; engineering choices and mechanical gaps are resolved in the plan.
34078
34067
  - End after one adversarial pass unless its repair exposes one new material product choice. Do not recursively review the review.
34079
34068
 
34080
34069
  ## Dispatch and revision
34081
34070
 
34082
- Existing authorization permits dispatch when the initiating command already settles the exact material scope. Drafting a brief does not create approval. Honor an explicit request to review first. When a later answer is needed, bind that exact message snapshot as \`explicit-human-answer\`; the server records it against the exact revision hash.
34071
+ Existing authorization permits dispatch when the initiating command already settles the exact material scope; that command is the approval. Drafting a brief does not create approval. When the scope was not already explicit, post the spec and ask the corner's opener to approve it, then use their reply as the \`approval\`. Honor an explicit request to review first.
34083
34072
 
34084
- Pass the typed contract as \`open_corner.brief\`. Read the current revision before revising and use \`revise_corner_brief\` with the complete replacement plus a concise change description. Preserve unaffected intent, criteria IDs, and authority labels. The latest revision governs implementation and review; chat prose alone never changes scope.
34073
+ Pass the brief as \`open_corner.brief\`. Read the current revision before revising and use \`revise_corner_brief\` with the complete replacement spec, the approving message, and a concise change description. Preserve unaffected intent quotes, checklist lines, and references. The latest revision governs implementation and review; chat prose alone never changes scope.
34085
34074
  `;
34086
34075
  }
34087
34076
  function beelineTriageSkillMarkdown(releaseId) {
@@ -34098,7 +34087,7 @@ Run these checks before opening a corner.
34098
34087
 
34099
34088
  ## 1. Is it clear?
34100
34089
 
34101
- - Rewrite the request as a concrete outcome and acceptance criteria.
34090
+ - Rewrite the request as a concrete outcome and a checklist of what done means.
34102
34091
  - State material exclusions needed to prevent unrequested work.
34103
34092
  - Keep the corner objective complete and within 24 words.
34104
34093
  - If an ambiguity could materially change the outcome, ask one focused question before opening the corner.
@@ -35059,6 +35048,21 @@ var HOME_SUBDIRS = [
35059
35048
  "cache",
35060
35049
  "tmp"
35061
35050
  ];
35051
+ function claudeLoginExpiresAt(text2) {
35052
+ try {
35053
+ const expiresAt = JSON.parse(text2)?.claudeAiOauth?.expiresAt;
35054
+ return typeof expiresAt === "number" && Number.isFinite(expiresAt) ? expiresAt : void 0;
35055
+ } catch {
35056
+ return void 0;
35057
+ }
35058
+ }
35059
+ async function hasNewerDetachedClaudeLogin(detached, source) {
35060
+ const detachedExpiresAt = claudeLoginExpiresAt(await readFile17(detached, "utf8"));
35061
+ if (detachedExpiresAt === void 0)
35062
+ return false;
35063
+ const sourceExpiresAt = claudeLoginExpiresAt(await readFile17(source, "utf8"));
35064
+ return sourceExpiresAt !== void 0 && detachedExpiresAt > sourceExpiresAt;
35065
+ }
35062
35066
  async function repairRoomAgentCredentialLinks(input) {
35063
35067
  const root = resolve21(input.root);
35064
35068
  const operatorHome = input.operatorHome ?? homedir13();
@@ -35079,6 +35083,9 @@ async function repairRoomAgentCredentialLinks(input) {
35079
35083
  continue;
35080
35084
  }
35081
35085
  if (stats) {
35086
+ if (input.keepNewerDetachedClaudeLogin && credential.dir === "claude" && stats.isFile() && await hasNewerDetachedClaudeLogin(target, source)) {
35087
+ continue;
35088
+ }
35082
35089
  const quarantine = `${target}.beeline-quarantine-${Date.now()}-${randomUUID8()}`;
35083
35090
  await rename5(target, quarantine);
35084
35091
  }
@@ -35106,7 +35113,11 @@ async function prepareRoomAgentHome(input) {
35106
35113
  return {};
35107
35114
  }
35108
35115
  try {
35109
- await repairRoomAgentCredentialLinks({ root, operatorHome });
35116
+ await repairRoomAgentCredentialLinks({
35117
+ root,
35118
+ operatorHome,
35119
+ keepNewerDetachedClaudeLogin: input.agentKind === "claude"
35120
+ });
35110
35121
  } catch (error) {
35111
35122
  if (input.failClosed || input.resourceAuthFile)
35112
35123
  throw error;
@@ -36274,8 +36285,6 @@ function sessionConfigFingerprint(input) {
36274
36285
  ];
36275
36286
  if (input.reviewerHandle !== void 0)
36276
36287
  fingerprint.push(input.reviewerHandle);
36277
- if (input.feedbackTriage)
36278
- fingerprint.push("feedback-triage");
36279
36288
  return JSON.stringify(fingerprint);
36280
36289
  }
36281
36290
  function mountedMcpSet(servers) {
@@ -36753,7 +36762,6 @@ function beelineAgentMcpServer(config, api, context) {
36753
36762
  ...context.cornerId ? [{ name: "BEELINE_DAEMON_CORNER_ID", value: context.cornerId }] : [],
36754
36763
  ...context.agentMayCloseCorner ? [{ name: "BEELINE_CORNER_AGENT_CLOSE", value: "1" }] : [],
36755
36764
  ...context.agentMayUpgradeCorner ? [{ name: "BEELINE_CORNER_CAN_UPGRADE", value: "1" }] : [],
36756
- ...context.feedbackTriage ? [{ name: "BEELINE_CORNER_FEEDBACK_TRIAGE", value: "1" }] : [],
36757
36765
  ...context.reviewer ? [{ name: "BEELINE_CORNER_REVIEWER", value: "1" }] : [],
36758
36766
  ...context.cornerId && context.lane ? [{ name: "BEELINE_CORNER_LANE", value: context.lane }] : [],
36759
36767
  ...context.attachRoot ? [{ name: "BEELINE_ATTACH_ROOT", value: context.attachRoot }] : [],
@@ -36934,6 +36942,11 @@ function isAccountOrProviderRefusal(record6) {
36934
36942
  // apps/body/dist/monolith-corner-turn.js
36935
36943
  init_runtime();
36936
36944
 
36945
+ // packages/api-contract/dist/system-identity.js
36946
+ import { createHash as createHash8 } from "node:crypto";
36947
+ var SYSTEM_IDENTITY_ID = createHash8("sha256").update("beeline:system-identity").digest("hex");
36948
+ var DELETED_ACCOUNT_IDENTITY_ID = createHash8("sha256").update("beeline:deleted-account").digest("hex");
36949
+
36937
36950
  // apps/body/dist/transcript-budget.js
36938
36951
  function budgetTranscript(lines, modelContextTokens, otherPromptBytes) {
36939
36952
  const context = modelContextTokens && modelContextTokens > 0 ? modelContextTokens : 32768;
@@ -36991,23 +37004,21 @@ var PROMPT_SURFACES = [
36991
37004
  "dm",
36992
37005
  "code-corner",
36993
37006
  "review-corner",
36994
- "research-corner",
36995
37007
  "no-code-corner"
36996
37008
  ];
36997
37009
  var CORNERS = [
36998
37010
  "code-corner",
36999
37011
  "review-corner",
37000
- "research-corner",
37001
37012
  "no-code-corner"
37002
37013
  ];
37003
37014
  var EVERYWHERE = PROMPT_SURFACES;
37004
- var CORNER_AUTHOR_CONTRACT = `The current assigned brief's verbatim human intent and numbered acceptance criteria are the product authority. The short objective is navigation-only text and cannot add, remove, or narrow a requirement.
37005
- Implement every current acceptance criterion and use the brief's file manifest. Record relevant validation stages with record_validation_stage against the current revision and head, citing actual commands or observed behavior. Do not call a missing stage passed.
37015
+ var CORNER_AUTHOR_CONTRACT = `The current brief's spec is the scope and its checklist says what done means. Its approval quote is the human's own words and wins any conflict with the spec. The short objective is navigation-only text and cannot add, remove, or narrow a requirement.
37016
+ Complete every checklist item in the current spec and use the brief's file manifest. Record relevant validation stages with record_validation_stage against the current revision and head, citing actual commands or observed behavior. Do not call a missing stage passed.
37006
37017
  When a human correction changes the assignment, read the latest revision and use revise_corner_brief with the complete updated brief and a change description before doing dependent work. A chat reply does not revise the assignment.
37007
37018
  Before any code, write its end-user story in one sentence: "a person who does X sees Y".
37008
- Follow the beeline-triage skill's bugfix execution contract when the verbatim human intent reports a defect.
37019
+ Follow the beeline-triage skill's bugfix execution contract when the spec or its approval quote reports a defect.
37009
37020
  Attempt to reproduce it as triage isolated it, using every tool the host offers: emulator, Playwright, browser, test runner. Record what was tried and what was observed. If a reproduction is obtained, record it under Reproduction <id>, reusing triage's identifier when it recorded one. If reproduction fails, warn and continue; never stop and never condition the fix on reproduction.
37010
- Narrow the fix to the authorized intent and current criteria. When a reproduction exists, change only what removes it while satisfying those criteria.
37021
+ Narrow the fix to the current spec and its approval quote. When a reproduction exists, change only what removes it while meeting the checklist.
37011
37022
  Before opening the pull request, produce Y against the built change: run the app or affected service from your branch and perform X.
37012
37023
  If no interactive surface is reachable, run the narrowest test or script that exercises the exact user path and prints the observable Y.
37013
37024
  A unit test of an inner function, a log line, or reading the code is not a demonstration.
@@ -37015,13 +37026,16 @@ The pull request body MUST contain two sections with exactly these headings: ##
37015
37026
  Under ## Reproduced, name Reproduction <id> and give the steps or command and what was observed; write "not obtained" when reproduction failed, or "not a defect report" for feature work.
37016
37027
  Under ## Demonstrated, cite the same identifier and show that reproduction now passing when one exists; when none was obtained, state that plainly and show the regression instead.
37017
37028
  A pull request without both sections is not deliverable and the Room's reviewer will fail it.
37018
- Change only what the verbatim intent and current criteria authorize. No unrequested features, flags, compatibility shims, or refactors.`;
37029
+ Change only what the current spec and its approval quote authorize. No unrequested features, flags, compatibility shims, or refactors.`;
37019
37030
  var CORNER_REVIEWER_SESSION_INSTRUCTION = "You are this Room's configured reviewer. The active turn prompt names the latest stable green PR head. Review and approve only that exact head; if no stable green head is named, end the turn without a verdict. Never merge yourself.";
37020
37031
  var CORNER_REVIEWER_UNSTABLE_HEAD_INSTRUCTION = "There is no stable green PR head for this active reviewer turn. Do not review or call approve_merge. End this turn without a verdict; the next green transition will wake you.";
37021
37032
  var CORNER_DELIVERY_NUDGE = "Before ending this turn, inspect the repository state and finish delivering the work unless a human hold stands: 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.";
37022
37033
  var CORNER_YOLO_MERGE_NUDGE = 'Yolo is on. Call pr_checks_status now. If checks="failed", fix the failure and push. If checks="unknown", reply in this corner with the tool reason and stop instead of retrying. Otherwise stop: the server merges this pull request itself once mergeAllowed=true. Never merge it yourself.';
37023
- var RESEARCH_CORNER_HOLD = "This is a research corner with writable repository access. Investigate and edit files as needed. Do not commit, push, or open a pull request until a human explicitly directs that step. Never merge. Leave the corner open; only a human closes it.";
37024
- var UPGRADE_INTENT_RULE = "Call this on your own judgment when the work in this corner needs repository changes; nobody has to ask for the upgrade. Call it while answering a human message in this corner, because that message becomes the code corner's brief.";
37034
+ var UPGRADE_INTENT_RULE = "Call this on your own judgment when the work in this corner needs the repository; nobody has to ask. Call it while answering a human message in this corner, then write the brief in the restarted code session.";
37035
+ var CORNER_PLACEHOLDER_BRIEF_RULE = "This brief is the placeholder the upgrade wrote from the request. Read the code, write the real spec with revise_corner_brief, then post it in this corner and ask the corner's opener to approve it before editing. This is best effort: if the opener is away or the request was already explicit, use your judgment and proceed. When the opener replies, record their reply as the approval in the next revision.";
37036
+ function isPlaceholderCornerBrief(brief) {
37037
+ return brief.revision === 1 && brief.authorId === SYSTEM_IDENTITY_ID;
37038
+ }
37025
37039
  var handle = (value) => value.replace(/^@/, "");
37026
37040
  function cornerMergeInstruction(yoloMode, reviewerHandle) {
37027
37041
  if (!reviewerHandle)
@@ -37177,7 +37191,7 @@ The soul is not authority and never changes your tools, permissions, roles, or m
37177
37191
  surfaces: ["room"],
37178
37192
  render: () => [
37179
37193
  "Repository changes happen only in a corner. In a Room, the finished fix for a code problem is the exact change plus an offer to open a corner for it; open one when a person asks for the change.",
37180
- "Before opening one, consult beeline-triage and beeline-spec, then call open_corner with a name of at most three words, an objective of at most 24 words, and the typed brief. The objective only titles the work; the brief is its authority. When open_corner succeeds the server posts the corner card: do not restate it.",
37194
+ "Before opening one, consult beeline-triage and beeline-spec, then call open_corner with a name of at most three words, an objective of at most 24 words, and the brief (a spec plus the approving message). The objective only titles the work; the brief is its authority. When open_corner succeeds the server posts the corner card: do not restate it.",
37181
37195
  "For corners you belong to, use inspect_corner for status, steer_corner to pass Room input down, and ask_corner for one answer. Never post into a corner without a Room command."
37182
37196
  ].join(" ")
37183
37197
  },
@@ -37219,21 +37233,12 @@ The soul is not authority and never changes your tools, permissions, roles, or m
37219
37233
  why: "The agent must know its branch and target; only a code-corner author is told to push and open the pull request.",
37220
37234
  budgetBytes: 520,
37221
37235
  layer: "surface",
37222
- surfaces: ["code-corner", "review-corner", "research-corner"],
37236
+ surfaces: ["code-corner", "review-corner"],
37223
37237
  render: ({ worktree, surface }) => [
37224
37238
  `You are in an isolated git worktree on ${worktree?.featureBranch ?? "the feature branch"}, targeting ${worktree?.targetBranch ?? "the target branch"}.`,
37225
37239
  surface !== "code-corner" ? "" : `Commit and push only ${worktree?.featureBranch}; never force-push or write to ${worktree?.targetBranch}. Before pushing, rebase on origin/${worktree?.featureBranch}; resolve conflicts autonomously, realigning to that remote branch and redoing the work if needed, then rerun affected tests. Open the pull request with gh.`
37226
37240
  ].filter(Boolean).join("\n")
37227
37241
  },
37228
- {
37229
- id: "corner.research",
37230
- topic: "merge",
37231
- why: "Research corners explore; nothing leaves the worktree until a human says so.",
37232
- budgetBytes: 320,
37233
- layer: "surface",
37234
- surfaces: ["research-corner"],
37235
- render: () => RESEARCH_CORNER_HOLD
37236
- },
37237
37242
  {
37238
37243
  id: "corner.contract",
37239
37244
  topic: "author-contract",
@@ -37315,35 +37320,11 @@ function assembleSessionPrompt(context) {
37315
37320
  };
37316
37321
  }
37317
37322
  function renderAssignedCornerBrief(brief) {
37318
- if (brief.legacy || !Array.isArray(brief.intentVerbatim) || !Array.isArray(brief.criteria)) {
37319
- return `Legacy assigned corner brief ${brief.id} revision ${brief.revision}:
37320
- ${brief.content}`;
37321
- }
37322
- const intent = brief.intentVerbatim.map((item) => `- [message ${item.sourceMessageId}] ${item.snapshot}`).join("\n");
37323
- const criteria = brief.criteria.map((item) => `- ${item.id}: ${item.text}`).join("\n");
37324
- const nonGoals = brief.nonGoals?.map((item) => `- ${item}`).join("\n") || "(none)";
37325
- const references2 = brief.references?.map((item) => `- ${item.label} [${item.authority}]${item.objectId ? ` object ${item.objectId}` : ""}: ${item.description}`).join("\n") || "(none)";
37326
- const basis = brief.approvalBasis;
37327
- const approval = basis.kind === "legacy-pre-migration" ? basis.reason : `${basis.kind} by ${basis.approvedBy}, message ${basis.sourceMessageId}: ${basis.snapshot}`;
37328
- return `Assigned corner brief ${brief.id} revision ${brief.revision} (hash ${brief.revisionHash}; current server revision):
37329
-
37330
- Verbatim human intent \u2014 authoritative:
37331
- ${intent}
37332
-
37333
- Current acceptance criteria \u2014 authoritative:
37334
- ${criteria}
37335
-
37336
- Non-goals:
37337
- ${nonGoals}
37338
-
37339
- References and authority:
37340
- ${references2}
37323
+ const approval = brief.approval ? `Approved by ${brief.approval.approverName}, message ${brief.approval.sourceMessageId}: ${brief.approval.text}` : "This revision predates recorded approvals.";
37324
+ return `Brief revision ${brief.revision}:
37325
+ ${brief.spec}
37341
37326
 
37342
- Approval basis bound to this revision:
37343
- ${approval}
37344
-
37345
- Build spec \u2014 implementation guidance:
37346
- ${brief.buildSpec}`;
37327
+ ${approval}`;
37347
37328
  }
37348
37329
  function roomMentionDirectory(roster, selfId) {
37349
37330
  const rows = [];
@@ -37381,6 +37362,15 @@ var TURN_SECTIONS = [
37381
37362
  surfaces: CORNERS,
37382
37363
  render: ({ objective }) => objective ? `Corner objective (navigation only, not product authority): ${objective}` : ""
37383
37364
  },
37365
+ {
37366
+ id: "turn.rename",
37367
+ topic: "corner-rename",
37368
+ why: "A generated corner name says nothing about the work; only the server knows the name is still generated, so the ask rides only on those turns.",
37369
+ budgetBytes: 600,
37370
+ layer: "turn",
37371
+ surfaces: CORNERS,
37372
+ render: ({ generatedTitle }) => generatedTitle ? `This corner still has its generated name, "${generatedTitle}". If the newest message states the work, call rename_corner once before you reply, with a name of at most three words taken from that message. A bare mention does not state the work; leave the name until a message does.` : ""
37373
+ },
37384
37374
  {
37385
37375
  id: "turn.brief",
37386
37376
  topic: "brief",
@@ -37388,10 +37378,12 @@ var TURN_SECTIONS = [
37388
37378
  budgetBytes: 24e3,
37389
37379
  layer: "turn",
37390
37380
  surfaces: CORNERS,
37391
- render: ({ brief }) => brief ? `${renderAssignedCornerBrief(brief.brief)}
37381
+ render: ({ brief, surface }) => brief ? `${renderAssignedCornerBrief(brief.brief)}
37392
37382
 
37393
37383
  Assigned files:
37394
- ${brief.fileLines.join("\n") || "(none)"}${brief.missingRequiredFile ? "\nRequired assignment files are unavailable. Pause work that depends on them and report the missing file precisely." : ""}` : "No assigned brief: the human messages in this corner are the authority; skip steps that need a brief revision."
37384
+ ${brief.fileLines.join("\n") || "(none)"}${brief.missingRequiredFile ? "\nRequired assignment files are unavailable. Pause work that depends on them and report the missing file precisely." : ""}${surface === "code-corner" && isPlaceholderCornerBrief(brief.brief) ? `
37385
+
37386
+ ${CORNER_PLACEHOLDER_BRIEF_RULE}` : ""}` : "No assigned brief: the human messages in this corner are the authority; skip steps that need a brief revision."
37395
37387
  },
37396
37388
  {
37397
37389
  id: "turn.checkout",
@@ -38040,7 +38032,7 @@ process.exit(result.status ?? 1);
38040
38032
  }
38041
38033
 
38042
38034
  // apps/body/dist/warm-node-modules.js
38043
- import { createHash as createHash8, randomUUID as randomUUID9 } from "node:crypto";
38035
+ import { createHash as createHash9, randomUUID as randomUUID9 } from "node:crypto";
38044
38036
  import { constants as fsConstants3 } from "node:fs";
38045
38037
  import { chmod as chmod8, copyFile as copyFile2, link, lstat as lstat4, mkdir as mkdir17, readdir as readdir7, readFile as readFile19, readlink as readlink2, rename as rename6, rm as rm8, stat as stat6, symlink as symlink3, utimes } from "node:fs/promises";
38046
38038
  import { dirname as dirname16, join as join13, resolve as resolve27 } from "node:path";
@@ -38079,7 +38071,7 @@ async function readWarmPlan(worktreePath) {
38079
38071
  const unsafe = trees.find((tree) => !isContainedTreePath(tree));
38080
38072
  if (unsafe)
38081
38073
  return { failure: "unsafe-lockfile", detail: unsafe };
38082
- const key = createHash8("sha256").update(`${STORE_FORMAT}\0${process.platform}\0${process.arch}\0${process.versions.modules}\0`).update(lockfile).digest("hex").slice(0, 32);
38074
+ const key = createHash9("sha256").update(`${STORE_FORMAT}\0${process.platform}\0${process.arch}\0${process.versions.modules}\0`).update(lockfile).digest("hex").slice(0, 32);
38083
38075
  return { key, trees };
38084
38076
  }
38085
38077
  function nodeModulesTreePaths(packages) {
@@ -38497,7 +38489,7 @@ function spentAuthorityOnLaneUpgrade(call) {
38497
38489
  return /(?:^|[._:/-])upgrade_corner_to_code$/i.test(call.title ?? "") && isCompletedToolCall(call);
38498
38490
  }
38499
38491
  function toolCallKey(call, index) {
38500
- return call.id ? `id-${createHash9("sha256").update(call.id).digest("hex")}` : `tool-${index}`;
38492
+ return call.id ? `id-${createHash10("sha256").update(call.id).digest("hex")}` : `tool-${index}`;
38501
38493
  }
38502
38494
  function toolCallSettled(call) {
38503
38495
  if (call.resultReceived)
@@ -38770,8 +38762,7 @@ var MonolithCornerTurnLoop = class {
38770
38762
  }),
38771
38763
  ...registryRoutes.map((route) => route.routeName)
38772
38764
  ], this.sessionCodegraphReady),
38773
- reviewerHandle: configuration.reviewerHandle,
38774
- feedbackTriage: configuration.feedbackTriage
38765
+ reviewerHandle: configuration.reviewerHandle
38775
38766
  });
38776
38767
  }
38777
38768
  async grantedHostRoutes() {
@@ -38798,7 +38789,8 @@ var MonolithCornerTurnLoop = class {
38798
38789
  if (this.options.config.agentHomeRoot) {
38799
38790
  await repairRoomAgentCredentialLinks({
38800
38791
  root: this.options.config.agentHomeRoot,
38801
- operatorHome: this.options.config.operatorHome
38792
+ operatorHome: this.options.config.operatorHome,
38793
+ keepNewerDetachedClaudeLogin: this.options.config.agentKind === "claude"
38802
38794
  });
38803
38795
  }
38804
38796
  return this.sessionId;
@@ -38821,10 +38813,10 @@ var MonolithCornerTurnLoop = class {
38821
38813
  authorHandle: opener?.handle,
38822
38814
  openedByAgent: !this.options.openedBy || this.options.openedBy === this.agent.publicKey
38823
38815
  };
38824
- const reviewerInstruction = this.options.lane !== "research" && cornerReviewerInstruction(reviewerInput) ? CORNER_REVIEWER_SESSION_INSTRUCTION : void 0;
38816
+ const reviewerInstruction = cornerReviewerInstruction(reviewerInput) ? CORNER_REVIEWER_SESSION_INSTRUCTION : void 0;
38825
38817
  this.reviewerInstructionInput = reviewerInstruction ? reviewerInput : void 0;
38826
- const selfReviewerInstruction = this.options.lane === "research" ? void 0 : cornerSelfReviewerInstruction(reviewerInput);
38827
- this.sessionSurface = !this.options.repository ? "no-code-corner" : this.options.lane === "research" ? "research-corner" : reviewerInstruction ? "review-corner" : "code-corner";
38818
+ const selfReviewerInstruction = cornerSelfReviewerInstruction(reviewerInput);
38819
+ this.sessionSurface = !this.options.repository ? "no-code-corner" : reviewerInstruction ? "review-corner" : "code-corner";
38828
38820
  this.sessionPromptContext = {
38829
38821
  surface: this.sessionSurface,
38830
38822
  agentName: self?.name ?? this.agent.name,
@@ -38991,8 +38983,7 @@ var MonolithCornerTurnLoop = class {
38991
38983
  }),
38992
38984
  ...Object.keys(registryHostDeclarations)
38993
38985
  ], codegraphReady),
38994
- reviewerHandle: configuration.reviewerHandle,
38995
- feedbackTriage: configuration.feedbackTriage
38986
+ reviewerHandle: configuration.reviewerHandle
38996
38987
  });
38997
38988
  const servers = [
38998
38989
  ...repository ? [
@@ -39020,9 +39011,8 @@ var MonolithCornerTurnLoop = class {
39020
39011
  roomId: this.options.parentRoomId,
39021
39012
  workspaceId: this.options.workspaceId,
39022
39013
  cornerId: this.options.cornerId,
39023
- agentMayCloseCorner: Boolean(repository) && this.options.lane !== "research",
39014
+ agentMayCloseCorner: Boolean(repository),
39024
39015
  agentMayUpgradeCorner: this.options.agentMayUpgradeCorner,
39025
- feedbackTriage: configuration.feedbackTriage === true,
39026
39016
  reviewer: Boolean(reviewerInstruction),
39027
39017
  lane: this.options.lane ?? (repository ? "code" : "no_code"),
39028
39018
  attachRoot: this.options.worktreePath,
@@ -39321,7 +39311,7 @@ var MonolithCornerTurnLoop = class {
39321
39311
  const delivered = this.attachmentDir && allAttachments.length ? await deliverAttachments(allAttachments, join14(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : [];
39322
39312
  const briefFileLines = await Promise.all((restored.brief?.attachments ?? []).map(async (file, index) => {
39323
39313
  const entry = delivered.find((item) => item.attachment === briefAttachments[index]);
39324
- const verified = entry?.path && createHash9("sha256").update(await readFile20(entry.path)).digest("hex") === file.sha256;
39314
+ const verified = entry?.path && createHash10("sha256").update(await readFile20(entry.path)).digest("hex") === file.sha256;
39325
39315
  return `- ${file.title} (${file.purpose}; ${file.required ? "required" : "optional"}; sha256 ${file.sha256}): ${verified ? entry.path : "UNAVAILABLE OR CONTENT MISMATCH"}`;
39326
39316
  }));
39327
39317
  const missingRequiredBriefFile = (restored.brief?.attachments ?? []).some((file, index) => file.required && briefFileLines[index]?.includes("UNAVAILABLE OR CONTENT MISMATCH"));
@@ -39343,6 +39333,7 @@ var MonolithCornerTurnLoop = class {
39343
39333
  surface: this.sessionSurface,
39344
39334
  sessionPrefix: this.turnSessionPrefix,
39345
39335
  objective: this.options.objective,
39336
+ ...restored.titleGenerated && restored.title ? { generatedTitle: restored.title } : {},
39346
39337
  ...restored.brief ? {
39347
39338
  brief: {
39348
39339
  brief: restored.brief,
@@ -39515,6 +39506,12 @@ var MonolithCornerTurnLoop = class {
39515
39506
  loginRetryUsed = true;
39516
39507
  console.warn(`[thin-core] corner ${cornerId} turn ${requestId}: harness login expired; repairing the shared credential and retrying once`);
39517
39508
  trace.retry({ reason: "expired harness login" });
39509
+ if (this.options.config.agentHomeRoot) {
39510
+ await repairRoomAgentCredentialLinks({
39511
+ root: this.options.config.agentHomeRoot,
39512
+ operatorHome: this.options.config.operatorHome
39513
+ });
39514
+ }
39518
39515
  await this.discardSession();
39519
39516
  await trace.measure("activation", () => this.activate(trace));
39520
39517
  try {
@@ -39564,7 +39561,7 @@ var MonolithCornerTurnLoop = class {
39564
39561
  explained = await this.explainEmpty(result);
39565
39562
  }
39566
39563
  const checksTurn = isCornerChecksTurn(trigger, restates);
39567
- const deliveryState = !checksTurn && this.options.repository && this.options.lane !== "research" ? await cornerUndeliveredRepositoryState(this.options.worktreePath, this.options.repository.featureBranch, this.options.repository.targetBranch) : void 0;
39564
+ const deliveryState = !checksTurn && this.options.repository ? await cornerUndeliveredRepositoryState(this.options.worktreePath, this.options.repository.featureBranch, this.options.repository.targetBranch) : void 0;
39568
39565
  const needsDeliveryNudge = deliveryState !== void 0 && deliveryState !== this.lastDeliveryNudgeState;
39569
39566
  let refreshedReviewerInstruction;
39570
39567
  let reviewerSecondPass = false;
@@ -39576,7 +39573,7 @@ var MonolithCornerTurnLoop = class {
39576
39573
  reviewerTargetChanged = refreshedReviewerInstruction !== activeReviewerInstruction;
39577
39574
  }
39578
39575
  let replyBeforeNudge = "";
39579
- if (!explained && (needsDeliveryNudge || checksTurn && this.options.lane !== "research" && (Boolean(this.reviewerInstructionInput) || this.yoloMode))) {
39576
+ if (!explained && (needsDeliveryNudge || checksTurn && (Boolean(this.reviewerInstructionInput) || this.yoloMode))) {
39580
39577
  if (needsDeliveryNudge)
39581
39578
  this.lastDeliveryNudgeState = deliveryState;
39582
39579
  await flushToolCalls(result.toolCalls, "");
@@ -40229,7 +40226,8 @@ var MonolithRoomTurnLoop = class {
40229
40226
  if (this.options.config.agentHomeRoot) {
40230
40227
  await repairRoomAgentCredentialLinks({
40231
40228
  root: this.options.config.agentHomeRoot,
40232
- operatorHome: this.options.config.operatorHome
40229
+ operatorHome: this.options.config.operatorHome,
40230
+ keepNewerDetachedClaudeLogin: this.options.config.agentKind === "claude"
40233
40231
  });
40234
40232
  }
40235
40233
  return this.sessionId;
@@ -40755,6 +40753,12 @@ var MonolithRoomTurnLoop = class {
40755
40753
  loginRetryUsed = true;
40756
40754
  console.warn(`[thin-core] monolith Room ${this.options.roomId} turn ${item.id}: harness login expired; repairing the shared credential and retrying once`);
40757
40755
  trace.retry({ reason: "expired harness login" });
40756
+ if (this.options.config.agentHomeRoot) {
40757
+ await repairRoomAgentCredentialLinks({
40758
+ root: this.options.config.agentHomeRoot,
40759
+ operatorHome: this.options.config.operatorHome
40760
+ });
40761
+ }
40758
40762
  await this.discardSession();
40759
40763
  await trace.measure("activation", () => this.activate(trace));
40760
40764
  continue;
@@ -41524,7 +41528,7 @@ function cornerStartConfigKey(repository, objective) {
41524
41528
  }
41525
41529
  function cornerRepositoryCacheDir(supervisorRoot, remote) {
41526
41530
  const normalizedRemote = roomCheckoutRemote(remote);
41527
- const repositoryHash = createHash10("sha256").update(normalizedRemote).digest("hex").slice(0, 24);
41531
+ const repositoryHash = createHash11("sha256").update(normalizedRemote).digest("hex").slice(0, 24);
41528
41532
  return resolve29(supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
41529
41533
  }
41530
41534
  function isStandingCornerStartFault(error) {
@@ -42318,7 +42322,7 @@ var RoomRuntimeCoordinator = class {
42318
42322
  return this.roomRoot(roomId);
42319
42323
  const remote = roomCheckoutRemote(repository.remote);
42320
42324
  const targetBranch = repository.targetBranch || "main";
42321
- const checkoutId = createHash10("sha256").update(`${roomId}\0${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
42325
+ const checkoutId = createHash11("sha256").update(`${roomId}\0${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
42322
42326
  const path = resolve29(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
42323
42327
  await mkdir20(dirname19(path), { recursive: true, mode: 448 });
42324
42328
  const token = remote.startsWith("https://github.com/") ? await this.parentRepositoryToken(roomId) : void 0;
@@ -43199,7 +43203,7 @@ init_runtime();
43199
43203
  init_launchd();
43200
43204
  init_systemd();
43201
43205
  import { spawn as spawn11 } from "node:child_process";
43202
- import { createHash as createHash11 } from "node:crypto";
43206
+ import { createHash as createHash12 } from "node:crypto";
43203
43207
  import { mkdir as mkdir23, rm as rm11, stat as stat7, writeFile as writeFile17 } from "node:fs/promises";
43204
43208
  import { dirname as dirname21, resolve as resolve33 } from "node:path";
43205
43209
 
@@ -43609,7 +43613,7 @@ var DEFAULT_UPDATE_INTERVAL_MS = 3e4;
43609
43613
  var UPDATE_DRAIN_DEADLINE_MS = UPDATE_CONVERGENCE_SLO_MS - 15e4;
43610
43614
  var MAX_HOST_RESTART_STAGGER_MS = 15e3;
43611
43615
  function managedRestartStaggerMs(agentId, desiredRelease, drainDeadlineAt, now2 = Date.now()) {
43612
- const digest = createHash11("sha256").update(agentId).update("\0").update(desiredRelease).digest();
43616
+ const digest = createHash12("sha256").update(agentId).update("\0").update(desiredRelease).digest();
43613
43617
  const spread = digest.readUInt32BE(0) % (MAX_HOST_RESTART_STAGGER_MS + 1);
43614
43618
  return Math.min(spread, Math.max(0, drainDeadlineAt - now2));
43615
43619
  }
@@ -44604,7 +44608,7 @@ async function runStartCommand(args, interactiveUi, dependencyOverrides = {}) {
44604
44608
 
44605
44609
  // apps/body/dist/connect-command.js
44606
44610
  import { spawn as spawn12 } from "node:child_process";
44607
- import { createHash as createHash12, randomUUID as randomUUID10 } from "node:crypto";
44611
+ import { createHash as createHash13, randomUUID as randomUUID10 } from "node:crypto";
44608
44612
  import { chmod as chmod9, mkdir as mkdir25, readFile as readFile23, unlink as unlink7, writeFile as writeFile18 } from "node:fs/promises";
44609
44613
  import { homedir as homedir17, hostname as hostname3 } from "node:os";
44610
44614
  import { dirname as dirname24, resolve as resolve35 } from "node:path";
@@ -45294,7 +45298,7 @@ async function readMachineId(env = process.env) {
45294
45298
  await writeFile18(machineIdPath, `${machineId}
45295
45299
  `, { mode: 384 });
45296
45300
  } catch {
45297
- machineId = createHash12("sha256").update(machineName).digest("hex").slice(0, 36);
45301
+ machineId = createHash13("sha256").update(machineName).digest("hex").slice(0, 36);
45298
45302
  }
45299
45303
  }
45300
45304
  return { machineId, machineName };
@@ -45303,7 +45307,7 @@ function requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl, machine
45303
45307
  const normalizedPairingCode = normalizeAgentPairingCode(pairingCode);
45304
45308
  if (!normalizedPairingCode)
45305
45309
  throw new Error("invalid pairing code");
45306
- const avatarSeed = createHash12("sha256").update(normalizedPairingCode.toUpperCase()).digest("hex").slice(0, 32);
45310
+ const avatarSeed = createHash13("sha256").update(normalizedPairingCode.toUpperCase()).digest("hex").slice(0, 32);
45307
45311
  return jsonRequest(`${baseUrl}/auth/agent/connect`, {
45308
45312
  pairing_code: normalizedPairingCode,
45309
45313
  harness: selection.harness,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "usebeeline",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Connect an AI coding agent to Beeline with one command.",
5
5
  "homepage": "https://usebeeline.app",
6
6
  "bugs": {