orion-super-agent-dev 0.1.24 → 0.1.25

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/out/main.js CHANGED
@@ -2230,7 +2230,7 @@ var require_react_jsx_runtime_development = __commonJS({
2230
2230
  if (process.env.NODE_ENV !== "production") {
2231
2231
  (function() {
2232
2232
  "use strict";
2233
- var React32 = require_react();
2233
+ var React33 = require_react();
2234
2234
  var REACT_ELEMENT_TYPE = Symbol.for("react.element");
2235
2235
  var REACT_PORTAL_TYPE = Symbol.for("react.portal");
2236
2236
  var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
@@ -2256,7 +2256,7 @@ var require_react_jsx_runtime_development = __commonJS({
2256
2256
  }
2257
2257
  return null;
2258
2258
  }
2259
- var ReactSharedInternals = React32.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2259
+ var ReactSharedInternals = React33.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2260
2260
  function error(format2) {
2261
2261
  {
2262
2262
  {
@@ -9963,9 +9963,9 @@ var require_react_reconciler_development = __commonJS({
9963
9963
  module2.exports = function $$$reconciler($$$hostConfig) {
9964
9964
  var exports3 = {};
9965
9965
  "use strict";
9966
- var React32 = require_react();
9966
+ var React33 = require_react();
9967
9967
  var Scheduler = require_scheduler();
9968
- var ReactSharedInternals = React32.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
9968
+ var ReactSharedInternals = React33.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
9969
9969
  var suppressWarning = false;
9970
9970
  function setSuppressWarning(newSuppressWarning) {
9971
9971
  {
@@ -29222,14 +29222,12 @@ var require_duetEntry = __commonJS({
29222
29222
  {
29223
29223
  value: "executor",
29224
29224
  label: "Executor decides",
29225
- description: "Your local executor routes. No planner call, no download."
29225
+ description: "Your executor routes. No planner call, no download."
29226
29226
  }
29227
29227
  ];
29228
- function effectiveDuetEntry(setting, routerState, executorState) {
29228
+ function effectiveDuetEntry(setting, routerState) {
29229
29229
  if (setting === "router" && routerState !== "ready")
29230
29230
  return { entry: "planner", downgraded: true };
29231
- if (setting === "executor" && executorState !== "ready")
29232
- return { entry: "planner", downgraded: true };
29233
29231
  return { entry: setting, downgraded: false };
29234
29232
  }
29235
29233
  function duetEntryLabel2(entry) {
@@ -29368,20 +29366,18 @@ var require_duetExecutorGateStatus = __commonJS({
29368
29366
  "use strict";
29369
29367
  Object.defineProperty(exports2, "__esModule", { value: true });
29370
29368
  exports2.executorGateStatusLine = executorGateStatusLine2;
29371
- exports2.executorGateDowngradeNote = executorGateDowngradeNote;
29369
+ exports2.executorGateFallbackNote = executorGateFallbackNote;
29372
29370
  exports2.executorGateOptionAvailability = executorGateOptionAvailability;
29373
29371
  function unavailableWhy(reason, problem) {
29374
29372
  switch (reason) {
29375
29373
  case "not_resolved":
29376
29374
  return "its endpoint is not configured";
29377
- case "not_loopback":
29378
- return "it is not on this machine";
29379
29375
  case "unreachable":
29380
29376
  return "it is not answering";
29381
29377
  case "no_completions":
29382
29378
  return "it has no /v1/completions route";
29383
29379
  case "thinking":
29384
- return "it answers with thinking on (load it with thinking off)";
29380
+ return "its completions route answers thinking text, not a plain token";
29385
29381
  case "unparseable":
29386
29382
  return "it did not answer E or P";
29387
29383
  case "error":
@@ -29395,30 +29391,30 @@ var require_duetExecutorGateStatus = __commonJS({
29395
29391
  case "miscalibrated":
29396
29392
  return `Executor gate: ${status.target.model} on '${status.target.name}' misrouted ${status.calibration.failed.length} of ${status.calibration.total} probe scenarios (${status.mode}, threshold ${status.threshold}) \u2014 tune executorGate.threshold on that endpoint.`;
29397
29393
  case "platform":
29398
- return "Executor gate: needs a local executor \u2014 the Duet executor is a platform model.";
29394
+ return "Executor gate: the Duet executor is a platform model \u2014 this entry routes on Duet's rules.";
29399
29395
  case "unavailable":
29400
- return `Executor gate: not available \u2014 ${unavailableWhy(status.reason, status.problem)}.`;
29396
+ return `Executor gate: not asking \u2014 ${unavailableWhy(status.reason, status.problem)}.`;
29401
29397
  }
29402
29398
  }
29403
- function executorGateDowngradeNote(status) {
29399
+ function executorGateFallbackNote(status) {
29404
29400
  const why = status.state === "platform" ? "the Duet executor is a platform model" : status.state === "unavailable" ? unavailableWhy(status.reason, status.problem) : "it could not run";
29405
- return `Executor decides needs a local executor that answers a one-token routing question and ${why} \u2014 this turn ran through the planner instead.`;
29401
+ return `Executor decides could not ask your executor (${why}) \u2014 this turn routed on Duet's rules instead.`;
29406
29402
  }
29407
29403
  function executorGateOptionAvailability(status) {
29408
29404
  if (status === null || status.state === "ready")
29409
29405
  return { disabled: false, note: null };
29410
29406
  switch (status.state) {
29411
29407
  case "platform":
29412
- return { disabled: true, note: "Needs a local executor (the Duet executor is a platform model)." };
29408
+ return { disabled: false, note: "The executor is a platform model \u2014 routes on Duet's rules." };
29413
29409
  case "miscalibrated":
29414
29410
  return {
29415
- disabled: true,
29416
- note: `The executor's routing gate failed calibration (${status.calibration.passed}/${status.calibration.total}) \u2014 see the Duet card.`
29411
+ disabled: false,
29412
+ note: `The gate misrouted ${status.calibration.failed.length} of ${status.calibration.total} probe scenarios \u2014 tune executorGate.threshold on that endpoint.`
29417
29413
  };
29418
29414
  case "unavailable":
29419
29415
  return {
29420
- disabled: true,
29421
- note: `Needs a local executor that answers /v1/completions (${unavailableWhy(status.reason, status.problem)}).`
29416
+ disabled: false,
29417
+ note: `The executor cannot be asked right now (${unavailableWhy(status.reason, status.problem)}) \u2014 routes on Duet's rules.`
29422
29418
  };
29423
29419
  }
29424
29420
  }
@@ -29899,9 +29895,9 @@ var require_duetRouterModel = __commonJS({
29899
29895
  if (setting === "executor") {
29900
29896
  if (opts.executorGate !== void 0)
29901
29897
  return opts.executorGate.prepareTurn(text, ctx);
29902
- const note = executorNoted ? null : (0, duetExecutorGateStatus_js_1.executorGateDowngradeNote)({ state: "unavailable", reason: "error", problem: "this host has no executor gate" });
29898
+ const note = executorNoted ? null : (0, duetExecutorGateStatus_js_1.executorGateFallbackNote)({ state: "unavailable", reason: "error", problem: "this host has no executor gate" });
29903
29899
  executorNoted = true;
29904
- return { ...(0, duetEntry_js_1.effectiveDuetEntry)("executor", void 0, "unavailable"), verdict: null, note };
29900
+ return { entry: "executor", verdict: null, note };
29905
29901
  }
29906
29902
  if (setting !== "router")
29907
29903
  return { entry: setting, verdict: null, note: null };
@@ -33479,6 +33475,8 @@ var require_segmentDriver = __commonJS({
33479
33475
  body2.workspace_root = routing.workspaceRoot;
33480
33476
  if (routing.clientType !== void 0)
33481
33477
  body2.client_type = routing.clientType;
33478
+ if (routing.clientVersion !== void 0)
33479
+ body2.client_version = routing.clientVersion;
33482
33480
  if (routing.mode !== void 0)
33483
33481
  body2.mode = routing.mode;
33484
33482
  if (routing.reasoning !== void 0)
@@ -34772,7 +34770,10 @@ var require_frames = __commonJS({
34772
34770
  if (typeof frame.id !== "string") {
34773
34771
  throw new FrameDecodeError("malformed renew_bearer frame");
34774
34772
  }
34775
- return { type: "renew_bearer", id: frame.id };
34773
+ const decoded = { type: "renew_bearer", id: frame.id };
34774
+ if (typeof frame.refused === "string")
34775
+ decoded.refused = frame.refused;
34776
+ return decoded;
34776
34777
  }
34777
34778
  case "rpc_result": {
34778
34779
  if (typeof frame.id !== "string" || !("result" in frame)) {
@@ -37267,7 +37268,6 @@ var require_duetExecutorGate = __commonJS({
37267
37268
  var duetMode_js_1 = require_duetMode();
37268
37269
  var duetPlan_js_1 = require_duetPlan();
37269
37270
  var duetRoutingAdvisor_js_1 = require_duetRoutingAdvisor();
37270
- var duetEntry_js_1 = require_duetEntry();
37271
37271
  var duetExecutorGateStatus_js_1 = require_duetExecutorGateStatus();
37272
37272
  exports2.EXECUTOR_GATE_SOURCE = "executor_gate";
37273
37273
  exports2.EXECUTOR_GATE_PROMPT_VERSION = "1";
@@ -37292,9 +37292,6 @@ var require_duetExecutorGate = __commonJS({
37292
37292
  if (routing === void 0) {
37293
37293
  return { state: "unavailable", reason: "not_resolved", problem: "the executor's endpoint is not configured", name: name2 };
37294
37294
  }
37295
- if (!(0, customProviders_js_1.isLoopbackEndpoint)(routing.baseUrl)) {
37296
- return { state: "unavailable", reason: "not_loopback", problem: "the executor is not on this machine", name: name2 };
37297
- }
37298
37295
  if (!deps2.alive(workspaceRoot)) {
37299
37296
  return { state: "unavailable", reason: "unreachable", problem: "the executor is not answering", name: name2 };
37300
37297
  }
@@ -37323,9 +37320,6 @@ var require_duetExecutorGate = __commonJS({
37323
37320
  if (entry === null) {
37324
37321
  return { state: "unavailable", reason: "not_resolved", problem: "the executor's endpoint is not configured", name: name2 };
37325
37322
  }
37326
- if (!(0, customProviders_js_1.isLoopbackEndpoint)(entry.baseUrl)) {
37327
- return { state: "unavailable", reason: "not_loopback", problem: "the executor is not on this machine", name: name2 };
37328
- }
37329
37323
  const apiKey = await (0, customProviders_js_1.resolveApiKey)(entry);
37330
37324
  if (!await (0, customProviders_js_1.endpointIsReachable)(entry.baseUrl, apiKey, opts.fetchImpl)) {
37331
37325
  return { state: "unavailable", reason: "unreachable", problem: "the executor is not answering", name: name2 };
@@ -37629,10 +37623,10 @@ var require_duetExecutorGate = __commonJS({
37629
37623
  const ttl = opts.statusTtlMs ?? exports2.EXECUTOR_GATE_STATUS_TTL_MS;
37630
37624
  let cached = null;
37631
37625
  let noted = false;
37632
- const downgrade = (why) => {
37633
- const note = noted ? null : (0, duetExecutorGateStatus_js_1.executorGateDowngradeNote)(why);
37626
+ const fallback = (why) => {
37627
+ const note = noted ? null : (0, duetExecutorGateStatus_js_1.executorGateFallbackNote)(why);
37634
37628
  noted = true;
37635
- return { ...(0, duetEntry_js_1.effectiveDuetEntry)("executor", void 0, "unavailable"), verdict: null, note };
37629
+ return { entry: "executor", verdict: null, note };
37636
37630
  };
37637
37631
  return {
37638
37632
  async status(o = {}) {
@@ -37656,20 +37650,20 @@ var require_duetExecutorGate = __commonJS({
37656
37650
  const resolved = resolveExecutorGateTarget(ctx.workspaceRoot, opts.resolveDeps);
37657
37651
  if (resolved.state !== "ready") {
37658
37652
  opts.onError?.("resolve", resolved.state === "platform" ? "platform executor" : resolved.problem);
37659
- return downgrade(resolved);
37653
+ return fallback(resolved);
37660
37654
  }
37661
37655
  const { target } = resolved;
37662
37656
  const prompt = renderExecutorGatePrompt(executorGateStateFrom(ctx.record, text));
37663
37657
  const asked = await askExecutorGate(target, prompt, { fetchImpl: opts.fetchImpl, timeoutMs: opts.timeoutMs });
37664
37658
  if (!asked.ok) {
37665
37659
  opts.onError?.("ask", asked.problem);
37666
- return downgrade({ state: "unavailable", reason: asked.reason, problem: asked.problem });
37660
+ return fallback({ state: "unavailable", reason: asked.reason, problem: asked.problem });
37667
37661
  }
37668
37662
  const decision = decideExecutorGate(asked.answer, target.threshold);
37669
37663
  if (decision === null) {
37670
37664
  const said = asked.answer.raw.trim();
37671
37665
  opts.onError?.("ask", `undecidable answer "${said}"`);
37672
- return downgrade({ state: "unavailable", reason: "unparseable", problem: `the executor answered "${said}"` });
37666
+ return fallback({ state: "unavailable", reason: "unparseable", problem: `the executor answered "${said}"` });
37673
37667
  }
37674
37668
  noted = false;
37675
37669
  const verdict = {
@@ -39005,6 +38999,58 @@ var require_agentStore = __commonJS({
39005
38999
  }
39006
39000
  });
39007
39001
 
39002
+ // ../packages/orion-client-core/dist/goalClaim.js
39003
+ var require_goalClaim = __commonJS({
39004
+ "../packages/orion-client-core/dist/goalClaim.js"(exports2) {
39005
+ "use strict";
39006
+ Object.defineProperty(exports2, "__esModule", { value: true });
39007
+ exports2.GOAL_REPORT_TOOL = exports2.GOAL_CAPABILITY = void 0;
39008
+ exports2.readGoalReportInput = readGoalReportInput;
39009
+ exports2.goalClaimFromWire = goalClaimFromWire3;
39010
+ exports2.goalReportToolResult = goalReportToolResult3;
39011
+ exports2.GOAL_CAPABILITY = "goal";
39012
+ exports2.GOAL_REPORT_TOOL = "goal_report";
39013
+ function readGoalReportInput(input) {
39014
+ if (!input || typeof input !== "object")
39015
+ return null;
39016
+ const r2 = input;
39017
+ if (typeof r2.done !== "boolean")
39018
+ return null;
39019
+ const note = r2.done ? r2.verified : r2.outstanding;
39020
+ return { done: r2.done, note: typeof note === "string" ? note.trim() : "" };
39021
+ }
39022
+ function goalClaimFromWire3(messages) {
39023
+ if (!Array.isArray(messages))
39024
+ return null;
39025
+ let claim = null;
39026
+ for (const message of messages) {
39027
+ const m2 = message;
39028
+ if (!m2 || m2.role !== "assistant" || !Array.isArray(m2.content))
39029
+ continue;
39030
+ for (const block of m2.content) {
39031
+ const b2 = block;
39032
+ if (!b2 || b2.type !== "tool_use" || b2.name !== exports2.GOAL_REPORT_TOOL)
39033
+ continue;
39034
+ const parsed = readGoalReportInput(b2.input);
39035
+ if (parsed !== null)
39036
+ claim = parsed;
39037
+ }
39038
+ }
39039
+ return claim;
39040
+ }
39041
+ function goalReportToolResult3(params) {
39042
+ const claim = readGoalReportInput(params);
39043
+ if (claim === null) {
39044
+ return "goal_report needs `done` as a boolean: false while ANY part of the goal remains (say what in `outstanding`), true only when every part is verified complete (name what you ran in `verified`).";
39045
+ }
39046
+ if (claim.done) {
39047
+ return "Completion claim recorded. An independent check now reviews the evidence of what you actually did \u2014 the goal ends only if it confirms; otherwise you will be told what is still outstanding. End your turn now.";
39048
+ }
39049
+ return "Status recorded \u2014 the goal continues. If you can take the next step now, keep working; otherwise end your turn and you will be continued.";
39050
+ }
39051
+ }
39052
+ });
39053
+
39008
39054
  // ../packages/orion-client-core/dist/goalMarker.js
39009
39055
  var require_goalMarker = __commonJS({
39010
39056
  "../packages/orion-client-core/dist/goalMarker.js"(exports2) {
@@ -39426,7 +39472,8 @@ var require_goalEvaluate = __commonJS({
39426
39472
  const params = { goal: args2.goal, evidence };
39427
39473
  if (args2.sessionId)
39428
39474
  params.session_id = args2.sessionId;
39429
- const chosen = await configuredEvaluatorModel(args2);
39475
+ const sessionFallback = args2.sessionModel && !args2.sessionProvider?.startsWith("custom") ? { model: args2.sessionModel, provider: args2.sessionProvider ?? "" } : void 0;
39476
+ const chosen = await configuredEvaluatorModel(args2) ?? sessionFallback;
39430
39477
  if (chosen) {
39431
39478
  params.model = chosen.model;
39432
39479
  if (chosen.provider)
@@ -39443,15 +39490,18 @@ var require_goalRunner = __commonJS({
39443
39490
  "../packages/orion-client-core/dist/goalRunner.js"(exports2) {
39444
39491
  "use strict";
39445
39492
  Object.defineProperty(exports2, "__esModule", { value: true });
39446
- exports2.GoalRunner = exports2.GOAL_CONTINUE_DISPLAY = exports2.GOAL_REASON_PROMPT_MAX_CHARS = exports2.GOAL_REASON_MAX_CHARS = exports2.GOAL_MAX_EVALUATOR_FAILURES = exports2.DEFAULT_GOAL_MAX_WALL_MS = exports2.DEFAULT_GOAL_MAX_TURNS = exports2.GOAL_INSTRUCTION = void 0;
39493
+ exports2.GoalRunner = exports2.GOAL_CONTINUE_DISPLAY = exports2.GOAL_REASON_PROMPT_MAX_CHARS = exports2.GOAL_REASON_MAX_CHARS = exports2.GOAL_UNCLAIMED_CHECK_INTERVAL = exports2.GOAL_MAX_EVALUATOR_FAILURES = exports2.DEFAULT_GOAL_MAX_WALL_MS = exports2.DEFAULT_GOAL_MAX_TURNS = exports2.GOAL_INSTRUCTION = void 0;
39447
39494
  exports2.buildGoalPrompt = buildGoalPrompt;
39448
39495
  exports2.buildContinuationPrompt = buildContinuationPrompt;
39449
39496
  exports2.finalAssistantTextFromWire = finalAssistantTextFromWire2;
39450
39497
  exports2.describeGoalEnd = describeGoalEnd;
39451
- exports2.goalReasonLine = goalReasonLine2;
39498
+ exports2.goalReasonLine = goalReasonLine3;
39452
39499
  exports2.goalEndRow = goalEndRow2;
39453
39500
  exports2.goalNotMetRow = goalNotMetRow2;
39454
39501
  exports2.goalStartDisplay = goalStartDisplay2;
39502
+ exports2.goalFromStartDisplay = goalFromStartDisplay;
39503
+ exports2.goalSetRow = goalSetRow2;
39504
+ exports2.goalRoundReason = goalRoundReason2;
39455
39505
  exports2.GOAL_INSTRUCTION = [
39456
39506
  "",
39457
39507
  "---",
@@ -39460,11 +39510,14 @@ var require_goalRunner = __commonJS({
39460
39510
  "Do not end your turn with a plan, an intention, or a promise about work you have not done \u2014",
39461
39511
  "if the next step is clear, take it now instead of describing it.",
39462
39512
  "",
39463
- "You do NOT decide when the goal is finished: an independent check reviews each turn against",
39464
- "the goal and continues you if anything is outstanding. Reading code is not verifying it \u2014",
39465
- "run the tests, execute the command, show the output. State plainly what you did and what the",
39466
- "result actually was; an unverified claim counts for nothing, and reporting a failure honestly",
39467
- "is always better than glossing it."
39513
+ "End every turn by calling the goal_report tool \u2014 a status line in prose is not a report.",
39514
+ "While ANY part of the goal remains, report done: false and say in `outstanding` exactly what",
39515
+ 'is missing. Be ruthlessly honest \u2014 an honest "not done" costs nothing and keeps you going.',
39516
+ "Report done: true only when you have VERIFIED every part \u2014 ran the tests, executed the",
39517
+ "command, saw the output \u2014 and name in `verified` what you ran and what it showed.",
39518
+ "Your report is a claim, not a verdict: an independent check reviews the evidence of what you",
39519
+ "actually did before the goal can end, and an unverified claim is simply sent back. Reading",
39520
+ "code is not verifying it; reporting a failure honestly is always better than glossing it."
39468
39521
  ].join("\n");
39469
39522
  function buildGoalPrompt(goal) {
39470
39523
  return `# Goal
@@ -39472,7 +39525,7 @@ ${goal}
39472
39525
  ${exports2.GOAL_INSTRUCTION}`;
39473
39526
  }
39474
39527
  function buildContinuationPrompt(goal, reason) {
39475
- const line = reason ? goalReasonLine2(reason, exports2.GOAL_REASON_PROMPT_MAX_CHARS) : "";
39528
+ const line = reason ? goalReasonLine3(reason, exports2.GOAL_REASON_PROMPT_MAX_CHARS) : "";
39476
39529
  const outstanding = line === "" ? "" : `
39477
39530
 
39478
39531
  ## What the completion check reported
@@ -39505,6 +39558,7 @@ ${exports2.GOAL_INSTRUCTION}`;
39505
39558
  exports2.DEFAULT_GOAL_MAX_TURNS = 0;
39506
39559
  exports2.DEFAULT_GOAL_MAX_WALL_MS = 0;
39507
39560
  exports2.GOAL_MAX_EVALUATOR_FAILURES = 3;
39561
+ exports2.GOAL_UNCLAIMED_CHECK_INTERVAL = 5;
39508
39562
  function describeGoalEnd(reason) {
39509
39563
  switch (reason) {
39510
39564
  case "done":
@@ -39525,7 +39579,7 @@ ${exports2.GOAL_INSTRUCTION}`;
39525
39579
  }
39526
39580
  exports2.GOAL_REASON_MAX_CHARS = 140;
39527
39581
  exports2.GOAL_REASON_PROMPT_MAX_CHARS = 500;
39528
- function goalReasonLine2(reason, max = exports2.GOAL_REASON_MAX_CHARS) {
39582
+ function goalReasonLine3(reason, max = exports2.GOAL_REASON_MAX_CHARS) {
39529
39583
  const flat = reason.replace(/\s+/g, " ").trim();
39530
39584
  if (flat.length <= max)
39531
39585
  return flat;
@@ -39552,7 +39606,7 @@ ${exports2.GOAL_INSTRUCTION}`;
39552
39606
  }
39553
39607
  }
39554
39608
  function goalNotMetRow2(reason) {
39555
- const line = goalReasonLine2(reason);
39609
+ const line = goalReasonLine3(reason);
39556
39610
  return {
39557
39611
  glyph: "\u25CE",
39558
39612
  text: line === "" ? "Not met yet" : `Not met yet \u2014 ${line}`,
@@ -39564,10 +39618,29 @@ ${exports2.GOAL_INSTRUCTION}`;
39564
39618
  function goalStartDisplay2(goal) {
39565
39619
  return `/goal ${goal}`;
39566
39620
  }
39621
+ function goalFromStartDisplay(display) {
39622
+ return (display.startsWith("/goal ") ? display.slice("/goal ".length) : display).trim();
39623
+ }
39624
+ function goalSetRow2(goal) {
39625
+ const line = goal.replace(/\s+/g, " ").trim();
39626
+ return {
39627
+ glyph: "\u25CE",
39628
+ text: line === "" ? "Goal set" : `Goal set: ${line}`,
39629
+ done: false,
39630
+ progress: true
39631
+ };
39632
+ }
39633
+ function goalRoundReason2(round) {
39634
+ if (round.ruling)
39635
+ return round.ruling.evaluated ? round.ruling.reason : "";
39636
+ if (round.claim && !round.claim.done)
39637
+ return round.claim.note;
39638
+ return "";
39639
+ }
39567
39640
  function readOutcome(outcome) {
39568
39641
  if (typeof outcome === "string")
39569
- return { text: outcome, evidence: outcome };
39570
- return { text: outcome.text ?? "", evidence: outcome.evidence ?? "" };
39642
+ return { text: outcome, evidence: outcome, claim: null };
39643
+ return { text: outcome.text ?? "", evidence: outcome.evidence ?? "", claim: outcome.claim ?? null };
39571
39644
  }
39572
39645
  var GoalRunner3 = class {
39573
39646
  deps;
@@ -39580,10 +39653,17 @@ ${exports2.GOAL_INSTRUCTION}`;
39580
39653
  /** Wall-clock anchor for the envelope, from the injected clock. */
39581
39654
  startedAt = 0;
39582
39655
  /** Consecutive evaluator calls that produced no verdict. Any real ruling —
39583
- * including "not yet" — resets it. */
39656
+ * including "not yet" — resets it. Untouched on rounds that run no check:
39657
+ * they say nothing about the evaluator either way. */
39584
39658
  evaluatorFailures = 0;
39585
39659
  /** The evaluator's last account of what is outstanding. */
39586
39660
  lastReason = "";
39661
+ /** Consecutive rounds settled without a check. At
39662
+ * [`GOAL_UNCLAIMED_CHECK_INTERVAL`] the backstop runs one; reset on every
39663
+ * check run, claimed or backstop. */
39664
+ uncheckedRounds = 0;
39665
+ /** The agent's own last `goal_report`. */
39666
+ lastClaim = null;
39587
39667
  constructor(deps2) {
39588
39668
  this.deps = deps2;
39589
39669
  }
@@ -39593,7 +39673,8 @@ ${exports2.GOAL_INSTRUCTION}`;
39593
39673
  goal: this.goal,
39594
39674
  endReason: this.endReason,
39595
39675
  turns: this.turns,
39596
- lastReason: this.lastReason === "" ? null : this.lastReason
39676
+ lastReason: this.lastReason === "" ? null : this.lastReason,
39677
+ lastClaim: this.lastClaim
39597
39678
  };
39598
39679
  }
39599
39680
  /** The user's stop (Esc, `/goal stop`, banner button). The in-flight turn is
@@ -39613,6 +39694,8 @@ ${exports2.GOAL_INSTRUCTION}`;
39613
39694
  this.turns = 0;
39614
39695
  this.evaluatorFailures = 0;
39615
39696
  this.lastReason = "";
39697
+ this.uncheckedRounds = 0;
39698
+ this.lastClaim = null;
39616
39699
  this.emit();
39617
39700
  this.startedAt = (this.deps.now ?? Date.now)();
39618
39701
  let prompt = buildGoalPrompt(goal);
@@ -39626,30 +39709,40 @@ ${exports2.GOAL_INSTRUCTION}`;
39626
39709
  this.turns += 1;
39627
39710
  if (this.stopRequested)
39628
39711
  return this.finish("stopped");
39629
- const { text, evidence } = readOutcome(outcome);
39630
- const ruling = await this.rule(goal, evidence, text);
39712
+ const { text, evidence, claim } = readOutcome(outcome);
39713
+ this.lastClaim = claim;
39714
+ this.uncheckedRounds += 1;
39715
+ const check2 = claim?.done === true ? "claimed" : this.uncheckedRounds >= exports2.GOAL_UNCLAIMED_CHECK_INTERVAL || this.envelopeVerdict(this.turns) !== null ? "backstop" : "none";
39716
+ let ruling = null;
39717
+ if (check2 !== "none") {
39718
+ this.uncheckedRounds = 0;
39719
+ ruling = await this.rule(goal, evidence, text);
39720
+ }
39631
39721
  if (this.stopRequested)
39632
39722
  return this.finish("stopped");
39633
- if (ruling.evaluated && ruling.ok) {
39634
- this.lastReason = ruling.reason;
39635
- return this.finish("done");
39636
- }
39637
- if (ruling.evaluated && !ruling.achievable) {
39638
- this.lastReason = ruling.reason;
39639
- return this.finish("not_achievable");
39640
- }
39641
- if (ruling.evaluated) {
39642
- this.evaluatorFailures = 0;
39643
- } else if ((this.evaluatorFailures += 1) >= exports2.GOAL_MAX_EVALUATOR_FAILURES) {
39644
- this.lastReason = ruling.reason;
39645
- return this.finish("evaluator_failed");
39723
+ if (ruling) {
39724
+ if (ruling.evaluated && ruling.ok) {
39725
+ this.lastReason = ruling.reason;
39726
+ return this.finish("done");
39727
+ }
39728
+ if (ruling.evaluated && !ruling.achievable) {
39729
+ this.lastReason = ruling.reason;
39730
+ return this.finish("not_achievable");
39731
+ }
39732
+ if (ruling.evaluated) {
39733
+ this.evaluatorFailures = 0;
39734
+ this.lastReason = ruling.reason;
39735
+ } else if ((this.evaluatorFailures += 1) >= exports2.GOAL_MAX_EVALUATOR_FAILURES) {
39736
+ this.lastReason = ruling.reason;
39737
+ return this.finish("evaluator_failed");
39738
+ }
39646
39739
  }
39647
39740
  const ceiling = this.envelopeVerdict(this.turns);
39648
39741
  if (ceiling !== null)
39649
39742
  return this.finish(ceiling);
39650
- this.lastReason = ruling.reason;
39743
+ this.deps.onRound?.({ turns: this.turns, check: check2, ruling, claim });
39651
39744
  this.emit();
39652
- prompt = buildContinuationPrompt(goal, ruling.evaluated ? ruling.reason : void 0);
39745
+ prompt = buildContinuationPrompt(goal, ruling?.evaluated ? ruling.reason : void 0);
39653
39746
  }
39654
39747
  }
39655
39748
  /** One completion ruling, with the evaluator's own failures absorbed. A judge
@@ -41516,7 +41609,7 @@ var require_agentAuth = __commonJS({
41516
41609
  "../packages/orion-client-core/dist/auth/agentAuth.js"(exports2) {
41517
41610
  "use strict";
41518
41611
  Object.defineProperty(exports2, "__esModule", { value: true });
41519
- exports2.USAGE_TOPUP_COVERING_LABEL = exports2.NO_USAGE_LIMIT_LABEL = exports2.AgentSession = exports2.TOKEN_REQUEST_TIMEOUT_MS = exports2.AgentAuthError = void 0;
41612
+ exports2.USAGE_TOPUP_COVERING_LABEL = exports2.NO_USAGE_LIMIT_LABEL = exports2.AgentSession = exports2.BRAIN_RENEW_DEADLINE_MS = exports2.RENEW_BUDGET_MS = exports2.SECRET_READ_TIMEOUT_MS = exports2.TOKEN_REQUEST_TIMEOUT_MS = exports2.AgentAuthError = void 0;
41520
41613
  exports2.isAgentSessionKey = isAgentSessionKey;
41521
41614
  exports2.pkcePair = pkcePair;
41522
41615
  exports2.buildConnectUrl = buildConnectUrl;
@@ -41597,6 +41690,16 @@ var require_agentAuth = __commonJS({
41597
41690
  const value = jwtClaim(token, claim);
41598
41691
  return typeof value === "string" && value ? value : null;
41599
41692
  }
41693
+ function remainingValidityMs(token) {
41694
+ const exp = jwtClaim(token, "exp");
41695
+ return typeof exp === "number" && Number.isFinite(exp) ? exp * 1e3 - Date.now() : 0;
41696
+ }
41697
+ function sleep(ms) {
41698
+ return new Promise((resolve5) => {
41699
+ const timer = setTimeout(resolve5, ms);
41700
+ timer.unref?.();
41701
+ });
41702
+ }
41600
41703
  async function pkcePair() {
41601
41704
  const raw = new Uint8Array(48);
41602
41705
  globalThis.crypto.getRandomValues(raw);
@@ -41684,16 +41787,54 @@ var require_agentAuth = __commonJS({
41684
41787
  }
41685
41788
  var FRESH_TOKEN_BUFFER_MS = 6e4;
41686
41789
  var EARLY_REFRESH_MS = 10 * 6e4;
41790
+ exports2.SECRET_READ_TIMEOUT_MS = 5e3;
41791
+ exports2.RENEW_BUDGET_MS = 55e3;
41792
+ exports2.BRAIN_RENEW_DEADLINE_MS = 9e4;
41793
+ var RENEWED_TOKEN_MIN_REMAINING_MS = 5 * 6e4;
41794
+ var READ_TIMED_OUT = Symbol("orion.secret-read-timed-out");
41687
41795
  var AgentSession = class {
41688
41796
  store;
41689
41797
  apiBaseUrl;
41690
41798
  options;
41691
41799
  inflightRefresh = null;
41800
+ /** The last token set THIS process saved — a write-through mirror of {@link save}, never
41801
+ * of sibling processes' writes (those live only in the shared store). Lets a renewal
41802
+ * answer with our own recent mint when the store read itself is wedged. NEVER used to
41803
+ * START a refresh: a cached refresh token may be rotated-away by a sibling, and replaying
41804
+ * one late revokes the whole token family server-side. */
41805
+ lastSaved = null;
41692
41806
  constructor(store, apiBaseUrl, options = {}) {
41693
41807
  this.store = store;
41694
41808
  this.apiBaseUrl = apiBaseUrl;
41695
41809
  this.options = options;
41696
41810
  }
41811
+ /** Breadcrumb line (see {@link AgentSessionOptions.trace}); a throwing sink is the host's
41812
+ * bug and must never break the auth path. */
41813
+ trace(line) {
41814
+ try {
41815
+ this.options.trace?.(line);
41816
+ } catch {
41817
+ }
41818
+ }
41819
+ /** One bounded store read. {@link READ_TIMED_OUT} = the store did not answer (timed out
41820
+ * or threw) — an UNREACHABLE store, distinct from `null` = the key is definitively
41821
+ * absent. The renewal path branches on that difference: absent means signed out (fail
41822
+ * closed now); unreachable means retry and degrade, never a declared sign-out. */
41823
+ async boundedRead(key) {
41824
+ const timeoutMs = this.options.secretReadTimeoutMs ?? exports2.SECRET_READ_TIMEOUT_MS;
41825
+ let timer;
41826
+ const timeout = new Promise((resolve5) => {
41827
+ timer = setTimeout(() => resolve5(READ_TIMED_OUT), timeoutMs);
41828
+ timer.unref?.();
41829
+ });
41830
+ try {
41831
+ const read = Promise.resolve(this.store.get(key)).then((value) => value || null, () => READ_TIMED_OUT);
41832
+ return await Promise.race([read, timeout]);
41833
+ } finally {
41834
+ if (timer !== void 0)
41835
+ clearTimeout(timer);
41836
+ }
41837
+ }
41697
41838
  async currentAccessToken() {
41698
41839
  return await this.store.get(ACCESS_KEY) || null;
41699
41840
  }
@@ -41713,9 +41854,7 @@ var require_agentAuth = __commonJS({
41713
41854
  const token = await this.currentAccessToken();
41714
41855
  if (!token)
41715
41856
  return null;
41716
- const exp = jwtClaim(token, "exp");
41717
- const expiresAtMs = typeof exp === "number" && Number.isFinite(exp) ? exp * 1e3 : 0;
41718
- const remainingMs = expiresAtMs - Date.now();
41857
+ const remainingMs = remainingValidityMs(token);
41719
41858
  if (remainingMs > EARLY_REFRESH_MS)
41720
41859
  return token;
41721
41860
  if (remainingMs > FRESH_TOKEN_BUFFER_MS) {
@@ -41725,6 +41864,64 @@ var require_agentAuth = __commonJS({
41725
41864
  await this.refresh();
41726
41865
  return this.currentAccessToken();
41727
41866
  }
41867
+ /** The FAIL-CLOSED renewal answer for the local brain's `renew_bearer` request — invoked
41868
+ * only after the gateway REFUSED a bearer (401), which makes the server's verdict the
41869
+ * ground truth this method never argues with. Its contract:
41870
+ * - it never answers with `refused` (the token just declared dead) nor with a near-dead
41871
+ * token — a mint is forced instead;
41872
+ * - a DIFFERENT stored token with comfortable validity (a sibling process already
41873
+ * renewed through the shared store) is the answer immediately, no mint;
41874
+ * - otherwise it mints, retrying transient failures with backoff under `renewBudgetMs`,
41875
+ * re-reading the store between tries — a sibling's mint landing while ours failed
41876
+ * (the rotation race's other half, reply-lost rotations included) is a heal;
41877
+ * - a wedged store degrades to this process's own last save for the ACCESS token
41878
+ * (never for starting a refresh — rotation safety, see {@link refresh});
41879
+ * - `null` means the account genuinely cannot produce a fresh token (signed out,
41880
+ * family revoked, or the budget lapsed with everything unreachable) — the brain then
41881
+ * surfaces the honest auth error.
41882
+ *
41883
+ * {@link currentFreshAccessToken} stays the PROACTIVE read with its deliberate fail-OPEN
41884
+ * degradation ("the stored token stands"); this is the REACTIVE one, and the two must
41885
+ * not be merged: the fail-open answer is exactly what let the 2026-08-24/25 stage turns
41886
+ * die — it handed the refused token straight back, and the one heal was spent. */
41887
+ async renewedAccessToken(refused) {
41888
+ const budget = this.options.renewBudgetMs ?? exports2.RENEW_BUDGET_MS;
41889
+ const backoffBase = this.options.renewBackoffBaseMs ?? 500;
41890
+ const deadline = Date.now() + budget;
41891
+ const answerable = (token2, minted) => typeof token2 === "string" && token2 !== "" && token2 !== refused && // A mint vouches for freshness by EVENT (it just happened server-side), sidestepping
41892
+ // the local clock entirely — a fast client clock must not veto a genuinely new token.
41893
+ (minted || remainingValidityMs(token2) > RENEWED_TOKEN_MIN_REMAINING_MS);
41894
+ const storedAccess = async () => {
41895
+ const read = await this.boundedRead(ACCESS_KEY);
41896
+ if (read !== READ_TIMED_OUT)
41897
+ return { token: read, wedged: false };
41898
+ return { token: this.lastSaved?.accessToken ?? null, wedged: true };
41899
+ };
41900
+ let { token, wedged } = await storedAccess();
41901
+ if (answerable(token, false)) {
41902
+ this.trace(wedged ? "renew: answered from the process cache (store unreachable), no mint" : "renew: answered from the store (sibling renewal), no mint");
41903
+ return token;
41904
+ }
41905
+ for (let attempt = 0; ; attempt += 1) {
41906
+ const minted = await this.refresh();
41907
+ ({ token, wedged } = await storedAccess());
41908
+ if (answerable(token, minted)) {
41909
+ this.trace(minted ? `renew: minted and answered (attempt ${attempt + 1})` : "renew: a sibling's mint landed \u2014 answered");
41910
+ return token;
41911
+ }
41912
+ const refreshToken = await this.boundedRead(REFRESH_KEY);
41913
+ if (refreshToken === null) {
41914
+ this.trace("renew: no session (signed out / revoked) \u2014 fail-closed");
41915
+ return null;
41916
+ }
41917
+ const wait = Math.min(Math.min(8e3, backoffBase * 2 ** attempt), deadline - Date.now());
41918
+ if (wait <= 0)
41919
+ break;
41920
+ await sleep(wait);
41921
+ }
41922
+ this.trace(`renew: budget (${budget}ms) exhausted \u2014 fail-closed`);
41923
+ return null;
41924
+ }
41728
41925
  /** The plan the user is on (free/pro/…), for display + upgrade CTAs. */
41729
41926
  async tier() {
41730
41927
  return await this.store.get(TIER_KEY) || null;
@@ -41861,6 +42058,7 @@ var require_agentAuth = __commonJS({
41861
42058
  return Boolean(await this.store.get(REFRESH_KEY));
41862
42059
  }
41863
42060
  async save(tokens) {
42061
+ this.lastSaved = tokens;
41864
42062
  await this.store.store(ACCESS_KEY, tokens.accessToken);
41865
42063
  await this.store.store(REFRESH_KEY, tokens.refreshToken);
41866
42064
  await this.store.store(TIER_KEY, tokens.tier);
@@ -41881,20 +42079,47 @@ var require_agentAuth = __commonJS({
41881
42079
  return inflight;
41882
42080
  }
41883
42081
  async doRefresh() {
41884
- const refreshToken = await this.store.get(REFRESH_KEY);
42082
+ const started = Date.now();
42083
+ const refreshToken = await this.boundedRead(REFRESH_KEY);
42084
+ if (refreshToken === READ_TIMED_OUT) {
42085
+ this.trace(`refresh: store read unanswered after ${Date.now() - started}ms \u2014 transient`);
42086
+ return false;
42087
+ }
41885
42088
  if (!refreshToken)
41886
42089
  return false;
41887
42090
  try {
41888
- await this.save(await refreshTokens({
42091
+ const minted = await refreshTokens({
41889
42092
  apiBaseUrl: this.apiBaseUrl(),
41890
42093
  refreshToken,
41891
42094
  requestTimeoutMs: this.options.requestTimeoutMs
41892
- }));
42095
+ });
42096
+ if (!minted.accessToken) {
42097
+ this.trace("refresh: malformed 200 (empty access token) \u2014 transient");
42098
+ return false;
42099
+ }
42100
+ const tokens = minted.refreshToken ? minted : { ...minted, refreshToken };
42101
+ const written = await Promise.race([
42102
+ this.save(tokens).then(() => true, () => false),
42103
+ sleep(3 * (this.options.secretReadTimeoutMs ?? exports2.SECRET_READ_TIMEOUT_MS)).then(() => false)
42104
+ ]);
42105
+ this.trace(written ? `refresh: minted in ${Date.now() - started}ms` : `refresh: minted in ${Date.now() - started}ms, store write still pending \u2014 tokens live in the process cache`);
41893
42106
  return true;
41894
42107
  } catch (err2) {
41895
42108
  if (err2 instanceof AgentAuthError && isDefinitiveAuthRejection(err2)) {
42109
+ const current2 = await this.boundedRead(REFRESH_KEY);
42110
+ if (current2 === READ_TIMED_OUT) {
42111
+ this.trace("refresh: rejected, but the store is unreachable \u2014 clear deferred");
42112
+ return false;
42113
+ }
42114
+ if (current2 && current2 !== refreshToken) {
42115
+ this.trace("refresh: rejection was a rotation-race replay \u2014 sibling's session adopted");
42116
+ return true;
42117
+ }
42118
+ this.trace("refresh: definitively rejected \u2014 session cleared");
41896
42119
  await this.clear();
42120
+ return false;
41897
42121
  }
42122
+ this.trace(`refresh: transient failure (${err2 instanceof AgentAuthError ? err2.status : "malformed reply"})`);
41898
42123
  return false;
41899
42124
  }
41900
42125
  }
@@ -41906,6 +42131,7 @@ var require_agentAuth = __commonJS({
41906
42131
  await this.clear();
41907
42132
  }
41908
42133
  async clear() {
42134
+ this.lastSaved = null;
41909
42135
  await this.store.delete(ACCESS_KEY);
41910
42136
  await this.store.delete(REFRESH_KEY);
41911
42137
  await this.store.delete(TIER_KEY);
@@ -42189,8 +42415,8 @@ var require_browserLogin = __commonJS({
42189
42415
  } catch {
42190
42416
  }
42191
42417
  }
42192
- function createAgentSession3(secrets, config) {
42193
- return new agentAuth_1.AgentSession(secrets, () => config.accountsApiUrl);
42418
+ function createAgentSession3(secrets, config, options = {}) {
42419
+ return new agentAuth_1.AgentSession(secrets, () => config.accountsApiUrl, options);
42194
42420
  }
42195
42421
  async function signInViaBrowser3(session, config, deps2 = {}) {
42196
42422
  if (await session.isSignedIn())
@@ -70548,7 +70774,7 @@ var require_connection = __commonJS({
70548
70774
  return;
70549
70775
  }
70550
70776
  case "renew_bearer": {
70551
- void this.answerRenew(frame.id);
70777
+ void this.answerRenew(frame.id, frame.refused);
70552
70778
  return;
70553
70779
  }
70554
70780
  case "rpc_result": {
@@ -70566,15 +70792,19 @@ var require_connection = __commonJS({
70566
70792
  return;
70567
70793
  }
70568
70794
  }
70569
- /** Run (or join) the ONE in-flight refresh and answer the renew request with its result.
70570
- * A throwing or absent auth layer answers "no bearer" — a failed renewal at the brain,
70571
- * never a connection fault. */
70572
- async answerRenew(id) {
70795
+ /** Run (or join) the ONE in-flight renewal and answer the renew request with its result.
70796
+ * Joiners share the in-flight answer even when their `refused` differs (a turn's main
70797
+ * call and its interim passes usually 401 on the SAME bearer; when they don't, a shared
70798
+ * answer the gateway still refuses just triggers that call's second renew round, which
70799
+ * runs fresh with ITS refused token — self-correcting, never a loop). A throwing or
70800
+ * absent auth layer answers "no bearer" — a failed renewal at the brain, never a
70801
+ * connection fault. */
70802
+ async answerRenew(id, refused) {
70573
70803
  let bearer = null;
70574
70804
  if (this.renewBearer) {
70575
70805
  this.renewInFlight ??= (async () => {
70576
70806
  try {
70577
- return await this.renewBearer();
70807
+ return await this.renewBearer(refused);
70578
70808
  } catch {
70579
70809
  return null;
70580
70810
  } finally {
@@ -71400,6 +71630,7 @@ var require_dist = __commonJS({
71400
71630
  __exportStar(require_duetRoutingAdvisor(), exports2);
71401
71631
  __exportStar(require_cron(), exports2);
71402
71632
  __exportStar(require_agentStore(), exports2);
71633
+ __exportStar(require_goalClaim(), exports2);
71403
71634
  __exportStar(require_goalMarker(), exports2);
71404
71635
  __exportStar(require_goalEvidence(), exports2);
71405
71636
  __exportStar(require_goalEvaluate(), exports2);
@@ -72384,7 +72615,8 @@ var require_toolVisibility = __commonJS({
72384
72615
  exports2.SILENT_TOOLS = /* @__PURE__ */ new Set([
72385
72616
  "ask_user",
72386
72617
  "exit_plan_mode",
72387
- "await_agents"
72618
+ "await_agents",
72619
+ "goal_report"
72388
72620
  ]);
72389
72621
  function isSilentTool3(name2) {
72390
72622
  return typeof name2 === "string" && exports2.SILENT_TOOLS.has(name2);
@@ -88422,8 +88654,19 @@ var darkTheme = {
88422
88654
  contextCometFragment: "#7c5cbf",
88423
88655
  contextCometDust: "#4a3d66",
88424
88656
  border: "#808080",
88425
- diffAdd: "#38a660",
88426
- diffRemove: "#b3596b",
88657
+ // Diff layers (see the Theme interface): near-black bands a step apart, loud
88658
+ // color reserved for the +/- decorations, bright off-white plain text. The
88659
+ // hues are Orion's own family — EMERALD for additions (cooler than a leaf
88660
+ // green; the decoration green IS the app's semantic green, autoAccept, so
88661
+ // the diff and the posture/success chrome speak one color) and ROSE for
88662
+ // removals (sits naturally beside the violet brand).
88663
+ diffAdd: "#3fb950",
88664
+ diffRemove: "#e5484d",
88665
+ diffAddBg: "#022711",
88666
+ diffRemoveBg: "#330210",
88667
+ diffAddWordBg: "#044921",
88668
+ diffRemoveWordBg: "#4d0416",
88669
+ diffText: "#f8f8f2",
88427
88670
  diffContext: "#808080",
88428
88671
  gutter: "#808080",
88429
88672
  synKeyword: "#569cd6",
@@ -88433,11 +88676,6 @@ var darkTheme = {
88433
88676
  synType: "#4ec9b0",
88434
88677
  synComment: "#6a9955",
88435
88678
  synControl: "#c586c0",
88436
- // Per-line diff BASE bands (muted). The brighter diffAdd/diffRemove ride on top
88437
- // as word-level change highlights, so a small edit shows a two-tone line instead
88438
- // of one flat wash.
88439
- diffAddBg: "#225c2b",
88440
- diffRemoveBg: "#7a2936",
88441
88679
  autoAccept: "#3fb950",
88442
88680
  planMode: "#38bdf8",
88443
88681
  duetMode: "#a78bfa",
@@ -88478,8 +88716,17 @@ var lightTheme = {
88478
88716
  contextCometFragment: "#8b6fd4",
88479
88717
  contextCometDust: "#b9a9dd",
88480
88718
  border: "#808080",
88481
- diffAdd: "#2f9d44",
88482
- diffRemove: "#d1454b",
88719
+ // Diff layers (see the Theme interface), mirrored for a light terminal: the
88720
+ // bands are the palest wash, the word step is deeper, decorations deeper
88721
+ // still. Same Orion family as dark — emerald additions (decoration green =
88722
+ // autoAccept, the app's semantic green) and rose removals.
88723
+ diffAdd: "#15803d",
88724
+ diffRemove: "#cf2240",
88725
+ diffAddBg: "#d9fbe8",
88726
+ diffRemoveBg: "#ffdce4",
88727
+ diffAddWordBg: "#aff5cd",
88728
+ diffRemoveWordBg: "#ffc2cf",
88729
+ diffText: "#333333",
88483
88730
  diffContext: "#808080",
88484
88731
  gutter: "#808080",
88485
88732
  synKeyword: "#0000ff",
@@ -88489,8 +88736,6 @@ var lightTheme = {
88489
88736
  synType: "#267f99",
88490
88737
  synComment: "#008000",
88491
88738
  synControl: "#af00db",
88492
- diffAddBg: "#a6f3b0",
88493
- diffRemoveBg: "#ffc9d0",
88494
88739
  autoAccept: "#15803d",
88495
88740
  planMode: "#267f99",
88496
88741
  duetMode: "#7c3aed",
@@ -88734,6 +88979,11 @@ async function transportBearer(session, store, fallback) {
88734
88979
  if (!token) await syncAccountGate(session, store);
88735
88980
  return token ?? fallback ?? null;
88736
88981
  }
88982
+ async function renewedTransportBearer(session, store, refused, fallback) {
88983
+ const token = await session.renewedAccessToken(refused);
88984
+ if (!token) await syncAccountGate(session, store);
88985
+ return token ?? fallback ?? null;
88986
+ }
88737
88987
  var SIGN_IN_FIRST_MESSAGE = "Sign in first with /signin to start chatting.";
88738
88988
  function isAuthDeadError(e) {
88739
88989
  return /\bhttp 401\b/.test(e instanceof Error ? e.message : String(e));
@@ -89721,11 +89971,6 @@ function appendLiveCode(s, id, delta) {
89721
89971
  if (!live.liveCode || live.liveCode.id !== id) return s;
89722
89972
  return { ...s, live: { ...live, liveCode: { ...live.liveCode, code: live.liveCode.code + delta } } };
89723
89973
  }
89724
- function endLiveCode(s, id) {
89725
- const live = s.live;
89726
- if (!live?.liveCode || live.liveCode.id !== id) return s;
89727
- return { ...s, live: { ...live, liveCode: null } };
89728
- }
89729
89974
  function startTool(s, name2, input) {
89730
89975
  const flushed = flushLive(s);
89731
89976
  const live = flushed.live ?? emptyLive();
@@ -89754,7 +89999,11 @@ function settleToolEnd(s, id, success, detail) {
89754
89999
  }
89755
90000
  const rest = { ...s.live.pendingWrites };
89756
90001
  delete rest[id];
89757
- const nextLive = { ...s.live, pendingWrites: rest, liveCode: null };
90002
+ const nextLive = {
90003
+ ...s.live,
90004
+ pendingWrites: rest,
90005
+ liveCode: s.live.liveCode && s.live.liveCode.id === id ? null : s.live.liveCode
90006
+ };
89758
90007
  if (success) {
89759
90008
  return { ...s, live: nextLive };
89760
90009
  }
@@ -89809,7 +90058,10 @@ function fileModified(s, d2) {
89809
90058
  affectedFiles: d2.affectedFiles,
89810
90059
  trust: d2.trust
89811
90060
  };
89812
- return { ...f, settled: [...f.settled, item] };
90061
+ const block = f.live?.liveCode;
90062
+ const settlesBlock = !!block && (d2.toolId ? block.id === d2.toolId : block.path === d2.path);
90063
+ const live = settlesBlock && f.live ? { ...f.live, liveCode: null } : f.live;
90064
+ return { ...f, live, settled: [...f.settled, item] };
89813
90065
  }
89814
90066
  function applyTurnComplete(s, data) {
89815
90067
  const flushed = flushLive(s);
@@ -90855,7 +91107,7 @@ function remoteView(r2) {
90855
91107
  footer: "Switch with /remote on|off \xB7 hide or show this session with /remote hide|show."
90856
91108
  };
90857
91109
  }
90858
- function goalView(running, goal, turns = 0, lastReason = null) {
91110
+ function goalView(running, goal, turns = 0, lastReason = null, lastClaim = null) {
90859
91111
  if (!running) {
90860
91112
  return {
90861
91113
  title: "Goal",
@@ -90864,7 +91116,12 @@ function goalView(running, goal, turns = 0, lastReason = null) {
90864
91116
  };
90865
91117
  }
90866
91118
  const rows = [statusRow("info", "Running", goal), statusRow("info", "Turns", String(turns))];
90867
- if (lastReason) rows.push(statusRow("pending", "Last check", lastReason));
91119
+ if (lastClaim) {
91120
+ const claim = lastClaim.done ? "done" : "not done";
91121
+ const note = (0, import_client_core15.goalReasonLine)(lastClaim.note);
91122
+ rows.push(statusRow("info", "Agent reports", note ? `${claim} \u2014 ${note}` : claim));
91123
+ }
91124
+ if (lastReason) rows.push(statusRow("pending", "Last check", (0, import_client_core15.goalReasonLine)(lastReason)));
90868
91125
  return {
90869
91126
  title: "Goal",
90870
91127
  tone: "info",
@@ -92091,12 +92348,12 @@ ${(0, import_client_core20.duetRoutingSummaryLine)(await (0, import_client_core2
92091
92348
  if (availability.disabled) {
92092
92349
  ctx.print(`${(0, import_client_core20.duetEntryLabel)(entry)}: ${availability.note ?? "unavailable"}`, "warning");
92093
92350
  if (entry === "router" && routerStatus !== null) ctx.print((0, import_client_core20.duetRouterStatusLine)(routerStatus), "info");
92094
- if (entry === "executor" && executorStatus !== null) ctx.print((0, import_client_core20.executorGateStatusLine)(executorStatus), "info");
92095
92351
  return;
92096
92352
  }
92097
92353
  await (0, import_client_core20.setDuetEntry)(entry);
92098
92354
  const option = import_client_core20.DUET_ENTRY_OPTIONS.find((o) => o.value === entry);
92099
92355
  ctx.print(`${import_client_core20.DUET_ENTRY_INFO.label}: ${(0, import_client_core20.duetEntryLabel)(entry)} \u2014 ${option?.description ?? ""}`, "success");
92356
+ if (entry === "executor" && executorStatus !== null) ctx.print((0, import_client_core20.executorGateStatusLine)(executorStatus), "info");
92100
92357
  };
92101
92358
  if (typed !== null) {
92102
92359
  await save(typed);
@@ -92117,7 +92374,9 @@ ${(0, import_client_core20.duetRoutingSummaryLine)(await (0, import_client_core2
92117
92374
  return {
92118
92375
  label: option.label,
92119
92376
  value: option.value,
92120
- // What it needs beats what it does when it cannot be picked.
92377
+ // The row's note — what this pick means on THIS machine (a refusal reason for
92378
+ // the router, the rules-floor explainer for the executor) — beats the generic
92379
+ // description.
92121
92380
  hint: availability.note ?? (option.value === active ? "(active)" : option.description),
92122
92381
  accent: option.value === active
92123
92382
  };
@@ -93802,7 +94061,7 @@ Answer with /loops answer <text>, or /loops deny.`,
93802
94061
  kind: "local",
93803
94062
  name: "goal",
93804
94063
  aliases: ["goals"],
93805
- description: "Work continuously until the goal is complete \u2014 the agent decides when it's done",
94064
+ description: "Work continuously until the goal is complete \u2014 an independent check confirms it's done",
93806
94065
  argumentHint: "<what to accomplish | status | stop>",
93807
94066
  // Starting a goal starts a TURN — typed mid-turn it defers to the queue
93808
94067
  // (runs when the turn ends) rather than racing the live stream. The verb
@@ -93822,7 +94081,7 @@ Answer with /loops answer <text>, or /loops deny.`,
93822
94081
  }
93823
94082
  if (arg === "" || lower === "status") {
93824
94083
  const st2 = ctx.goals.status();
93825
- return ctx.printInfo(goalView(st2.running, st2.goal, st2.turns ?? 0, st2.lastReason ?? null));
94084
+ return ctx.printInfo(goalView(st2.running, st2.goal, st2.turns ?? 0, st2.lastReason ?? null, st2.lastClaim ?? null));
93826
94085
  }
93827
94086
  if (ctx.goals.status().running) {
93828
94087
  return ctx.print("A goal is already running \u2014 /goal stop first, or steer it by typing normally.", "warning");
@@ -94408,6 +94667,9 @@ function renderLane(transcript, app, ev) {
94408
94667
  transcript.setState(
94409
94668
  (s) => fileModified(s, {
94410
94669
  path: String(d2.path ?? ""),
94670
+ // The causing call — pairs the diff card with the frozen live code
94671
+ // block it settles (rewind-emitted events legitimately omit it).
94672
+ toolId: typeof d2.tool_id === "string" ? d2.tool_id : void 0,
94411
94673
  diff: typeof d2.diff === "string" ? d2.diff : null,
94412
94674
  insertions: typeof d2.insertions === "number" ? d2.insertions : 0,
94413
94675
  deletions: typeof d2.deletions === "number" ? d2.deletions : 0,
@@ -94618,11 +94880,8 @@ function renderLane(transcript, app, ev) {
94618
94880
  }
94619
94881
  break;
94620
94882
  }
94621
- case "tool_input_end": {
94622
- const id = typeof d2.tool_id === "string" ? d2.tool_id : "";
94623
- if (id) transcript.setState((s) => endLiveCode(s, id));
94883
+ case "tool_input_end":
94624
94884
  break;
94625
- }
94626
94885
  case "tool_progress": {
94627
94886
  const kind = typeof d2.kind === "string" ? d2.kind : "working";
94628
94887
  app.setState((s) => ({ ...s, statusText: `${kind}\u2026` }));
@@ -94752,7 +95011,7 @@ function makeGoalRunTurn(deps2) {
94752
95011
  }
94753
95012
  switch (outcome.kind) {
94754
95013
  case "complete":
94755
- return { text: outcome.finalText, evidence: outcome.evidence };
95014
+ return { text: outcome.finalText, evidence: outcome.evidence, claim: outcome.claim };
94756
95015
  case "cancelled":
94757
95016
  return "";
94758
95017
  case "error":
@@ -95197,7 +95456,7 @@ var WorkPlanApprovalBridge = class {
95197
95456
  var import_client_ui_core20 = __toESM(require_dist2(), 1);
95198
95457
 
95199
95458
  // src/components/layout/Transcript.tsx
95200
- var import_react27 = __toESM(require_react(), 1);
95459
+ var import_react28 = __toESM(require_react(), 1);
95201
95460
 
95202
95461
  // src/components/messages/MessageView.tsx
95203
95462
  var import_react23 = __toESM(require_react(), 1);
@@ -111212,7 +111471,27 @@ function expandTabs2(s) {
111212
111471
  }
111213
111472
  return out2;
111214
111473
  }
111215
- function wordRuns(shown, lang, changed, baseBg, brightBg, syntax, theme) {
111474
+ function diffLineStyle(theme, kind) {
111475
+ switch (kind) {
111476
+ case "add":
111477
+ return {
111478
+ bg: theme.diffAddBg,
111479
+ wordBg: theme.diffAddWordBg,
111480
+ accent: theme.diffAdd,
111481
+ text: theme.diffText
111482
+ };
111483
+ case "del":
111484
+ return {
111485
+ bg: theme.diffRemoveBg,
111486
+ wordBg: theme.diffRemoveWordBg,
111487
+ accent: theme.diffRemove,
111488
+ text: theme.diffText
111489
+ };
111490
+ case "context":
111491
+ return { accent: theme.gutter, text: theme.diffText };
111492
+ }
111493
+ }
111494
+ function wordRuns(shown, lang, changed, baseBg, brightBg, syntax, plainFg, theme) {
111216
111495
  let text;
111217
111496
  let fgs;
111218
111497
  if (syntax) {
@@ -111220,12 +111499,12 @@ function wordRuns(shown, lang, changed, baseBg, brightBg, syntax, theme) {
111220
111499
  text = spans.map((s) => s.text).join("");
111221
111500
  fgs = [];
111222
111501
  for (const sp of spans) {
111223
- const fg = synColor(theme, sp.kind);
111502
+ const fg = synColor(theme, sp.kind) ?? plainFg;
111224
111503
  for (let c3 = 0; c3 < sp.text.length; c3++) fgs.push(fg);
111225
111504
  }
111226
111505
  } else {
111227
111506
  text = shown;
111228
- fgs = new Array(shown.length).fill(void 0);
111507
+ fgs = new Array(shown.length).fill(plainFg);
111229
111508
  }
111230
111509
  const bgAt = (k) => changed[k] ? brightBg : baseBg;
111231
111510
  const runs = [];
@@ -111261,8 +111540,10 @@ function StructuredDiff({
111261
111540
  }
111262
111541
  const isAdd = l3.type === "add";
111263
111542
  const isDel = l3.type === "del";
111264
- const bg = isAdd ? theme.diffAddBg : isDel ? theme.diffRemoveBg : void 0;
111265
- const accent = isAdd ? theme.diffAdd : isDel ? theme.diffRemove : theme.gutter;
111543
+ const { bg, wordBg, accent, text } = diffLineStyle(
111544
+ theme,
111545
+ isAdd ? "add" : isDel ? "del" : "context"
111546
+ );
111266
111547
  const marker = isAdd ? "+" : isDel ? "-" : " ";
111267
111548
  const num = isDel ? l3.oldNo : l3.newNo;
111268
111549
  const raw = expandTabs2(l3.text ?? "");
@@ -111279,7 +111560,7 @@ function StructuredDiff({
111279
111560
  while (changed.length < shown.length) changed.push(false);
111280
111561
  }
111281
111562
  }
111282
- const body2 = changed ? wordRuns(shown, lang, changed, bg, accent, isAdd, theme) : isDel ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text2, { children: shown }) : (highlightCode(shown, lang)[0] ?? []).map((sp, k) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text2, { color: synColor(theme, sp.kind), children: sp.text }, k));
111563
+ const body2 = changed ? wordRuns(shown, lang, changed, bg, wordBg, isAdd, text, theme) : isDel ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text2, { color: text, children: shown }) : (highlightCode(shown, lang)[0] ?? []).map((sp, k) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text2, { color: synColor(theme, sp.kind) ?? text, children: sp.text }, k));
111283
111564
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Text2, { backgroundColor: bg, children: [
111284
111565
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Text2, { color: accent, children: [
111285
111566
  gutter(num),
@@ -111787,7 +112068,7 @@ function OrionRing() {
111787
112068
 
111788
112069
  // src/services/version.ts
111789
112070
  function tuiVersion() {
111790
- return "0.1.24".length > 0 ? "0.1.24" : null;
112071
+ return "0.1.25".length > 0 ? "0.1.25" : null;
111791
112072
  }
111792
112073
 
111793
112074
  // src/components/layout/WelcomeCard.tsx
@@ -111826,18 +112107,48 @@ var import_client_ui_core9 = __toESM(require_dist2(), 1);
111826
112107
  var import_client_core29 = __toESM(require_dist(), 1);
111827
112108
 
111828
112109
  // src/components/messages/Thinking.tsx
112110
+ var import_react24 = __toESM(require_react(), 1);
111829
112111
  var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
111830
- var LIVE_LINES = 12;
111831
- var LIVE_CHARS = 1200;
111832
- function thinkingTail(text) {
111833
- const tail = text.split("\n").slice(-LIVE_LINES).join("\n").trimEnd();
111834
- return tail.length > LIVE_CHARS ? `\u2026${tail.slice(-LIVE_CHARS)}` : tail;
112112
+ var LIVE_ROWS = 12;
112113
+ function wrapPlain(line, width) {
112114
+ const rows = [];
112115
+ let row = null;
112116
+ for (const word of line.split(" ")) {
112117
+ let w2 = word;
112118
+ while (w2.length > width) {
112119
+ if (row !== null) {
112120
+ rows.push(row);
112121
+ row = null;
112122
+ }
112123
+ rows.push(w2.slice(0, width));
112124
+ w2 = w2.slice(width);
112125
+ }
112126
+ if (w2 === "" && word !== "") continue;
112127
+ if (row === null) row = w2;
112128
+ else if (row.length + 1 + w2.length <= width) row += ` ${w2}`;
112129
+ else {
112130
+ rows.push(row);
112131
+ row = w2;
112132
+ }
112133
+ }
112134
+ if (row !== null) rows.push(row);
112135
+ return rows.length ? rows : [""];
112136
+ }
112137
+ function thinkingTailRows(text, width) {
112138
+ const w2 = Math.max(1, Math.floor(width));
112139
+ const tail = text.split("\n").slice(-LIVE_ROWS).join("\n").trimEnd();
112140
+ if (!tail) return [];
112141
+ const rows = [];
112142
+ for (const line of tail.split("\n")) rows.push(...wrapPlain(line, w2));
112143
+ return rows.slice(-LIVE_ROWS);
111835
112144
  }
111836
112145
  function Thinking({
111837
112146
  text,
111838
112147
  spinner = ""
111839
112148
  }) {
111840
112149
  const { columns } = useTerminalSize();
112150
+ const width = Math.max(20, columns - 4);
112151
+ const rows = import_react24.default.useMemo(() => thinkingTailRows(text, width), [text, width]);
111841
112152
  if (!text.trim()) return null;
111842
112153
  return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
111843
112154
  /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Box2, { flexDirection: "row", children: [
@@ -111845,7 +112156,7 @@ function Thinking({
111845
112156
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ThemedText, { dim: true, italic: true, children: "Thinking" }),
111846
112157
  spinner ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ThemedText, { colorKey: "spinner", children: ` ${spinner}` }) : null
111847
112158
  ] }),
111848
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { width: Math.max(20, columns - 4), children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ThemedText, { dim: true, italic: true, wrap: "wrap", children: thinkingTail(text) }) }) })
112159
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { width, flexDirection: "column", children: rows.map((row, i2) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ThemedText, { dim: true, italic: true, wrap: "truncate-end", children: row.length ? row : " " }, i2)) }) })
111849
112160
  ] });
111850
112161
  }
111851
112162
 
@@ -111923,21 +112234,21 @@ function LiveCode({
111923
112234
  }
111924
112235
 
111925
112236
  // src/hooks/useStore.ts
111926
- var import_react24 = __toESM(require_react(), 1);
112237
+ var import_react25 = __toESM(require_react(), 1);
111927
112238
  function useStoreSelector(store, selector) {
111928
- return (0, import_react24.useSyncExternalStore)(
112239
+ return (0, import_react25.useSyncExternalStore)(
111929
112240
  store.subscribe,
111930
112241
  () => selector(store.getState())
111931
112242
  );
111932
112243
  }
111933
112244
 
111934
112245
  // src/hooks/useTranscriptEviction.ts
111935
- var import_react26 = __toESM(require_react(), 1);
112246
+ var import_react27 = __toESM(require_react(), 1);
111936
112247
 
111937
112248
  // src/vendor/ink/hooks/use-committed-rows.ts
111938
- var import_react25 = __toESM(require_react(), 1);
112249
+ var import_react26 = __toESM(require_react(), 1);
111939
112250
  function useCommittedRows() {
111940
- return (0, import_react25.useContext)(CommittedRowsContext);
112251
+ return (0, import_react26.useContext)(CommittedRowsContext);
111941
112252
  }
111942
112253
 
111943
112254
  // src/hooks/useTranscriptEviction.ts
@@ -111963,14 +112274,14 @@ function useTranscriptEviction({
111963
112274
  getItemsContainer
111964
112275
  }) {
111965
112276
  const api = useCommittedRows();
111966
- const forkSize = (0, import_react26.useContext)(TerminalSizeContext);
112277
+ const forkSize = (0, import_react27.useContext)(TerminalSizeContext);
111967
112278
  const fallbackSize = useTerminalSize();
111968
112279
  const rows = forkSize?.rows ?? fallbackSize.rows;
111969
112280
  const evictedCount = useStoreSelector(transcriptStore, (s) => s.evictedCount);
111970
112281
  const committedCount = useStoreSelector(transcriptStore, (s) => s.committedCount);
111971
- const apiRef = (0, import_react26.useRef)(api);
112282
+ const apiRef = (0, import_react27.useRef)(api);
111972
112283
  apiRef.current = api;
111973
- (0, import_react26.useLayoutEffect)(() => {
112284
+ (0, import_react27.useLayoutEffect)(() => {
111974
112285
  const snap = (s) => ({
111975
112286
  sessionId: s.sessionId,
111976
112287
  settledLength: s.settled.length,
@@ -111985,7 +112296,7 @@ function useTranscriptEviction({
111985
112296
  prev = s;
111986
112297
  });
111987
112298
  }, [transcriptStore]);
111988
- (0, import_react26.useEffect)(() => {
112299
+ (0, import_react27.useEffect)(() => {
111989
112300
  if (!enabled || !api || items.length <= 1) return;
111990
112301
  const container = getItemsContainer();
111991
112302
  if (!container) return;
@@ -112033,15 +112344,15 @@ function Transcript({
112033
112344
  const subAgents = useStoreSelector(appStore, (s) => s.subAgents);
112034
112345
  const subagentsAwaiting = useStoreSelector(appStore, (s) => s.subagentsAwaiting);
112035
112346
  const { columns } = useTerminalSize();
112036
- const items = import_react27.default.useMemo(
112347
+ const items = import_react28.default.useMemo(
112037
112348
  () => groupToolRuns(evictedCount > 0 ? settled.slice(evictedCount) : settled),
112038
112349
  [settled, evictedCount]
112039
112350
  );
112040
- const itemsContainerRef = import_react27.default.useRef(null);
112041
- const setItemsContainer = import_react27.default.useCallback((el) => {
112351
+ const itemsContainerRef = import_react28.default.useRef(null);
112352
+ const setItemsContainer = import_react28.default.useCallback((el) => {
112042
112353
  itemsContainerRef.current = el;
112043
112354
  }, []);
112044
- const getItemsContainer = import_react27.default.useCallback(() => itemsContainerRef.current, []);
112355
+ const getItemsContainer = import_react28.default.useCallback(() => itemsContainerRef.current, []);
112045
112356
  useTranscriptEviction({ enabled: evictionEnabled, transcriptStore, items, getItemsContainer });
112046
112357
  const running = live?.runningTool ?? null;
112047
112358
  const foldTail = running && !verbose ? trailingToolRun(items) : null;
@@ -112075,10 +112386,10 @@ function Transcript({
112075
112386
  }
112076
112387
 
112077
112388
  // src/components/layout/ReplFooter.tsx
112078
- var import_react46 = __toESM(require_react(), 1);
112389
+ var import_react47 = __toESM(require_react(), 1);
112079
112390
 
112080
112391
  // src/components/tools/PlanCard.tsx
112081
- var import_react28 = __toESM(require_react(), 1);
112392
+ var import_react29 = __toESM(require_react(), 1);
112082
112393
  var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
112083
112394
  function planStepView(index, currentStep) {
112084
112395
  const done2 = index + 1 < currentStep;
@@ -112103,8 +112414,8 @@ function PlanCard({ plan }) {
112103
112414
  const total = plan.steps.length;
112104
112415
  const allDone = total > 0 && plan.current_step > total;
112105
112416
  const planKey = `${plan.current_step}|${plan.steps.join("\0")}`;
112106
- const [hiddenKey, setHiddenKey] = import_react28.default.useState(null);
112107
- import_react28.default.useEffect(() => {
112417
+ const [hiddenKey, setHiddenKey] = import_react29.default.useState(null);
112418
+ import_react29.default.useEffect(() => {
112108
112419
  if (!allDone) return;
112109
112420
  const t = setTimeout(() => setHiddenKey(planKey), DONE_HOLD_MS);
112110
112421
  return () => clearTimeout(t);
@@ -112138,7 +112449,7 @@ function PlanCard({ plan }) {
112138
112449
  }
112139
112450
 
112140
112451
  // src/components/tools/SubAgentCard.tsx
112141
- var import_react29 = __toESM(require_react(), 1);
112452
+ var import_react30 = __toESM(require_react(), 1);
112142
112453
  var import_client_core30 = __toESM(require_dist(), 1);
112143
112454
  var import_client_ui_core10 = __toESM(require_dist2(), 1);
112144
112455
  var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
@@ -112158,8 +112469,8 @@ function SubAgentList({
112158
112469
  }) {
112159
112470
  const running = agents.filter((a) => a.phase !== "finished");
112160
112471
  const visible = !awaiting && running.length > 0;
112161
- const [now2, setNow] = import_react29.default.useState(() => Date.now());
112162
- import_react29.default.useEffect(() => {
112472
+ const [now2, setNow] = import_react30.default.useState(() => Date.now());
112473
+ import_react30.default.useEffect(() => {
112163
112474
  if (!visible) return void 0;
112164
112475
  const timer = setInterval(() => setNow(Date.now()), 1e3);
112165
112476
  return () => clearInterval(timer);
@@ -112175,7 +112486,7 @@ function SubAgentList({
112175
112486
  }
112176
112487
 
112177
112488
  // src/components/input/PromptInput.tsx
112178
- var import_react31 = __toESM(require_react(), 1);
112489
+ var import_react32 = __toESM(require_react(), 1);
112179
112490
 
112180
112491
  // src/components/input/slashSegments.ts
112181
112492
  function segmentSlice(text, offset, ranges) {
@@ -112952,7 +113263,7 @@ function vimKeypress(st2, buffer, input, key) {
112952
113263
  }
112953
113264
 
112954
113265
  // src/voice/useHoldToTalk.ts
112955
- var import_react30 = __toESM(require_react(), 1);
113266
+ var import_react31 = __toESM(require_react(), 1);
112956
113267
  var REPEAT_GAP_MS = 120;
112957
113268
  var WARMUP_THRESHOLD = 2;
112958
113269
  var HOLD_THRESHOLD = 5;
@@ -113110,9 +113421,9 @@ function spliceTranscript(value, cursor, text) {
113110
113421
  return { value: before + inserted + after, cursor: cursor + lead.length + text.length };
113111
113422
  }
113112
113423
  function useHoldToTalk(opts) {
113113
- const optsRef = (0, import_react30.useRef)(opts);
113424
+ const optsRef = (0, import_react31.useRef)(opts);
113114
113425
  optsRef.current = opts;
113115
- const machineRef = (0, import_react30.useRef)(null);
113426
+ const machineRef = (0, import_react31.useRef)(null);
113116
113427
  if (!machineRef.current) {
113117
113428
  machineRef.current = createHoldToTalk(
113118
113429
  {
@@ -113192,37 +113503,37 @@ function PromptInput({
113192
113503
  mode,
113193
113504
  permissionMode
113194
113505
  }) {
113195
- const [value, setValue2] = (0, import_react31.useState)("");
113196
- const [cursor, setCursor] = (0, import_react31.useState)(0);
113197
- const [history, setHistory] = (0, import_react31.useState)(
113506
+ const [value, setValue2] = (0, import_react32.useState)("");
113507
+ const [cursor, setCursor] = (0, import_react32.useState)(0);
113508
+ const [history, setHistory] = (0, import_react32.useState)(
113198
113509
  () => (initialHistory ?? []).slice(0, HISTORY_LIMIT)
113199
113510
  );
113200
- const [vimState, setVimState] = (0, import_react31.useState)(() => initialVimState("insert"));
113201
- const [menuIdx, setMenuIdx] = (0, import_react31.useState)(0);
113202
- const [menuDismissed, setMenuDismissed] = (0, import_react31.useState)(false);
113203
- const [search, setSearch] = (0, import_react31.useState)(null);
113204
- const [escArmed, setEscArmed] = (0, import_react31.useState)(false);
113205
- const [exitArmed, setExitArmed] = (0, import_react31.useState)(null);
113206
- const [postureFlash, setPostureFlash] = (0, import_react31.useState)(false);
113207
- const chordRef = (0, import_react31.useRef)(emptyChord());
113208
- const escAtRef = (0, import_react31.useRef)(0);
113209
- const exitAtRef = (0, import_react31.useRef)(0);
113210
- const valueRef = (0, import_react31.useRef)(value);
113511
+ const [vimState, setVimState] = (0, import_react32.useState)(() => initialVimState("insert"));
113512
+ const [menuIdx, setMenuIdx] = (0, import_react32.useState)(0);
113513
+ const [menuDismissed, setMenuDismissed] = (0, import_react32.useState)(false);
113514
+ const [search, setSearch] = (0, import_react32.useState)(null);
113515
+ const [escArmed, setEscArmed] = (0, import_react32.useState)(false);
113516
+ const [exitArmed, setExitArmed] = (0, import_react32.useState)(null);
113517
+ const [postureFlash, setPostureFlash] = (0, import_react32.useState)(false);
113518
+ const chordRef = (0, import_react32.useRef)(emptyChord());
113519
+ const escAtRef = (0, import_react32.useRef)(0);
113520
+ const exitAtRef = (0, import_react32.useRef)(0);
113521
+ const valueRef = (0, import_react32.useRef)(value);
113211
113522
  valueRef.current = value;
113212
- const cursorRef = (0, import_react31.useRef)(cursor);
113523
+ const cursorRef = (0, import_react32.useRef)(cursor);
113213
113524
  cursorRef.current = cursor;
113214
- const pasteLedger = (0, import_react31.useRef)({ nextId: 1, texts: /* @__PURE__ */ new Map() });
113215
- const recall = (0, import_react31.useRef)(NOT_RECALLING);
113216
- const wheelRef = (0, import_react31.useRef)(createWheelAccel());
113217
- const flashTimer = (0, import_react31.useRef)(null);
113218
- const firstPosture = (0, import_react31.useRef)(true);
113525
+ const pasteLedger = (0, import_react32.useRef)({ nextId: 1, texts: /* @__PURE__ */ new Map() });
113526
+ const recall = (0, import_react32.useRef)(NOT_RECALLING);
113527
+ const wheelRef = (0, import_react32.useRef)(createWheelAccel());
113528
+ const flashTimer = (0, import_react32.useRef)(null);
113529
+ const firstPosture = (0, import_react32.useRef)(true);
113219
113530
  const theme = useTheme();
113220
113531
  const { rows } = useTerminalSize();
113221
- const [voiceState, setVoiceState] = (0, import_react31.useState)("idle");
113222
- const [voiceProgress, setVoiceProgress] = (0, import_react31.useState)(null);
113223
- const [voiceError, setVoiceError] = (0, import_react31.useState)(null);
113224
- const [voiceBlink, setVoiceBlink] = (0, import_react31.useState)(false);
113225
- (0, import_react31.useEffect)(() => {
113532
+ const [voiceState, setVoiceState] = (0, import_react32.useState)("idle");
113533
+ const [voiceProgress, setVoiceProgress] = (0, import_react32.useState)(null);
113534
+ const [voiceError, setVoiceError] = (0, import_react32.useState)(null);
113535
+ const [voiceBlink, setVoiceBlink] = (0, import_react32.useState)(false);
113536
+ (0, import_react32.useEffect)(() => {
113226
113537
  if (voiceState !== "recording") return;
113227
113538
  const t = setInterval(() => setVoiceBlink((b2) => !b2), 600);
113228
113539
  return () => {
@@ -113230,7 +113541,7 @@ function PromptInput({
113230
113541
  setVoiceBlink(false);
113231
113542
  };
113232
113543
  }, [voiceState]);
113233
- const micRef = (0, import_react31.useRef)(null);
113544
+ const micRef = (0, import_react32.useRef)(null);
113234
113545
  const holdToTalk = useHoldToTalk({
113235
113546
  getBuffer: () => ({ value: valueRef.current, cursor: cursorRef.current }),
113236
113547
  applyBuffer: (v2, c3) => {
@@ -113266,11 +113577,11 @@ function PromptInput({
113266
113577
  }
113267
113578
  }
113268
113579
  });
113269
- (0, import_react31.useEffect)(() => () => holdToTalk.dispose(), []);
113270
- (0, import_react31.useEffect)(() => {
113580
+ (0, import_react32.useEffect)(() => () => holdToTalk.dispose(), []);
113581
+ (0, import_react32.useEffect)(() => {
113271
113582
  if (vim) setVimState(initialVimState("insert"));
113272
113583
  }, [vim]);
113273
- (0, import_react31.useEffect)(() => {
113584
+ (0, import_react32.useEffect)(() => {
113274
113585
  if (firstPosture.current) {
113275
113586
  firstPosture.current = false;
113276
113587
  return;
@@ -113282,7 +113593,7 @@ function PromptInput({
113282
113593
  if (flashTimer.current) clearTimeout(flashTimer.current);
113283
113594
  };
113284
113595
  }, [mode, permissionMode]);
113285
- const pickedMentions = (0, import_react31.useRef)(/* @__PURE__ */ new Set());
113596
+ const pickedMentions = (0, import_react32.useRef)(/* @__PURE__ */ new Set());
113286
113597
  const suggestionsFor = (v2) => v2.startsWith("/") && !v2.includes(" ") ? getCompletions?.(v2) ?? [] : [];
113287
113598
  const suggestions = suggestionsFor(value);
113288
113599
  const mPfx = mentionPrefix(value, cursor);
@@ -113290,18 +113601,18 @@ function PromptInput({
113290
113601
  const menuFiles = fileSuggestions.length > 0;
113291
113602
  const menuLen = menuFiles ? fileSuggestions.length : suggestions.length;
113292
113603
  const menuOpen = !menuDismissed && menuLen > 0 && (!vim || vimState.mode === "insert");
113293
- const notifyMenuRef = (0, import_react31.useRef)(onMenuOpenChange);
113604
+ const notifyMenuRef = (0, import_react32.useRef)(onMenuOpenChange);
113294
113605
  notifyMenuRef.current = onMenuOpenChange;
113295
- (0, import_react31.useEffect)(() => {
113606
+ (0, import_react32.useEffect)(() => {
113296
113607
  notifyMenuRef.current?.(menuOpen);
113297
113608
  }, [menuOpen]);
113298
- (0, import_react31.useEffect)(() => () => notifyMenuRef.current?.(false), []);
113299
- (0, import_react31.useEffect)(() => {
113609
+ (0, import_react32.useEffect)(() => () => notifyMenuRef.current?.(false), []);
113610
+ (0, import_react32.useEffect)(() => {
113300
113611
  for (const path14 of pickedMentions.current) {
113301
113612
  if (!value.includes(`${import_client_core32.FILE_MENTION_LEADER}${path14}`)) pickedMentions.current.delete(path14);
113302
113613
  }
113303
113614
  }, [value]);
113304
- (0, import_react31.useEffect)(() => {
113615
+ (0, import_react32.useEffect)(() => {
113305
113616
  setMenuIdx(0);
113306
113617
  setMenuDismissed(false);
113307
113618
  setEscArmed(false);
@@ -113753,7 +114064,7 @@ function PromptInput({
113753
114064
  }
113754
114065
 
113755
114066
  // src/hooks/useIndexBadge.ts
113756
- var import_react32 = __toESM(require_react(), 1);
114067
+ var import_react33 = __toESM(require_react(), 1);
113757
114068
  var READY_BADGE_LINGER_MS = 3e3;
113758
114069
  function shouldShowIndexBadge(mode, phase, lingerElapsed) {
113759
114070
  if (mode !== "on") return true;
@@ -113761,8 +114072,8 @@ function shouldShowIndexBadge(mode, phase, lingerElapsed) {
113761
114072
  return !lingerElapsed;
113762
114073
  }
113763
114074
  function useIndexBadgeVisible(mode, phase, lingerMs = READY_BADGE_LINGER_MS) {
113764
- const [lingerElapsed, setLingerElapsed] = (0, import_react32.useState)(false);
113765
- (0, import_react32.useEffect)(() => {
114075
+ const [lingerElapsed, setLingerElapsed] = (0, import_react33.useState)(false);
114076
+ (0, import_react33.useEffect)(() => {
113766
114077
  setLingerElapsed(false);
113767
114078
  if (phase !== "ready") return;
113768
114079
  const timer = setTimeout(() => setLingerElapsed(true), lingerMs);
@@ -113925,7 +114236,7 @@ function StatusBar({
113925
114236
  }
113926
114237
 
113927
114238
  // src/components/dialogs/AskUserPrompt.tsx
113928
- var import_react33 = __toESM(require_react(), 1);
114239
+ var import_react34 = __toESM(require_react(), 1);
113929
114240
  var import_client_ui_core11 = __toESM(require_dist2(), 1);
113930
114241
 
113931
114242
  // src/components/dialogs/LineEditor.tsx
@@ -113977,15 +114288,15 @@ function AskUserPrompt({
113977
114288
  guardMs = 250
113978
114289
  }) {
113979
114290
  const { requestId, sessionId } = pending;
113980
- const card = (0, import_react33.useMemo)(() => (0, import_client_ui_core11.buildAskCard)(pending.request), [pending.request]);
114291
+ const card = (0, import_react34.useMemo)(() => (0, import_client_ui_core11.buildAskCard)(pending.request), [pending.request]);
113981
114292
  const questions = card.questions;
113982
- const [selections, setSelections] = (0, import_react33.useState)(
114293
+ const [selections, setSelections] = (0, import_react34.useState)(
113983
114294
  () => questions.map(() => import_client_ui_core11.EMPTY_SELECTION)
113984
114295
  );
113985
- const [index, setIndex] = (0, import_react33.useState)(0);
113986
- const [cursor, setCursor] = (0, import_react33.useState)(0);
113987
- const [draft, setDraft] = (0, import_react33.useState)(null);
113988
- const guard = (0, import_react33.useRef)({ id: requestId, at: Date.now() });
114296
+ const [index, setIndex] = (0, import_react34.useState)(0);
114297
+ const [cursor, setCursor] = (0, import_react34.useState)(0);
114298
+ const [draft, setDraft] = (0, import_react34.useState)(null);
114299
+ const guard = (0, import_react34.useRef)({ id: requestId, at: Date.now() });
113989
114300
  if (guard.current.id !== requestId) {
113990
114301
  guard.current = { id: requestId, at: Date.now() };
113991
114302
  }
@@ -114131,7 +114442,7 @@ function writtenInPreview(selection) {
114131
114442
  }
114132
114443
 
114133
114444
  // src/components/dialogs/FeedbackPrompt.tsx
114134
- var import_react34 = __toESM(require_react(), 1);
114445
+ var import_react35 = __toESM(require_react(), 1);
114135
114446
  var import_client_ui_core12 = __toESM(require_dist2(), 1);
114136
114447
  var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
114137
114448
  function FeedbackPrompt({
@@ -114141,10 +114452,10 @@ function FeedbackPrompt({
114141
114452
  guardMs = 250
114142
114453
  }) {
114143
114454
  const { requestId } = pending;
114144
- const [score, setScore] = (0, import_react34.useState)(0);
114145
- const [why, setWhy] = (0, import_react34.useState)(null);
114455
+ const [score, setScore] = (0, import_react35.useState)(0);
114456
+ const [why, setWhy] = (0, import_react35.useState)(null);
114146
114457
  const theme = useTheme();
114147
- const guard = (0, import_react34.useRef)({ id: requestId, at: Date.now() });
114458
+ const guard = (0, import_react35.useRef)({ id: requestId, at: Date.now() });
114148
114459
  if (guard.current.id !== requestId) {
114149
114460
  guard.current = { id: requestId, at: Date.now() };
114150
114461
  }
@@ -114193,13 +114504,13 @@ function FeedbackPrompt({
114193
114504
  }
114194
114505
 
114195
114506
  // src/components/dialogs/PermissionPrompt.tsx
114196
- var import_react36 = __toESM(require_react(), 1);
114507
+ var import_react37 = __toESM(require_react(), 1);
114197
114508
  var import_client_ui_core13 = __toESM(require_dist2(), 1);
114198
114509
  var import_client_ui_core14 = __toESM(require_dist2(), 1);
114199
114510
  var import_client_core34 = __toESM(require_dist(), 1);
114200
114511
 
114201
114512
  // src/components/dialogs/SelectList.tsx
114202
- var import_react35 = __toESM(require_react(), 1);
114513
+ var import_react36 = __toESM(require_react(), 1);
114203
114514
  var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
114204
114515
  function SelectList({
114205
114516
  title,
@@ -114211,17 +114522,17 @@ function SelectList({
114211
114522
  maxVisible
114212
114523
  }) {
114213
114524
  const { rows } = useTerminalSize();
114214
- const [query, setQuery] = (0, import_react35.useState)("");
114215
- const view = (0, import_react35.useMemo)(() => {
114525
+ const [query, setQuery] = (0, import_react36.useState)("");
114526
+ const view = (0, import_react36.useMemo)(() => {
114216
114527
  if (!filterable) return options;
114217
114528
  const q2 = query.trim().toLowerCase();
114218
114529
  if (!q2) return options;
114219
114530
  return options.filter((o) => !o.separator && o.label.toLowerCase().includes(q2));
114220
114531
  }, [options, query, filterable]);
114221
114532
  const selectable = view.flatMap((o, i2) => o.separator ? [] : [i2]);
114222
- const [idx, setIdx] = (0, import_react35.useState)(selectable[0] ?? 0);
114533
+ const [idx, setIdx] = (0, import_react36.useState)(selectable[0] ?? 0);
114223
114534
  const safeIdx = selectable.includes(idx) ? idx : selectable[0] ?? 0;
114224
- (0, import_react35.useEffect)(() => {
114535
+ (0, import_react36.useEffect)(() => {
114225
114536
  if (filterable) setIdx(selectable[0] ?? 0);
114226
114537
  }, [query, filterable]);
114227
114538
  const move = (dir) => {
@@ -114322,12 +114633,12 @@ function PermissionPrompt({
114322
114633
  guardMs = 250
114323
114634
  }) {
114324
114635
  const { data, sessionId } = pending;
114325
- const model = (0, import_react36.useMemo)(
114636
+ const model = (0, import_react37.useMemo)(
114326
114637
  () => (0, import_client_ui_core13.buildPermissionCard)(data, { agentLabel: pending.agentLabel ?? null }),
114327
114638
  [data, pending.agentLabel]
114328
114639
  );
114329
- const [stage, setStage] = (0, import_react36.useState)({ kind: "choose" });
114330
- const guard = (0, import_react36.useRef)({ id: data.request_id, at: Date.now() });
114640
+ const [stage, setStage] = (0, import_react37.useState)({ kind: "choose" });
114641
+ const guard = (0, import_react37.useRef)({ id: data.request_id, at: Date.now() });
114331
114642
  if (guard.current.id !== data.request_id) {
114332
114643
  guard.current = { id: data.request_id, at: Date.now() };
114333
114644
  if (stage.kind !== "choose") setStage({ kind: "choose" });
@@ -114502,7 +114813,7 @@ function PermissionPrompt({
114502
114813
  }
114503
114814
 
114504
114815
  // src/components/dialogs/EndpointsPanel.tsx
114505
- var import_react37 = __toESM(require_react(), 1);
114816
+ var import_react38 = __toESM(require_react(), 1);
114506
114817
  var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
114507
114818
  function maskedKeyState(e) {
114508
114819
  if (e.apiKey) return `key \u2022\u2022\u2022\u2022${e.apiKey.slice(-4)}`;
@@ -114532,20 +114843,20 @@ function EndpointsPanel({
114532
114843
  deps: deps2,
114533
114844
  onClose
114534
114845
  }) {
114535
- const [overlay, setOverlay] = (0, import_react37.useState)(null);
114536
- const [name2, setName] = (0, import_react37.useState)("");
114537
- const [url, setUrl] = (0, import_react37.useState)("");
114538
- const [wire, setWire] = (0, import_react37.useState)("openai");
114539
- const [key, setKey] = (0, import_react37.useState)("");
114540
- const [selected, setSelected] = (0, import_react37.useState)(/* @__PURE__ */ new Set());
114541
- const [discovered, setDiscovered] = (0, import_react37.useState)(null);
114542
- const [modelConfig, setModelConfig] = (0, import_react37.useState)({});
114543
- const [editing, setEditing] = (0, import_react37.useState)(null);
114544
- const [configDraft, setConfigDraft] = (0, import_react37.useState)("");
114545
- const [savedPins, setSavedPins] = (0, import_react37.useState)(/* @__PURE__ */ new Set());
114546
- const [savedConfig, setSavedConfig] = (0, import_react37.useState)({});
114547
- const [fetching, setFetching] = (0, import_react37.useState)(false);
114548
- const [note, setNote] = (0, import_react37.useState)(null);
114846
+ const [overlay, setOverlay] = (0, import_react38.useState)(null);
114847
+ const [name2, setName] = (0, import_react38.useState)("");
114848
+ const [url, setUrl] = (0, import_react38.useState)("");
114849
+ const [wire, setWire] = (0, import_react38.useState)("openai");
114850
+ const [key, setKey] = (0, import_react38.useState)("");
114851
+ const [selected, setSelected] = (0, import_react38.useState)(/* @__PURE__ */ new Set());
114852
+ const [discovered, setDiscovered] = (0, import_react38.useState)(null);
114853
+ const [modelConfig, setModelConfig] = (0, import_react38.useState)({});
114854
+ const [editing, setEditing] = (0, import_react38.useState)(null);
114855
+ const [configDraft, setConfigDraft] = (0, import_react38.useState)("");
114856
+ const [savedPins, setSavedPins] = (0, import_react38.useState)(/* @__PURE__ */ new Set());
114857
+ const [savedConfig, setSavedConfig] = (0, import_react38.useState)({});
114858
+ const [fetching, setFetching] = (0, import_react38.useState)(false);
114859
+ const [note, setNote] = (0, import_react38.useState)(null);
114549
114860
  const slots = [
114550
114861
  ...deps2.entries.map((_2, index) => ({ kind: "entry", index })),
114551
114862
  { kind: "field", field: "name" },
@@ -114555,9 +114866,9 @@ function EndpointsPanel({
114555
114866
  { kind: "action", action: "fetch" },
114556
114867
  { kind: "action", action: "save" }
114557
114868
  ];
114558
- const [at, setAt] = (0, import_react37.useState)(deps2.entries.length);
114869
+ const [at, setAt] = (0, import_react38.useState)(deps2.entries.length);
114559
114870
  const slot = slots[Math.min(at, slots.length - 1)];
114560
- const [verifiedFor, setVerifiedFor] = (0, import_react37.useState)(null);
114871
+ const [verifiedFor, setVerifiedFor] = (0, import_react38.useState)(null);
114561
114872
  const fingerprint = `${url.trim()}\0${key}`;
114562
114873
  const verified = verifiedFor === fingerprint;
114563
114874
  const resetForm = () => {
@@ -115044,7 +115355,7 @@ function EndpointsPanel({
115044
115355
  }
115045
115356
 
115046
115357
  // src/components/dialogs/PermissionRulesPanel.tsx
115047
- var import_react38 = __toESM(require_react(), 1);
115358
+ var import_react39 = __toESM(require_react(), 1);
115048
115359
  var import_client_core35 = __toESM(require_dist(), 1);
115049
115360
  var import_client_ui_core15 = __toESM(require_dist2(), 1);
115050
115361
  var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
@@ -115054,7 +115365,7 @@ function PermissionRulesPanel({
115054
115365
  add,
115055
115366
  onClose
115056
115367
  }) {
115057
- const [stage, setStage] = (0, import_react38.useState)({ kind: "list" });
115368
+ const [stage, setStage] = (0, import_react39.useState)({ kind: "list" });
115058
115369
  use_input_default((input, key) => {
115059
115370
  if (stage.kind !== "list") {
115060
115371
  if (stage.kind === "add-rule") {
@@ -115154,7 +115465,7 @@ function PermissionRulesPanel({
115154
115465
  }
115155
115466
 
115156
115467
  // src/components/dialogs/PlanApprovalPrompt.tsx
115157
- var import_react39 = __toESM(require_react(), 1);
115468
+ var import_react40 = __toESM(require_react(), 1);
115158
115469
  var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
115159
115470
  function PlanApprovalPrompt({
115160
115471
  pending,
@@ -115163,7 +115474,7 @@ function PlanApprovalPrompt({
115163
115474
  guardMs = 250
115164
115475
  }) {
115165
115476
  const { requestId, sessionId } = pending;
115166
- const guard = (0, import_react39.useRef)({ id: requestId, at: Date.now() });
115477
+ const guard = (0, import_react40.useRef)({ id: requestId, at: Date.now() });
115167
115478
  if (guard.current.id !== requestId) guard.current = { id: requestId, at: Date.now() };
115168
115479
  use_input_default((input, key) => {
115169
115480
  if (key.ctrl && input === "c") {
@@ -115197,7 +115508,7 @@ function PlanApprovalPrompt({
115197
115508
  }
115198
115509
 
115199
115510
  // src/components/dialogs/WorkPlanApprovalPrompt.tsx
115200
- var import_react40 = __toESM(require_react(), 1);
115511
+ var import_react41 = __toESM(require_react(), 1);
115201
115512
  var import_client_core36 = __toESM(require_dist(), 1);
115202
115513
  var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
115203
115514
  function WorkPlanApprovalPrompt({
@@ -115207,7 +115518,7 @@ function WorkPlanApprovalPrompt({
115207
115518
  guardMs = 250
115208
115519
  }) {
115209
115520
  const { requestId, plan } = pending;
115210
- const guard = (0, import_react40.useRef)({ id: requestId, at: Date.now() });
115521
+ const guard = (0, import_react41.useRef)({ id: requestId, at: Date.now() });
115211
115522
  if (guard.current.id !== requestId) guard.current = { id: requestId, at: Date.now() };
115212
115523
  use_input_default((input, key) => {
115213
115524
  if (key.ctrl && input === "c") {
@@ -115276,7 +115587,7 @@ function ConfirmDialog({ dialog }) {
115276
115587
  }
115277
115588
 
115278
115589
  // src/components/dialogs/HooksBrowser.tsx
115279
- var import_react41 = __toESM(require_react(), 1);
115590
+ var import_react42 = __toESM(require_react(), 1);
115280
115591
  var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
115281
115592
  function matcherLabel(m2) {
115282
115593
  if (!m2 || typeof m2 !== "object") return "(any)";
@@ -115344,9 +115655,9 @@ function HooksBrowser({
115344
115655
  hooks,
115345
115656
  onClose
115346
115657
  }) {
115347
- const [event, setEvent] = (0, import_react41.useState)(null);
115348
- const [matcher, setMatcher] = (0, import_react41.useState)(null);
115349
- const [hookIdx, setHookIdx] = (0, import_react41.useState)(null);
115658
+ const [event, setEvent] = (0, import_react42.useState)(null);
115659
+ const [matcher, setMatcher] = (0, import_react42.useState)(null);
115660
+ const [hookIdx, setHookIdx] = (0, import_react42.useState)(null);
115350
115661
  if (event === null) {
115351
115662
  const events = [...new Set(hooks.map((h) => h.event ?? "(unknown)"))].sort();
115352
115663
  const options = events.map((e) => {
@@ -115399,7 +115710,7 @@ function HooksBrowser({
115399
115710
  }
115400
115711
 
115401
115712
  // src/components/dialogs/PluginManager.tsx
115402
- var import_react42 = __toESM(require_react(), 1);
115713
+ var import_react43 = __toESM(require_react(), 1);
115403
115714
  var import_client_core37 = __toESM(require_dist(), 1);
115404
115715
  var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
115405
115716
  function pluginId(p) {
@@ -115418,8 +115729,8 @@ function PluginManager({
115418
115729
  install,
115419
115730
  onClose
115420
115731
  }) {
115421
- const [view, setView] = (0, import_react42.useState)({ at: "list" });
115422
- const [busy, setBusy] = (0, import_react42.useState)(false);
115732
+ const [view, setView] = (0, import_react43.useState)({ at: "list" });
115733
+ const [busy, setBusy] = (0, import_react43.useState)(false);
115423
115734
  const finish = (work) => {
115424
115735
  setBusy(true);
115425
115736
  void work.finally(() => {
@@ -115572,7 +115883,7 @@ Install "${view.id}" from "${view.catalog}" (${scope} scope)?`,
115572
115883
  }
115573
115884
 
115574
115885
  // src/components/dialogs/RewindPicker.tsx
115575
- var import_react43 = __toESM(require_react(), 1);
115886
+ var import_react44 = __toESM(require_react(), 1);
115576
115887
  var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
115577
115888
  function statLabel(t) {
115578
115889
  if (!t.files) return "no code changes";
@@ -115587,8 +115898,8 @@ function RewindPicker({
115587
115898
  apply: apply2,
115588
115899
  onClose
115589
115900
  }) {
115590
- const [picked, setPicked] = (0, import_react43.useState)(null);
115591
- const [busy, setBusy] = (0, import_react43.useState)(false);
115901
+ const [picked, setPicked] = (0, import_react44.useState)(null);
115902
+ const [busy, setBusy] = (0, import_react44.useState)(false);
115592
115903
  if (busy) {
115593
115904
  return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(ThemedText, { dim: true, children: "Working\u2026" }) });
115594
115905
  }
@@ -115626,7 +115937,7 @@ function RewindPicker({
115626
115937
  }
115627
115938
 
115628
115939
  // src/components/dialogs/McpManager.tsx
115629
- var import_react44 = __toESM(require_react(), 1);
115940
+ var import_react45 = __toESM(require_react(), 1);
115630
115941
  var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
115631
115942
  function statusLabel(s) {
115632
115943
  return s.status === "needs_auth" ? "needs auth" : s.status ?? "?";
@@ -115644,8 +115955,8 @@ function McpManager({
115644
115955
  act,
115645
115956
  onClose
115646
115957
  }) {
115647
- const [view, setView] = (0, import_react44.useState)({ at: "list" });
115648
- const [busy, setBusy] = (0, import_react44.useState)(false);
115958
+ const [view, setView] = (0, import_react45.useState)({ at: "list" });
115959
+ const [busy, setBusy] = (0, import_react45.useState)(false);
115649
115960
  const finish = (work, backTo = { at: "list" }) => {
115650
115961
  setBusy(true);
115651
115962
  void work.finally(() => {
@@ -116093,7 +116404,7 @@ function UsageMetricsPanel({
116093
116404
  }
116094
116405
 
116095
116406
  // src/components/status/WorkingStatus.tsx
116096
- var import_react45 = __toESM(require_react(), 1);
116407
+ var import_react46 = __toESM(require_react(), 1);
116097
116408
  var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
116098
116409
  var FRAME_MS = 50;
116099
116410
  function WorkingStatus({
@@ -116101,14 +116412,14 @@ function WorkingStatus({
116101
116412
  label,
116102
116413
  now: now2 = Date.now
116103
116414
  }) {
116104
- const startRef = (0, import_react45.useRef)(now2());
116105
- const wordsRef = (0, import_react45.useRef)(shuffleWords(LOADING_WORDS));
116106
- const wordIdxRef = (0, import_react45.useRef)(0);
116107
- const wordStartRef = (0, import_react45.useRef)(startRef.current);
116108
- const dwellRef = (0, import_react45.useRef)(nextCycleMs());
116109
- const [, forceFrame] = (0, import_react45.useState)(0);
116415
+ const startRef = (0, import_react46.useRef)(now2());
116416
+ const wordsRef = (0, import_react46.useRef)(shuffleWords(LOADING_WORDS));
116417
+ const wordIdxRef = (0, import_react46.useRef)(0);
116418
+ const wordStartRef = (0, import_react46.useRef)(startRef.current);
116419
+ const dwellRef = (0, import_react46.useRef)(nextCycleMs());
116420
+ const [, forceFrame] = (0, import_react46.useState)(0);
116110
116421
  const tokens = useStoreSelector(store, (s) => s.turnOutputTokens);
116111
- (0, import_react45.useEffect)(() => {
116422
+ (0, import_react46.useEffect)(() => {
116112
116423
  const timer = setInterval(() => {
116113
116424
  const n2 = now2();
116114
116425
  if (!label && n2 - startRef.current < META_REVEAL_AFTER_MS && n2 - wordStartRef.current >= dwellRef.current) {
@@ -116260,11 +116571,11 @@ function ReplFooter({
116260
116571
  (s) => s.pendingPermissions.length > 0 || !!s.pendingPlanApproval || !!s.pendingAskUser || !!s.pendingWorkPlan
116261
116572
  );
116262
116573
  const closePanel = () => appStore.setState((s) => ({ ...s, activePanel: null }));
116263
- const onQueuePop = import_react46.default.useCallback(
116574
+ const onQueuePop = import_react47.default.useCallback(
116264
116575
  (draft) => popEditableQueue(appStore, draft),
116265
116576
  [appStore]
116266
116577
  );
116267
- const [menuOpen, setMenuOpen] = import_react46.default.useState(false);
116578
+ const [menuOpen, setMenuOpen] = import_react47.default.useState(false);
116268
116579
  return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
116269
116580
  streaming && !parked && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(WorkingStatus, { store: appStore }),
116270
116581
  plan && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(PlanCard, { plan }),
@@ -116380,7 +116691,7 @@ function ReplFooter({
116380
116691
  }
116381
116692
 
116382
116693
  // src/components/layout/FullscreenLayout.tsx
116383
- var import_react47 = __toESM(require_react(), 1);
116694
+ var import_react48 = __toESM(require_react(), 1);
116384
116695
  var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
116385
116696
  function FullscreenLayout({
116386
116697
  appStore,
@@ -116402,7 +116713,7 @@ function FullscreenLayout({
116402
116713
  onCycleMode
116403
116714
  }) {
116404
116715
  const { columns, rows } = useTerminalSize();
116405
- const scrollRef = (0, import_react47.useRef)(null);
116716
+ const scrollRef = (0, import_react48.useRef)(null);
116406
116717
  const onScroll = (delta) => {
116407
116718
  const sb = scrollRef.current;
116408
116719
  if (!sb) return;
@@ -116437,7 +116748,7 @@ function FullscreenLayout({
116437
116748
  }
116438
116749
 
116439
116750
  // src/components/dialogs/AgentsDashboard.tsx
116440
- var import_react48 = __toESM(require_react(), 1);
116751
+ var import_react49 = __toESM(require_react(), 1);
116441
116752
  var import_client_core40 = __toESM(require_dist(), 1);
116442
116753
  var import_client_ui_core17 = __toESM(require_dist2(), 1);
116443
116754
  var import_strip_ansi4 = __toESM(require_strip_ansi(), 1);
@@ -116484,51 +116795,51 @@ function AgentsDashboard({
116484
116795
  onClose
116485
116796
  }) {
116486
116797
  const { rows } = useTerminalSize();
116487
- const [screen, setScreen] = (0, import_react48.useState)({ kind: "list" });
116488
- const [cursor, setCursor] = (0, import_react48.useState)(0);
116489
- const [busy, setBusy] = (0, import_react48.useState)(false);
116490
- const [error, setError] = (0, import_react48.useState)(null);
116491
- const [liveJob, setLiveJob] = (0, import_react48.useState)(null);
116492
- const [events, setEvents] = (0, import_react48.useState)([]);
116493
- const [pollError, setPollError] = (0, import_react48.useState)(null);
116494
- const [diff3, setDiff] = (0, import_react48.useState)(null);
116495
- const diffFetchedFor = (0, import_react48.useRef)(null);
116496
- const [liveItems, setLiveItems] = (0, import_react48.useState)([]);
116497
- const [liveTerm, setLiveTerm] = (0, import_react48.useState)("");
116498
- const [liveFrames, setLiveFrames] = (0, import_react48.useState)(0);
116499
- const liveIdRef = (0, import_react48.useRef)(0);
116500
- const [messaging, setMessaging] = (0, import_react48.useState)(false);
116501
- const [messageText, setMessageText] = (0, import_react48.useState)("");
116502
- const [messageNote, setMessageNote] = (0, import_react48.useState)(null);
116503
- const [tokenStatus, setTokenStatus] = (0, import_react48.useState)(null);
116504
- const [tokenBusy, setTokenBusy] = (0, import_react48.useState)(false);
116505
- const [tokenNote, setTokenNote] = (0, import_react48.useState)(null);
116506
- const [tokenInput, setTokenInput] = (0, import_react48.useState)(false);
116507
- const [tokenDraft, setTokenDraft] = (0, import_react48.useState)("");
116508
- const [jiraStatus, setJiraStatus] = (0, import_react48.useState)(null);
116509
- const [jiraBusy, setJiraBusy] = (0, import_react48.useState)(false);
116510
- const [jiraNote, setJiraNote] = (0, import_react48.useState)(null);
116511
- const [jiraInput, setJiraInput] = (0, import_react48.useState)(null);
116512
- const [form, setForm] = (0, import_react48.useState)(EMPTY_FORM);
116513
- const [field2, setField] = (0, import_react48.useState)(0);
116798
+ const [screen, setScreen] = (0, import_react49.useState)({ kind: "list" });
116799
+ const [cursor, setCursor] = (0, import_react49.useState)(0);
116800
+ const [busy, setBusy] = (0, import_react49.useState)(false);
116801
+ const [error, setError] = (0, import_react49.useState)(null);
116802
+ const [liveJob, setLiveJob] = (0, import_react49.useState)(null);
116803
+ const [events, setEvents] = (0, import_react49.useState)([]);
116804
+ const [pollError, setPollError] = (0, import_react49.useState)(null);
116805
+ const [diff3, setDiff] = (0, import_react49.useState)(null);
116806
+ const diffFetchedFor = (0, import_react49.useRef)(null);
116807
+ const [liveItems, setLiveItems] = (0, import_react49.useState)([]);
116808
+ const [liveTerm, setLiveTerm] = (0, import_react49.useState)("");
116809
+ const [liveFrames, setLiveFrames] = (0, import_react49.useState)(0);
116810
+ const liveIdRef = (0, import_react49.useRef)(0);
116811
+ const [messaging, setMessaging] = (0, import_react49.useState)(false);
116812
+ const [messageText, setMessageText] = (0, import_react49.useState)("");
116813
+ const [messageNote, setMessageNote] = (0, import_react49.useState)(null);
116814
+ const [tokenStatus, setTokenStatus] = (0, import_react49.useState)(null);
116815
+ const [tokenBusy, setTokenBusy] = (0, import_react49.useState)(false);
116816
+ const [tokenNote, setTokenNote] = (0, import_react49.useState)(null);
116817
+ const [tokenInput, setTokenInput] = (0, import_react49.useState)(false);
116818
+ const [tokenDraft, setTokenDraft] = (0, import_react49.useState)("");
116819
+ const [jiraStatus, setJiraStatus] = (0, import_react49.useState)(null);
116820
+ const [jiraBusy, setJiraBusy] = (0, import_react49.useState)(false);
116821
+ const [jiraNote, setJiraNote] = (0, import_react49.useState)(null);
116822
+ const [jiraInput, setJiraInput] = (0, import_react49.useState)(null);
116823
+ const [form, setForm] = (0, import_react49.useState)(EMPTY_FORM);
116824
+ const [field2, setField] = (0, import_react49.useState)(0);
116514
116825
  const jobs = panel.jobs;
116515
116826
  const safeCursor = Math.min(cursor, Math.max(0, jobs.length - 1));
116516
116827
  const detailId = screen.kind === "detail" ? screen.id : null;
116517
116828
  const detailJob = detailId ? liveJob ?? jobs.find((j2) => j2.id === detailId) ?? null : null;
116518
- const panelRef = (0, import_react48.useRef)(panel);
116829
+ const panelRef = (0, import_react49.useRef)(panel);
116519
116830
  panelRef.current = panel;
116520
- const screenRef = (0, import_react48.useRef)(screen);
116831
+ const screenRef = (0, import_react49.useRef)(screen);
116521
116832
  screenRef.current = screen;
116522
- const oauthAlive = (0, import_react48.useRef)(true);
116523
- const oauthTimer = (0, import_react48.useRef)(null);
116524
- (0, import_react48.useEffect)(
116833
+ const oauthAlive = (0, import_react49.useRef)(true);
116834
+ const oauthTimer = (0, import_react49.useRef)(null);
116835
+ (0, import_react49.useEffect)(
116525
116836
  () => () => {
116526
116837
  oauthAlive.current = false;
116527
116838
  if (oauthTimer.current) clearTimeout(oauthTimer.current);
116528
116839
  },
116529
116840
  []
116530
116841
  );
116531
- (0, import_react48.useEffect)(() => {
116842
+ (0, import_react49.useEffect)(() => {
116532
116843
  if (!detailId) return;
116533
116844
  let cancelled = false;
116534
116845
  let timer = null;
@@ -116570,7 +116881,7 @@ function AgentsDashboard({
116570
116881
  };
116571
116882
  }, [detailId]);
116572
116883
  const branchName = detailJob?.branch_name ?? null;
116573
- (0, import_react48.useEffect)(() => {
116884
+ (0, import_react49.useEffect)(() => {
116574
116885
  if (!detailId || !branchName) return;
116575
116886
  const key = `${detailId}:${branchName}`;
116576
116887
  if (diffFetchedFor.current === key) return;
@@ -116588,7 +116899,7 @@ function AgentsDashboard({
116588
116899
  };
116589
116900
  }, [detailId, branchName]);
116590
116901
  const liveSessionId = detailJob && !(0, import_client_core40.isTerminal)(detailJob.status) && detailJob.session_id ? detailJob.session_id : null;
116591
- (0, import_react48.useEffect)(() => {
116902
+ (0, import_react49.useEffect)(() => {
116592
116903
  if (!liveSessionId) return;
116593
116904
  liveIdRef.current = 0;
116594
116905
  setLiveItems([]);
@@ -116609,7 +116920,7 @@ function AgentsDashboard({
116609
116920
  });
116610
116921
  return () => sub.dispose();
116611
116922
  }, [liveSessionId]);
116612
- (0, import_react48.useEffect)(() => {
116923
+ (0, import_react49.useEffect)(() => {
116613
116924
  let cancelled = false;
116614
116925
  void (async () => {
116615
116926
  try {
@@ -117265,14 +117576,14 @@ function LaunchFormView({ form, field: field2 }) {
117265
117576
  }
117266
117577
 
117267
117578
  // src/components/layout/TerminalTitle.tsx
117268
- var import_react50 = __toESM(require_react(), 1);
117579
+ var import_react51 = __toESM(require_react(), 1);
117269
117580
 
117270
117581
  // src/vendor/ink/hooks/use-terminal-title.ts
117271
- var import_react49 = __toESM(require_react(), 1);
117582
+ var import_react50 = __toESM(require_react(), 1);
117272
117583
  var import_strip_ansi5 = __toESM(require_strip_ansi(), 1);
117273
117584
  function useTerminalTitle(title) {
117274
- const writeRaw = (0, import_react49.useContext)(TerminalWriteContext);
117275
- (0, import_react49.useEffect)(() => {
117585
+ const writeRaw = (0, import_react50.useContext)(TerminalWriteContext);
117586
+ (0, import_react50.useEffect)(() => {
117276
117587
  if (title === null || !writeRaw) return;
117277
117588
  const clean = (0, import_strip_ansi5.default)(title);
117278
117589
  if (process.platform === "win32") {
@@ -117298,8 +117609,8 @@ function composeTerminalTitle(sessionTitle, streaming, frame) {
117298
117609
  function TerminalTitle({ appStore }) {
117299
117610
  const sessionTitle = useStoreSelector(appStore, (s) => s.sessionTitle);
117300
117611
  const streaming = useStoreSelector(appStore, (s) => s.status === "streaming");
117301
- const [frame, setFrame] = (0, import_react50.useState)(0);
117302
- (0, import_react50.useEffect)(() => {
117612
+ const [frame, setFrame] = (0, import_react51.useState)(0);
117613
+ (0, import_react51.useEffect)(() => {
117303
117614
  if (!streaming) return;
117304
117615
  const id = setInterval(
117305
117616
  () => setFrame((f) => (f + 1) % TITLE_ANIMATION_FRAMES.length),
@@ -117398,11 +117709,11 @@ function Root({
117398
117709
  }
117399
117710
 
117400
117711
  // src/components/layout/SignInScreen.tsx
117401
- var import_react52 = __toESM(require_react(), 1);
117712
+ var import_react53 = __toESM(require_react(), 1);
117402
117713
  var import_client_core41 = __toESM(require_dist(), 1);
117403
117714
 
117404
117715
  // src/components/layout/splash/Splash.tsx
117405
- var import_react51 = __toESM(require_react(), 1);
117716
+ var import_react52 = __toESM(require_react(), 1);
117406
117717
 
117407
117718
  // src/components/layout/splash/halfblock.ts
117408
117719
  var BLOCK = [" ", "\u2580", "\u2584", "\u2588"];
@@ -117721,7 +118032,7 @@ var TONE = {
117721
118032
  function Splash({ columns, rows, frame, copy }) {
117722
118033
  const theme = useTheme();
117723
118034
  const height = splashHeight(rows);
117724
- const shell2 = import_react51.default.useMemo(() => orbShell(), []);
118035
+ const shell2 = import_react52.default.useMemo(() => orbShell(), []);
117725
118036
  const grid = splashFrame({ width: columns, rows: height, frame, shell: shell2, copy });
117726
118037
  return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(Box2, { flexDirection: "column", children: grid.map((spans, y2) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(Text2, { wrap: "truncate", children: spans.length === 0 ? " " : spans.map((span, i2) => renderSpan(span, i2, theme)) }, y2)) });
117727
118038
  }
@@ -117767,15 +118078,15 @@ function SignInScreen({
117767
118078
  onSignedIn
117768
118079
  }) {
117769
118080
  const { exit } = use_app_default();
117770
- const [phase, setPhase] = import_react52.default.useState("idle");
117771
- const [url, setUrl] = import_react52.default.useState(null);
117772
- const [error, setError] = import_react52.default.useState(null);
117773
- const [frame, setFrame] = import_react52.default.useState(0);
118081
+ const [phase, setPhase] = import_react53.default.useState("idle");
118082
+ const [url, setUrl] = import_react53.default.useState(null);
118083
+ const [error, setError] = import_react53.default.useState(null);
118084
+ const [frame, setFrame] = import_react53.default.useState(0);
117774
118085
  const { columns, rows } = useTerminalSize();
117775
- const caps = import_react52.default.useMemo(() => detectTerminal2(), []);
118086
+ const caps = import_react53.default.useMemo(() => detectTerminal2(), []);
117776
118087
  const copy = splashCopy(phase, error, url, columns);
117777
118088
  const useSplash = !splashDisabled() && caps.unicode && splashFits(columns, rows, copy.length);
117778
- import_react52.default.useEffect(() => {
118089
+ import_react53.default.useEffect(() => {
117779
118090
  if (!useSplash || phase !== "idle") return;
117780
118091
  const t = setInterval(() => setFrame((f) => f + 1), TICK_MS);
117781
118092
  return () => clearInterval(t);
@@ -118539,7 +118850,9 @@ async function runHeadless(flags2) {
118539
118850
  const config = loadConfig();
118540
118851
  if (flags2.workspace) config.workspaceRoot = flags2.workspace;
118541
118852
  const secrets = createSecretStore();
118542
- const session = (0, import_client_core46.createAgentSession)(secrets, config);
118853
+ const session = (0, import_client_core46.createAgentSession)(secrets, config, {
118854
+ trace: (line) => console.error(`[orion-auth] ${line}`)
118855
+ });
118543
118856
  const signedIn = await session.isSignedIn();
118544
118857
  if (!signedIn && !process.env.ORION_AUTH_TOKEN) {
118545
118858
  throw new Error(
@@ -118580,8 +118893,10 @@ async function runHeadless(flags2) {
118580
118893
  }),
118581
118894
  gatewayUrl: () => config.apiUrl,
118582
118895
  clientVersion: tuiVersion() ?? "0.0.0-dev",
118583
- // Mid-segment token-expiry heal — same closure as the transport authToken below.
118584
- renewBearer: async () => await session.currentFreshAccessToken() ?? process.env.ORION_AUTH_TOKEN ?? null,
118896
+ // Mid-segment token-expiry heal — the FAIL-CLOSED renewal, not the fail-open
118897
+ // freshness read the transport authToken below uses (that degradation hands the
118898
+ // refused token back and burns the heal).
118899
+ renewBearer: async (refused) => await session.renewedAccessToken(refused) ?? process.env.ORION_AUTH_TOKEN ?? null,
118585
118900
  log: brainLog
118586
118901
  });
118587
118902
  const turnTransport = (0, import_client_core46.createTurnTransport)({
@@ -118624,6 +118939,7 @@ async function runHeadless(flags2) {
118624
118939
  () => permissionStore.rules()
118625
118940
  );
118626
118941
  executor.enableFileHistorySpill();
118942
+ executor.registerHostTool(import_client_core46.GOAL_REPORT_TOOL, async (params) => (0, import_client_core46.goalReportToolResult)(params));
118627
118943
  const boundary = createBoundaryHandlers({
118628
118944
  bridge,
118629
118945
  executor,
@@ -118655,6 +118971,9 @@ async function runHeadless(flags2) {
118655
118971
  permissionMode: a.permissionMode,
118656
118972
  workspaceRoot: config.workspaceRoot,
118657
118973
  clientType: "tui",
118974
+ // Omitted (not placeholdered) in an unstamped dev/test run — see the interactive
118975
+ // path in main.tsx for why the two absences must stay distinguishable.
118976
+ clientVersion: tuiVersion() ?? void 0,
118658
118977
  mode: a.mode,
118659
118978
  reasoning: a.reasoning,
118660
118979
  tokenSaving: a.tokenSaving,
@@ -118682,7 +119001,8 @@ async function runHeadless(flags2) {
118682
119001
  getMessages: () => snapshot,
118683
119002
  getClientState: () => clientState,
118684
119003
  routing: routing(),
118685
- clientCapabilities: [],
119004
+ // Every headless turn is a goal round — the claim tool is always on.
119005
+ clientCapabilities: [import_client_core46.GOAL_CAPABILITY],
118686
119006
  drainQueuedInput: () => [],
118687
119007
  getOrionResources: () => (0, import_client_core46.buildOrionSnapshot)(config.workspaceRoot, void 0, sessionId),
118688
119008
  getFileHistoryManifest: () => executor.fileHistoryManifest(sessionId)
@@ -118698,7 +119018,11 @@ async function runHeadless(flags2) {
118698
119018
  throw new Error(typeof data.error === "string" ? data.error : "turn failed");
118699
119019
  }
118700
119020
  if (Array.isArray(data.messages)) messages = data.messages;
118701
- return { text: extractFinalAssistantText(data), evidence: (0, import_client_core46.goalEvidenceFromWire)(data.messages) };
119021
+ return {
119022
+ text: extractFinalAssistantText(data),
119023
+ evidence: (0, import_client_core46.goalEvidenceFromWire)(data.messages),
119024
+ claim: (0, import_client_core46.goalClaimFromWire)(data.messages)
119025
+ };
118702
119026
  };
118703
119027
  const { endReason, turns } = await runGoalLoop({
118704
119028
  goal: flags2.goal,
@@ -118711,7 +119035,12 @@ async function runHeadless(flags2) {
118711
119035
  evidence,
118712
119036
  sessionId,
118713
119037
  // Lets the check read the user's `goalEvaluate` model choice.
118714
- workspaceRoot: config.workspaceRoot ?? null
119038
+ workspaceRoot: config.workspaceRoot ?? null,
119039
+ // The run's own model — the fallback when no evaluator model is
119040
+ // configured, so the check never lands on the gateway's deployment
119041
+ // default (see the interactive TUI's identical wiring).
119042
+ sessionModel: routing().model,
119043
+ sessionProvider: routing().provider
118715
119044
  });
118716
119045
  if (ruling.evaluated && !ruling.ok && ruling.achievable) {
118717
119046
  process.stderr.write(`[headless] not met yet \u2014 ${(0, import_client_core46.goalReasonLine)(ruling.reason)}
@@ -118954,7 +119283,11 @@ async function main() {
118954
119283
  }
118955
119284
  });
118956
119285
  const secrets = createSecretStore();
118957
- const session = (0, import_client_core49.createAgentSession)(secrets, config);
119286
+ const session = (0, import_client_core49.createAgentSession)(secrets, config, {
119287
+ // Renewal/refresh breadcrumbs (step outcomes + timings, never tokens) — the evidence
119288
+ // the 2026-08-22 refresh-wedge investigation lacked.
119289
+ trace: (line) => console.error(`[orion-auth] ${line}`)
119290
+ });
118958
119291
  const outcomes = new import_client_core49.OutcomeReporter({
118959
119292
  apiBaseUrl: () => config.accountsApiUrl,
118960
119293
  accessToken: () => session.currentAccessToken()
@@ -119027,10 +119360,10 @@ async function main() {
119027
119360
  }),
119028
119361
  gatewayUrl: () => config.apiUrl,
119029
119362
  clientVersion: tuiVersion() ?? "0.0.0-dev",
119030
- // Mid-segment token-expiry heal: the SAME bearer seam the per-segment authToken uses —
119031
- // an expired stored token forces its refresh, so calling it again IS the renewal (the
119032
- // brain retries once with the result); an emptied store re-gates the chat.
119033
- renewBearer: () => transportBearer(session, appStore, process.env.ORION_AUTH_TOKEN),
119363
+ // Mid-segment token-expiry heal: the FAIL-CLOSED renewal seam, NOT the fail-open
119364
+ // per-segment authToken read — the refused token rides in so the answer is decided
119365
+ // on token identity, never local clocks; an emptied store re-gates the chat.
119366
+ renewBearer: (refused) => renewedTransportBearer(session, appStore, refused, process.env.ORION_AUTH_TOKEN),
119034
119367
  log: brainLog
119035
119368
  });
119036
119369
  return brainInstance;
@@ -119769,6 +120102,11 @@ async function main() {
119769
120102
  workspaceRoot: config.workspaceRoot,
119770
120103
  clientType: "tui",
119771
120104
  // usage-telemetry surface tag
120105
+ // …and the build behind that tag. `tuiVersion()` is null in an unstamped dev/test run,
120106
+ // which becomes `undefined` here so the key is OMITTED rather than sent as a placeholder:
120107
+ // "not reported" and "reported but unreadable" are different states downstream, and a dev
120108
+ // build is the former.
120109
+ clientVersion: tuiVersion() ?? void 0,
119772
120110
  // mode/reasoning/context_window ride the body too (rule 1) so a cold pod keeps
119773
120111
  // plan/ask read-only + the right model settings — not a per-pod set_* RPC.
119774
120112
  mode: a.mode,
@@ -119936,7 +120274,10 @@ async function main() {
119936
120274
  import_client_core49.DUET_REPLAN_CAPABILITY,
119937
120275
  // …and runs the planner's `hand_off` (leg marker, phase line, journal), so
119938
120276
  // planner entry may offer it (further leg-gated backend-side).
119939
- import_client_core49.DUET_HANDOFF_CAPABILITY
120277
+ import_client_core49.DUET_HANDOFF_CAPABILITY,
120278
+ // `goal` lights up the goal_report claim tool, and only while a goal is
120279
+ // actually driving this conversation — an ordinary chat never sees it.
120280
+ ...goalRunner !== null ? [import_client_core49.GOAL_CAPABILITY] : []
119940
120281
  ],
119941
120282
  extraBody: {
119942
120283
  ...appStore.getState().subagentsEnabled ? agentManager.parentExtraBody() : {},
@@ -120012,7 +120353,8 @@ async function main() {
120012
120353
  endSettle = {
120013
120354
  kind: "complete",
120014
120355
  finalText: (0, import_client_core49.finalAssistantTextFromWire)(data.messages),
120015
- evidence: (0, import_client_core49.goalEvidenceFromWire)(data.messages)
120356
+ evidence: (0, import_client_core49.goalEvidenceFromWire)(data.messages),
120357
+ claim: (0, import_client_core49.goalClaimFromWire)(data.messages)
120016
120358
  };
120017
120359
  (0, import_client_core48.recordTurnMetrics)({
120018
120360
  app: "tui",
@@ -120193,6 +120535,7 @@ async function main() {
120193
120535
  );
120194
120536
  return (0, import_client_core49.duetHandoffResult)();
120195
120537
  });
120538
+ executor.registerHostTool(import_client_core49.GOAL_REPORT_TOOL, async (params) => (0, import_client_core49.goalReportToolResult)(params));
120196
120539
  const loopService = new LoopService({
120197
120540
  workspaceRoot: config.workspaceRoot,
120198
120541
  schedulePath: loopSchedulePathFor((0, import_client_core49.runsRootFor)("loops", config.workspaceRoot)),
@@ -120266,12 +120609,27 @@ async function main() {
120266
120609
  // stranger's routing.
120267
120610
  sessionId: goalSessionId ?? void 0,
120268
120611
  // Lets the check read the user's `goalEvaluate` model choice.
120269
- workspaceRoot: currentRouting().workspaceRoot ?? null
120612
+ workspaceRoot: currentRouting().workspaceRoot ?? null,
120613
+ // The session's model as THIS CLIENT knows it — the fallback when no
120614
+ // evaluator model is configured. The gateway's own session record can
120615
+ // still hold the deployment default for a local-brain session (routing
120616
+ // rides segment bodies), and a check on that default is a check on a
120617
+ // model this session never used.
120618
+ sessionModel: currentRouting().model,
120619
+ sessionProvider: currentRouting().provider
120270
120620
  });
120271
- if (ruling.evaluated && !ruling.ok && ruling.achievable) {
120272
- transcriptStore.setState((s) => appendGoalNoteFor(s, goalSessionId, (0, import_client_core49.goalNotMetRow)(ruling.reason)));
120273
- }
120274
120621
  return ruling;
120622
+ },
120623
+ // A round that did NOT meet the goal says so — in the judge's words when a
120624
+ // check ran, in the agent's own honest not-done report when none did
120625
+ // (goalRoundReason is the one mapping, shared by every client). Without it
120626
+ // a long goal is a wall of identical continuation lines and a stuck one is
120627
+ // indistinguishable from a working one.
120628
+ onRound: (round) => {
120629
+ const reason = (0, import_client_core49.goalRoundReason)(round);
120630
+ if (reason !== "") {
120631
+ transcriptStore.setState((s) => appendGoalNoteFor(s, goalSessionId, (0, import_client_core49.goalNotMetRow)(reason)));
120632
+ }
120275
120633
  }
120276
120634
  });
120277
120635
  goalRunner = runner;
@@ -120287,6 +120645,7 @@ async function main() {
120287
120645
  runCommand: routeInput
120288
120646
  });
120289
120647
  });
120648
+ transcriptStore.setState((s) => appendGoalNoteFor(s, goalSessionId, (0, import_client_core49.goalSetRow)(goal)));
120290
120649
  };
120291
120650
  const enqueueSteer = (text) => {
120292
120651
  appStore.setState((s) => ({ ...s, queuedMessages: [...s.queuedMessages, queuedSteer(text)] }));