orion-super-agent-dev 0.1.15 → 0.1.16

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
@@ -1371,7 +1371,7 @@ var require_react_development = __commonJS({
1371
1371
  }
1372
1372
  return dispatcher2.useContext(Context);
1373
1373
  }
1374
- function useState20(initialState) {
1374
+ function useState21(initialState) {
1375
1375
  var dispatcher2 = resolveDispatcher();
1376
1376
  return dispatcher2.useState(initialState);
1377
1377
  }
@@ -1379,7 +1379,7 @@ var require_react_development = __commonJS({
1379
1379
  var dispatcher2 = resolveDispatcher();
1380
1380
  return dispatcher2.useReducer(reducer, initialArg, init2);
1381
1381
  }
1382
- function useRef13(initialValue) {
1382
+ function useRef14(initialValue) {
1383
1383
  var dispatcher2 = resolveDispatcher();
1384
1384
  return dispatcher2.useRef(initialValue);
1385
1385
  }
@@ -2173,8 +2173,8 @@ var require_react_development = __commonJS({
2173
2173
  exports2.useLayoutEffect = useLayoutEffect4;
2174
2174
  exports2.useMemo = useMemo7;
2175
2175
  exports2.useReducer = useReducer;
2176
- exports2.useRef = useRef13;
2177
- exports2.useState = useState20;
2176
+ exports2.useRef = useRef14;
2177
+ exports2.useState = useState21;
2178
2178
  exports2.useSyncExternalStore = useSyncExternalStore3;
2179
2179
  exports2.useTransition = useTransition;
2180
2180
  exports2.version = ReactVersion;
@@ -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 React30 = require_react();
2233
+ var React31 = 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 = React30.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2259
+ var ReactSharedInternals = React31.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2260
2260
  function error(format2) {
2261
2261
  {
2262
2262
  {
@@ -3106,11 +3106,11 @@ var require_react_jsx_runtime_development = __commonJS({
3106
3106
  return jsxWithValidation(type, props, key, false);
3107
3107
  }
3108
3108
  }
3109
- var jsx73 = jsxWithValidationDynamic;
3110
- var jsxs51 = jsxWithValidationStatic;
3109
+ var jsx74 = jsxWithValidationDynamic;
3110
+ var jsxs52 = jsxWithValidationStatic;
3111
3111
  exports2.Fragment = REACT_FRAGMENT_TYPE;
3112
- exports2.jsx = jsx73;
3113
- exports2.jsxs = jsxs51;
3112
+ exports2.jsx = jsx74;
3113
+ exports2.jsxs = jsxs52;
3114
3114
  })();
3115
3115
  }
3116
3116
  }
@@ -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 React30 = require_react();
9966
+ var React31 = require_react();
9967
9967
  var Scheduler = require_scheduler();
9968
- var ReactSharedInternals = React30.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
9968
+ var ReactSharedInternals = React31.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
9969
9969
  var suppressWarning = false;
9970
9970
  function setSuppressWarning(newSuppressWarning) {
9971
9971
  {
@@ -10029,7 +10029,7 @@ var require_react_reconciler_development = __commonJS({
10029
10029
  var HostPortal = 4;
10030
10030
  var HostComponent = 5;
10031
10031
  var HostText = 6;
10032
- var Fragment12 = 7;
10032
+ var Fragment13 = 7;
10033
10033
  var Mode = 8;
10034
10034
  var ContextConsumer = 9;
10035
10035
  var ContextProvider = 10;
@@ -10169,7 +10169,7 @@ var require_react_reconciler_development = __commonJS({
10169
10169
  return "DehydratedFragment";
10170
10170
  case ForwardRef:
10171
10171
  return getWrappedName$1(type, type.render, "ForwardRef");
10172
- case Fragment12:
10172
+ case Fragment13:
10173
10173
  return "Fragment";
10174
10174
  case HostComponent:
10175
10175
  return type;
@@ -13303,7 +13303,7 @@ var require_react_reconciler_development = __commonJS({
13303
13303
  }
13304
13304
  }
13305
13305
  function updateFragment2(returnFiber, current3, fragment, lanes, key) {
13306
- if (current3 === null || current3.tag !== Fragment12) {
13306
+ if (current3 === null || current3.tag !== Fragment13) {
13307
13307
  var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
13308
13308
  created.return = returnFiber;
13309
13309
  return created;
@@ -13706,7 +13706,7 @@ var require_react_reconciler_development = __commonJS({
13706
13706
  if (child.key === key) {
13707
13707
  var elementType = element.type;
13708
13708
  if (elementType === REACT_FRAGMENT_TYPE) {
13709
- if (child.tag === Fragment12) {
13709
+ if (child.tag === Fragment13) {
13710
13710
  deleteRemainingChildren(returnFiber, child.sibling);
13711
13711
  var existing = useFiber(child, element.props.children);
13712
13712
  existing.return = returnFiber;
@@ -19197,7 +19197,7 @@ var require_react_reconciler_development = __commonJS({
19197
19197
  var _resolvedProps2 = workInProgress2.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
19198
19198
  return updateForwardRef(current3, workInProgress2, type, _resolvedProps2, renderLanes2);
19199
19199
  }
19200
- case Fragment12:
19200
+ case Fragment13:
19201
19201
  return updateFragment(current3, workInProgress2, renderLanes2);
19202
19202
  case Mode:
19203
19203
  return updateMode(current3, workInProgress2, renderLanes2);
@@ -19634,7 +19634,7 @@ var require_react_reconciler_development = __commonJS({
19634
19634
  case SimpleMemoComponent:
19635
19635
  case FunctionComponent:
19636
19636
  case ForwardRef:
19637
- case Fragment12:
19637
+ case Fragment13:
19638
19638
  case Mode:
19639
19639
  case Profiler:
19640
19640
  case ContextConsumer:
@@ -24402,7 +24402,7 @@ var require_react_reconciler_development = __commonJS({
24402
24402
  return fiber;
24403
24403
  }
24404
24404
  function createFiberFromFragment(elements, mode, lanes, key) {
24405
- var fiber = createFiber(Fragment12, elements, key, mode);
24405
+ var fiber = createFiber(Fragment13, elements, key, mode);
24406
24406
  fiber.lanes = lanes;
24407
24407
  return fiber;
24408
24408
  }
@@ -36859,6 +36859,243 @@ var require_outcomeReporter = __commonJS({
36859
36859
  }
36860
36860
  });
36861
36861
 
36862
+ // ../packages/orion-client-core/dist/feedbackScrub.js
36863
+ var require_feedbackScrub = __commonJS({
36864
+ "../packages/orion-client-core/dist/feedbackScrub.js"(exports2) {
36865
+ "use strict";
36866
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m2, k, k2) {
36867
+ if (k2 === void 0) k2 = k;
36868
+ var desc = Object.getOwnPropertyDescriptor(m2, k);
36869
+ if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
36870
+ desc = { enumerable: true, get: function() {
36871
+ return m2[k];
36872
+ } };
36873
+ }
36874
+ Object.defineProperty(o, k2, desc);
36875
+ } : function(o, m2, k, k2) {
36876
+ if (k2 === void 0) k2 = k;
36877
+ o[k2] = m2[k];
36878
+ });
36879
+ var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v2) {
36880
+ Object.defineProperty(o, "default", { enumerable: true, value: v2 });
36881
+ } : function(o, v2) {
36882
+ o["default"] = v2;
36883
+ });
36884
+ var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
36885
+ var ownKeys = function(o) {
36886
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
36887
+ var ar = [];
36888
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
36889
+ return ar;
36890
+ };
36891
+ return ownKeys(o);
36892
+ };
36893
+ return function(mod2) {
36894
+ if (mod2 && mod2.__esModule) return mod2;
36895
+ var result = {};
36896
+ if (mod2 != null) {
36897
+ for (var k = ownKeys(mod2), i2 = 0; i2 < k.length; i2++) if (k[i2] !== "default") __createBinding(result, mod2, k[i2]);
36898
+ }
36899
+ __setModuleDefault(result, mod2);
36900
+ return result;
36901
+ };
36902
+ }();
36903
+ Object.defineProperty(exports2, "__esModule", { value: true });
36904
+ exports2.FEEDBACK_CONVERSATION_MAX_BYTES = void 0;
36905
+ exports2.redactFeedbackText = redactFeedbackText;
36906
+ exports2.scrubFeedbackConversation = scrubFeedbackConversation2;
36907
+ var os8 = __importStar(__require("os"));
36908
+ exports2.FEEDBACK_CONVERSATION_MAX_BYTES = 1e6;
36909
+ var REDACTORS = [
36910
+ {
36911
+ // PEM private-key blocks, any algorithm label, multi-line.
36912
+ pattern: /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g,
36913
+ replacement: "[redacted:private-key]"
36914
+ },
36915
+ {
36916
+ // Authorization headers (Bearer/Basic/token …) — through end of the credential.
36917
+ pattern: /\b(authorization\s*[:=]\s*)(?:bearer|basic|token)\s+[^\s"'`,;]+/gi,
36918
+ replacement: "$1[redacted:credential]"
36919
+ },
36920
+ {
36921
+ // Bare bearer credentials outside a header line.
36922
+ pattern: /\bbearer\s+[A-Za-z0-9._~+/=-]{16,}/gi,
36923
+ replacement: "bearer [redacted:credential]"
36924
+ },
36925
+ {
36926
+ // JWT triplets (header.payload.signature).
36927
+ pattern: /\bey[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{10,}\b/g,
36928
+ replacement: "[redacted:jwt]"
36929
+ },
36930
+ {
36931
+ // Common API-key shapes: OpenAI-style sk-, GitHub gh?_, AWS AKIA, Slack xox?-.
36932
+ pattern: /\bsk-[A-Za-z0-9_-]{16,}\b/g,
36933
+ replacement: "[redacted:api-key]"
36934
+ },
36935
+ {
36936
+ pattern: /\bgh[pousr]_[A-Za-z0-9]{20,}\b/g,
36937
+ replacement: "[redacted:api-key]"
36938
+ },
36939
+ {
36940
+ // Stripe secret/restricted keys use an UNDERSCORE (sk_live_/sk_test_/rk_...).
36941
+ pattern: /\b[sr]k_(?:live|test)_[A-Za-z0-9]{10,}\b/g,
36942
+ replacement: "[redacted:api-key]"
36943
+ },
36944
+ {
36945
+ // Google API keys.
36946
+ pattern: /\bAIza[0-9A-Za-z_-]{35}\b/g,
36947
+ replacement: "[redacted:api-key]"
36948
+ },
36949
+ {
36950
+ pattern: /\bAKIA[0-9A-Z]{16}\b/g,
36951
+ replacement: "[redacted:api-key]"
36952
+ },
36953
+ {
36954
+ pattern: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g,
36955
+ replacement: "[redacted:api-key]"
36956
+ },
36957
+ {
36958
+ // Cookie material — redact through end of line (the partial-redaction lesson:
36959
+ // `Cookie: a=b; c=d` must not leak everything past the first pair).
36960
+ pattern: /\b(cookie|set-cookie)\s*:[^\n]+/gi,
36961
+ replacement: "$1: [redacted:cookie]"
36962
+ },
36963
+ {
36964
+ // Generic secret-bearing ASSIGNMENTS — the .env / YAML / JSON-ish / header shapes
36965
+ // a transcript picks up when a tool cats config (password=…, api_key: …,
36966
+ // aws_secret_access_key=…, x-api-key: …). Keeps the key name, redacts the value.
36967
+ // Deliberately greedy on what counts as a value (≥6 non-space chars): this module
36968
+ // errs toward redacting, and over-anonymizing prose costs nothing next to
36969
+ // shipping a live credential.
36970
+ pattern: /\b((?:aws_)?(?:x[-_])?(?:api[-_]?key|apikey|secret(?:[-_]?(?:key|access[-_]?key))?|access[-_]?key(?:[-_]?id)?|client[-_]?secret|auth[-_]?token|password|passwd)\s*["']?\s*[=:]\s*)["']?[^\s"',;]{6,}/gi,
36971
+ replacement: "$1[redacted:secret]"
36972
+ },
36973
+ {
36974
+ // Email addresses.
36975
+ pattern: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,
36976
+ replacement: "[redacted:email]"
36977
+ }
36978
+ ];
36979
+ function redactFeedbackText(text, homeDir) {
36980
+ let out2 = text;
36981
+ for (const { pattern, replacement } of REDACTORS) {
36982
+ out2 = out2.replace(pattern, replacement);
36983
+ }
36984
+ const home = homeDir ?? defaultHomeDir();
36985
+ if (home && home.length > 1) {
36986
+ out2 = out2.split(home).join("~");
36987
+ }
36988
+ return out2;
36989
+ }
36990
+ function defaultHomeDir() {
36991
+ try {
36992
+ return os8.homedir();
36993
+ } catch {
36994
+ return "";
36995
+ }
36996
+ }
36997
+ function scrubValue(value, homeDir) {
36998
+ if (typeof value === "string")
36999
+ return redactFeedbackText(value, homeDir);
37000
+ if (Array.isArray(value))
37001
+ return value.map((item) => scrubValue(item, homeDir));
37002
+ if (typeof value === "object" && value !== null) {
37003
+ const out2 = {};
37004
+ for (const [key, item] of Object.entries(value)) {
37005
+ out2[key] = scrubValue(item, homeDir);
37006
+ }
37007
+ return out2;
37008
+ }
37009
+ return value;
37010
+ }
37011
+ function messageBytes(message) {
37012
+ try {
37013
+ const serialized = JSON.stringify(message);
37014
+ if (typeof serialized !== "string")
37015
+ return 0;
37016
+ return new TextEncoder().encode(serialized).length;
37017
+ } catch {
37018
+ return null;
37019
+ }
37020
+ }
37021
+ function scrubFeedbackConversation2(conversation, opts = {}) {
37022
+ const maxBytes = opts.maxBytes ?? exports2.FEEDBACK_CONVERSATION_MAX_BYTES;
37023
+ const scrubbed = conversation.map((message) => scrubValue(message, opts.homeDir));
37024
+ const sizes = [];
37025
+ let truncated = false;
37026
+ const keep = [];
37027
+ for (const message of scrubbed) {
37028
+ const bytes = messageBytes(message);
37029
+ if (bytes === null) {
37030
+ truncated = true;
37031
+ continue;
37032
+ }
37033
+ keep.push(message);
37034
+ sizes.push(bytes + 1);
37035
+ }
37036
+ let total = sizes.reduce((sum, n) => sum + n, 2);
37037
+ let start2 = 0;
37038
+ while (total > maxBytes && start2 < keep.length) {
37039
+ total -= sizes[start2];
37040
+ start2 += 1;
37041
+ truncated = true;
37042
+ }
37043
+ return { conversation: keep.slice(start2), truncated };
37044
+ }
37045
+ }
37046
+ });
37047
+
37048
+ // ../packages/orion-client-core/dist/feedbackSubmit.js
37049
+ var require_feedbackSubmit = __commonJS({
37050
+ "../packages/orion-client-core/dist/feedbackSubmit.js"(exports2) {
37051
+ "use strict";
37052
+ Object.defineProperty(exports2, "__esModule", { value: true });
37053
+ exports2.FEEDBACK_SUBMIT_TIMEOUT_MS = void 0;
37054
+ exports2.sendFeedbackSubmission = sendFeedbackSubmission2;
37055
+ exports2.sendFeedbackImpression = sendFeedbackImpression2;
37056
+ exports2.FEEDBACK_SUBMIT_TIMEOUT_MS = 1e4;
37057
+ async function post(deps2, body2, attempts) {
37058
+ let token;
37059
+ try {
37060
+ token = await deps2.accessToken();
37061
+ } catch {
37062
+ return;
37063
+ }
37064
+ if (!token)
37065
+ return;
37066
+ const fetchFn = deps2.fetchFn ?? fetch;
37067
+ let payload;
37068
+ try {
37069
+ payload = JSON.stringify(body2);
37070
+ } catch {
37071
+ return;
37072
+ }
37073
+ for (let attempt = 0; attempt < attempts; attempt++) {
37074
+ try {
37075
+ const res = await fetchFn(`${deps2.apiBaseUrl()}/v1/feedback`, {
37076
+ method: "POST",
37077
+ headers: {
37078
+ authorization: `Bearer ${token}`,
37079
+ "content-type": "application/json"
37080
+ },
37081
+ body: payload,
37082
+ signal: AbortSignal.timeout(exports2.FEEDBACK_SUBMIT_TIMEOUT_MS)
37083
+ });
37084
+ if (res.ok || res.status < 500)
37085
+ return;
37086
+ } catch {
37087
+ }
37088
+ }
37089
+ }
37090
+ async function sendFeedbackSubmission2(deps2, body2) {
37091
+ await post(deps2, body2, 2);
37092
+ }
37093
+ async function sendFeedbackImpression2(deps2, event, client) {
37094
+ await post(deps2, { schema: 1, type: "impression", event, client }, 1);
37095
+ }
37096
+ }
37097
+ });
37098
+
36862
37099
  // ../packages/orion-client-core/dist/indexResultLinks.js
36863
37100
  var require_indexResultLinks = __commonJS({
36864
37101
  "../packages/orion-client-core/dist/indexResultLinks.js"(exports2) {
@@ -39433,12 +39670,33 @@ var require_backfill = __commonJS({
39433
39670
  }
39434
39671
  });
39435
39672
 
39673
+ // ../packages/orion-client-core/dist/remoteControl/deadline.js
39674
+ var require_deadline = __commonJS({
39675
+ "../packages/orion-client-core/dist/remoteControl/deadline.js"(exports2) {
39676
+ "use strict";
39677
+ Object.defineProperty(exports2, "__esModule", { value: true });
39678
+ exports2.withDeadline = withDeadline;
39679
+ function withDeadline(work, ms, timeoutError) {
39680
+ return new Promise((resolve5, reject) => {
39681
+ const timer = setTimeout(() => reject(timeoutError()), ms);
39682
+ Promise.resolve(work).then((value) => {
39683
+ clearTimeout(timer);
39684
+ resolve5(value);
39685
+ }, (error) => {
39686
+ clearTimeout(timer);
39687
+ reject(error);
39688
+ });
39689
+ });
39690
+ }
39691
+ }
39692
+ });
39693
+
39436
39694
  // ../packages/orion-client-core/dist/remoteControl/types.js
39437
39695
  var require_types2 = __commonJS({
39438
39696
  "../packages/orion-client-core/dist/remoteControl/types.js"(exports2) {
39439
39697
  "use strict";
39440
39698
  Object.defineProperty(exports2, "__esModule", { value: true });
39441
- exports2.RC_TUNING_DEFAULTS = exports2.RC_OK = exports2.RC_EFFORT_LEVELS = exports2.RC_SESSION_FIELD_BOUNDS = exports2.RC_COMMAND_BOUNDS = void 0;
39699
+ exports2.RC_TUNING_DEFAULTS = exports2.RC_OK = exports2.TURN_TERMINAL_KINDS = exports2.RC_EFFORT_LEVELS = exports2.RC_SESSION_FIELD_BOUNDS = exports2.RC_COMMAND_BOUNDS = void 0;
39442
39700
  exports2.boundedCommandCatalog = boundedCommandCatalog;
39443
39701
  exports2.rcEffortToLocal = rcEffortToLocal2;
39444
39702
  exports2.rcEffortToWire = rcEffortToWire2;
@@ -39477,6 +39735,10 @@ var require_types2 = __commonJS({
39477
39735
  function rcEffortToWire2(effort) {
39478
39736
  return effort === "" ? "off" : effort;
39479
39737
  }
39738
+ exports2.TURN_TERMINAL_KINDS = /* @__PURE__ */ new Set([
39739
+ "turn_complete",
39740
+ "turn_error"
39741
+ ]);
39480
39742
  exports2.RC_OK = Object.freeze({ ok: true });
39481
39743
  function rcRefusePhotosMidTurn2() {
39482
39744
  return rcRefuse2("internal", "a turn is running \u2014 photos can start the next one");
@@ -39505,7 +39767,8 @@ var require_types2 = __commonJS({
39505
39767
  dedupRing: 256,
39506
39768
  failureBudgetMs: 6e5,
39507
39769
  sleepGapFactor: 3,
39508
- rpcDeadlineMs: 15e3
39770
+ rpcDeadlineMs: 15e3,
39771
+ publishDeadlineMs: 45e3
39509
39772
  });
39510
39773
  }
39511
39774
  });
@@ -39516,20 +39779,9 @@ var require_dispatcher = __commonJS({
39516
39779
  "use strict";
39517
39780
  Object.defineProperty(exports2, "__esModule", { value: true });
39518
39781
  exports2.CommandDispatcher = void 0;
39782
+ var deadline_js_1 = require_deadline();
39519
39783
  var types_js_1 = require_types2();
39520
39784
  var MAX_COMMAND_ATTACHMENTS = 6;
39521
- function withDeadline(work, ms) {
39522
- return new Promise((resolve5, reject) => {
39523
- const timer = setTimeout(() => reject(new Error(`the app took too long (${ms}ms)`)), ms);
39524
- Promise.resolve(work).then((value) => {
39525
- clearTimeout(timer);
39526
- resolve5(value);
39527
- }, (error) => {
39528
- clearTimeout(timer);
39529
- reject(error);
39530
- });
39531
- });
39532
- }
39533
39785
  function parseCommand(event) {
39534
39786
  const data = event.data;
39535
39787
  const commandId = data.command_id;
@@ -39571,7 +39823,8 @@ var require_dispatcher = __commonJS({
39571
39823
  let verdict;
39572
39824
  let afterAck;
39573
39825
  try {
39574
- const outcome = await withDeadline(this.apply(command), this.deps.verbDeadlineMs ?? 3e4);
39826
+ const verbDeadlineMs = this.deps.verbDeadlineMs ?? 3e4;
39827
+ const outcome = await (0, deadline_js_1.withDeadline)(this.apply(command), verbDeadlineMs, () => new Error(`the app took too long (${verbDeadlineMs}ms)`));
39575
39828
  verdict = outcome.verdict;
39576
39829
  afterAck = outcome.afterAck;
39577
39830
  } catch (error) {
@@ -39801,17 +40054,111 @@ var require_flushGate = __commonJS({
39801
40054
  }
39802
40055
  });
39803
40056
 
40057
+ // ../packages/orion-client-core/dist/remoteControl/livePartial.js
40058
+ var require_livePartial = __commonJS({
40059
+ "../packages/orion-client-core/dist/remoteControl/livePartial.js"(exports2) {
40060
+ "use strict";
40061
+ Object.defineProperty(exports2, "__esModule", { value: true });
40062
+ exports2.LivePartialTracker = exports2.LIVE_PARTIAL_MAX_CHARS = void 0;
40063
+ exports2.decideBackfillTail = decideBackfillTail;
40064
+ var types_js_1 = require_types2();
40065
+ exports2.LIVE_PARTIAL_MAX_CHARS = 65536;
40066
+ var LivePartialTracker = class {
40067
+ text = "";
40068
+ clipped = false;
40069
+ /** A tool ran since the last delta: the next delta opens a new paragraph, so a
40070
+ * multi-round turn doesn't render as one glued blob. Free under the oracle —
40071
+ * whitespace never affects the match. */
40072
+ pendingBreak = false;
40073
+ observe(event) {
40074
+ if (types_js_1.TURN_TERMINAL_KINDS.has(event.event) || event.event === "turn_started") {
40075
+ this.text = "";
40076
+ this.clipped = false;
40077
+ this.pendingBreak = false;
40078
+ return;
40079
+ }
40080
+ if (event.event === "tool_use_start") {
40081
+ if (this.text !== "")
40082
+ this.pendingBreak = true;
40083
+ return;
40084
+ }
40085
+ if (event.event !== "text_delta")
40086
+ return;
40087
+ const delta = event.data?.delta;
40088
+ if (typeof delta !== "string" || delta === "" || this.clipped)
40089
+ return;
40090
+ const glue = this.pendingBreak && !this.text.endsWith("\n") ? "\n\n" : "";
40091
+ this.pendingBreak = false;
40092
+ const next = this.text + glue + delta;
40093
+ if (next.length > exports2.LIVE_PARTIAL_MAX_CHARS) {
40094
+ this.text = next.slice(0, exports2.LIVE_PARTIAL_MAX_CHARS);
40095
+ this.clipped = true;
40096
+ return;
40097
+ }
40098
+ this.text = next;
40099
+ }
40100
+ snapshot() {
40101
+ return { text: this.text, clipped: this.clipped };
40102
+ }
40103
+ };
40104
+ exports2.LivePartialTracker = LivePartialTracker;
40105
+ function normalized(text) {
40106
+ return text.replace(/\s+/g, "");
40107
+ }
40108
+ function committedTailText(backfill) {
40109
+ for (let i2 = backfill.length - 1; i2 >= 0; i2 -= 1) {
40110
+ const event = backfill[i2];
40111
+ if (event === void 0 || event.event !== "rc_message")
40112
+ continue;
40113
+ if (event.data.backfill_id === void 0)
40114
+ continue;
40115
+ if (event.data.role !== "assistant")
40116
+ continue;
40117
+ return typeof event.data.text === "string" ? event.data.text : null;
40118
+ }
40119
+ return null;
40120
+ }
40121
+ function decideBackfillTail(held, backfill, snapshot) {
40122
+ const terminalIndex = held.findIndex((event) => types_js_1.TURN_TERMINAL_KINDS.has(event.event));
40123
+ const partialText = snapshot.clipped ? (
40124
+ // The hole between the kept head and the deltas that will append is real —
40125
+ // mark it rather than splicing two distant parts of one answer silently.
40126
+ `${snapshot.text}
40127
+ \u2026 (truncated)
40128
+ `
40129
+ ) : snapshot.text;
40130
+ if (terminalIndex >= 0 && !snapshot.clipped) {
40131
+ const gatedText = held.slice(0, terminalIndex).filter((event) => event.event === "text_delta" && typeof event.data.delta === "string").map((event) => event.data.delta).join("");
40132
+ const committed = committedTailText(backfill);
40133
+ const full = normalized(snapshot.text + gatedText);
40134
+ const tail = committed === null ? "" : normalized(committed);
40135
+ if (tail !== "" && full.endsWith(tail)) {
40136
+ return {
40137
+ partialText: null,
40138
+ replay: held.filter((event, index) => index > terminalIndex || event.event.startsWith("rc_"))
40139
+ };
40140
+ }
40141
+ }
40142
+ return {
40143
+ partialText: partialText.trim() === "" ? null : partialText,
40144
+ replay: [...held]
40145
+ };
40146
+ }
40147
+ }
40148
+ });
40149
+
39804
40150
  // ../packages/orion-client-core/dist/remoteControl/mirror.js
39805
40151
  var require_mirror = __commonJS({
39806
40152
  "../packages/orion-client-core/dist/remoteControl/mirror.js"(exports2) {
39807
40153
  "use strict";
39808
40154
  Object.defineProperty(exports2, "__esModule", { value: true });
39809
- exports2.SessionMirror = void 0;
40155
+ exports2.SessionMirror = exports2.UNMIRRORED = void 0;
39810
40156
  var activity_js_1 = require_activity();
39811
40157
  var backfill_js_1 = require_backfill();
39812
40158
  var flushGate_js_1 = require_flushGate();
39813
- var UNMIRRORED = /* @__PURE__ */ new Set(["heartbeat", "client_write", "tool_request"]);
39814
- var TERMINAL_KINDS = /* @__PURE__ */ new Set(["turn_complete", "turn_error"]);
40159
+ var livePartial_js_1 = require_livePartial();
40160
+ var types_js_1 = require_types2();
40161
+ exports2.UNMIRRORED = /* @__PURE__ */ new Set(["heartbeat", "client_write", "tool_request"]);
39815
40162
  function coalesceInto(batch, event) {
39816
40163
  const last = batch[batch.length - 1];
39817
40164
  if (last !== void 0 && (event.event === "text_delta" || event.event === "thinking_delta") && last.event === event.event && typeof last.data.delta === "string" && typeof event.data.delta === "string") {
@@ -39827,6 +40174,10 @@ var require_mirror = __commonJS({
39827
40174
  phase = "dormant";
39828
40175
  batch = [];
39829
40176
  gate = new flushGate_js_1.FlushGate();
40177
+ /** TURN-scoped, deliberately not touched by goDormant/reset: an attach mid-turn
40178
+ * needs the text streamed BEFORE it, and a re-register fence mid-turn must not
40179
+ * cost the tail. Only turn boundaries clear it (inside the tracker). */
40180
+ partial = new livePartial_js_1.LivePartialTracker();
39830
40181
  timer = null;
39831
40182
  chain = Promise.resolve();
39832
40183
  watchingMisses = 0;
@@ -39842,13 +40193,14 @@ var require_mirror = __commonJS({
39842
40193
  * mirrors. Never throws — a mirror can never break a turn. */
39843
40194
  tap(event) {
39844
40195
  try {
40196
+ this.partial.observe(event);
39845
40197
  const line = (0, activity_js_1.summarizeToolEvent)(event, this.deps.workspaceRoot());
39846
40198
  if (line !== null)
39847
40199
  this.activity.push(line);
39848
40200
  if (this.phase === "dormant")
39849
40201
  return;
39850
40202
  const wire = event;
39851
- if (UNMIRRORED.has(wire.event))
40203
+ if (exports2.UNMIRRORED.has(wire.event))
39852
40204
  return;
39853
40205
  if (this.gate.enqueue(wire))
39854
40206
  return;
@@ -39931,6 +40283,7 @@ var require_mirror = __commonJS({
39931
40283
  const generation = this.generation;
39932
40284
  this.phase = "backfilling";
39933
40285
  this.gate.start();
40286
+ const partialSnapshot = this.partial.snapshot();
39934
40287
  this.chain = this.chain.then(async () => {
39935
40288
  if (generation !== this.generation)
39936
40289
  return;
@@ -39939,15 +40292,6 @@ var require_mirror = __commonJS({
39939
40292
  if (generation !== this.generation)
39940
40293
  return;
39941
40294
  const events = (0, backfill_js_1.wireMessagesToBackfill)(this.sessionId, this.deps.newBackfillId(), messages, this.deps.clock() / 1e3, backfill_js_1.BACKFILL_MESSAGE_CAP);
39942
- const ring = this.activity.lines();
39943
- if (ring.length > 0) {
39944
- events.splice(1, 0, {
39945
- event: "rc_activity",
39946
- session_id: this.sessionId,
39947
- timestamp: this.deps.clock() / 1e3,
39948
- data: { lines: ring }
39949
- });
39950
- }
39951
40295
  const prompt = this.deps.livePrompt();
39952
40296
  if (prompt !== null && prompt.trim() !== "" && !tailHasUserText(events, prompt)) {
39953
40297
  events.push({
@@ -39957,6 +40301,15 @@ var require_mirror = __commonJS({
39957
40301
  data: { role: "user", text: prompt }
39958
40302
  });
39959
40303
  }
40304
+ const ring = this.activity.lines();
40305
+ if (ring.length > 0) {
40306
+ events.push({
40307
+ event: "rc_activity",
40308
+ session_id: this.sessionId,
40309
+ timestamp: this.deps.clock() / 1e3,
40310
+ data: { lines: ring }
40311
+ });
40312
+ }
39960
40313
  events.push(...await this.deps.pendingEvents());
39961
40314
  if (generation !== this.generation)
39962
40315
  return;
@@ -39965,9 +40318,19 @@ var require_mirror = __commonJS({
39965
40318
  if (generation !== this.generation)
39966
40319
  return;
39967
40320
  }
40321
+ const held = this.gate.open();
40322
+ const tail = (0, livePartial_js_1.decideBackfillTail)(held, events, partialSnapshot);
39968
40323
  this.phase = "live";
39969
- for (const held of this.gate.open())
39970
- this.enqueueLive(held);
40324
+ if (tail.partialText !== null) {
40325
+ this.enqueueLive({
40326
+ event: "rc_message",
40327
+ session_id: this.sessionId,
40328
+ timestamp: this.deps.clock() / 1e3,
40329
+ data: { role: "assistant", text: tail.partialText, partial: true }
40330
+ });
40331
+ }
40332
+ for (const heldEvent of tail.replay)
40333
+ this.enqueueLive(heldEvent);
39971
40334
  } catch (error) {
39972
40335
  if (generation !== this.generation)
39973
40336
  return;
@@ -39982,7 +40345,7 @@ var require_mirror = __commonJS({
39982
40345
  }
39983
40346
  enqueueLive(event) {
39984
40347
  coalesceInto(this.batch, event);
39985
- const terminal = TERMINAL_KINDS.has(event.event);
40348
+ const terminal = types_js_1.TURN_TERMINAL_KINDS.has(event.event);
39986
40349
  if (terminal || this.batch.length >= this.deps.tuning.batchMax) {
39987
40350
  this.flushNow();
39988
40351
  return;
@@ -40167,6 +40530,7 @@ var require_hostBridge = __commonJS({
40167
40530
  exports2.isFenceRefusal = isFenceRefusal;
40168
40531
  exports2.createRemoteControlHost = createRemoteControlHost2;
40169
40532
  var node_crypto_1 = __require("node:crypto");
40533
+ var deadline_js_1 = require_deadline();
40170
40534
  var dispatcher_js_1 = require_dispatcher();
40171
40535
  var mirror_js_1 = require_mirror();
40172
40536
  var rcSettings_js_1 = require_rcSettings();
@@ -40237,17 +40601,31 @@ var require_hostBridge = __commonJS({
40237
40601
  async function publishBatch(sessionId, events) {
40238
40602
  if (epoch === null)
40239
40603
  throw new Error("not registered");
40240
- const { status: httpStatus, body: body2 } = await deps2.bridge.postJson("/rc/v1/publish", {
40241
- host_id: hostId,
40242
- epoch,
40243
- session_id: sessionId,
40244
- events
40245
- });
40246
- if (httpStatus === 200)
40604
+ const usedEpoch = epoch;
40605
+ let deadlined = false;
40606
+ let response;
40607
+ try {
40608
+ response = await (0, deadline_js_1.withDeadline)(deps2.bridge.postJson("/rc/v1/publish", {
40609
+ host_id: hostId,
40610
+ epoch: usedEpoch,
40611
+ session_id: sessionId,
40612
+ events
40613
+ }), tuning.publishDeadlineMs, () => {
40614
+ deadlined = true;
40615
+ return new Error(`rc publish deadline (${tuning.publishDeadlineMs}ms)`);
40616
+ });
40617
+ } catch (error) {
40618
+ if (deadlined)
40619
+ scheduleReregister("publish_deadline");
40620
+ throw error;
40621
+ }
40622
+ if (response.status === 200)
40247
40623
  return;
40248
- const reason = typeof body2 === "object" && body2 !== null ? String(body2.reason ?? httpStatus) : String(httpStatus);
40249
- if (httpStatus === 409 || isFenceRefusal(reason)) {
40250
- scheduleReregister(`publish_${reason}`);
40624
+ const body2 = response.body;
40625
+ const reason = typeof body2 === "object" && body2 !== null ? String(body2.reason ?? response.status) : String(response.status);
40626
+ if (response.status === 409 || isFenceRefusal(reason)) {
40627
+ if (usedEpoch === epoch)
40628
+ scheduleReregister(`publish_${reason}`);
40251
40629
  }
40252
40630
  throw new Error(`rc publish refused: ${reason}`);
40253
40631
  }
@@ -40274,7 +40652,9 @@ var require_hostBridge = __commonJS({
40274
40652
  adapter: deps2.adapter,
40275
40653
  // The relay-shelf fetch for attachment commands. Auth rides the SAME bridge as
40276
40654
  // everything else (per-instance closures, proactive refresh); a non-200 answer is
40277
- // `null`, which the dispatcher turns into a whole-command refusal.
40655
+ // `null`, which the dispatcher turns into a whole-command refusal. Deliberately
40656
+ // NOT deadlined here: a hung fetch strands only its own command's handler (the
40657
+ // dispatcher's verb deadline answers the phone), never the mirror chain.
40278
40658
  fetchAttachment: async (attachmentId) => {
40279
40659
  const { status: status2, body: body2 } = await deps2.bridge.getJson(`/rc/v1/attachment/${encodeURIComponent(attachmentId)}`);
40280
40660
  if (status2 !== 200 || typeof body2 !== "object" || body2 === null)
@@ -40379,16 +40759,7 @@ var require_hostBridge = __commonJS({
40379
40759
  void registerCycle();
40380
40760
  }
40381
40761
  function beatRpc(method, params) {
40382
- return new Promise((resolve5, reject) => {
40383
- const timer = setTimeout(() => reject(new Error(`${method} deadline (${tuning.rpcDeadlineMs}ms)`)), tuning.rpcDeadlineMs);
40384
- deps2.bridge.rpc(method, params).then((value) => {
40385
- clearTimeout(timer);
40386
- resolve5(value);
40387
- }, (error) => {
40388
- clearTimeout(timer);
40389
- reject(error);
40390
- });
40391
- });
40762
+ return (0, deadline_js_1.withDeadline)(deps2.bridge.rpc(method, params), tuning.rpcDeadlineMs, () => new Error(`${method} deadline (${tuning.rpcDeadlineMs}ms)`));
40392
40763
  }
40393
40764
  async function registerCycle() {
40394
40765
  if (registerInFlight !== null)
@@ -65176,6 +65547,8 @@ var require_dist = __commonJS({
65176
65547
  __exportStar(require_eventCoverage(), exports2);
65177
65548
  __exportStar(require_toolConcurrency(), exports2);
65178
65549
  __exportStar(require_outcomeReporter(), exports2);
65550
+ __exportStar(require_feedbackScrub(), exports2);
65551
+ __exportStar(require_feedbackSubmit(), exports2);
65179
65552
  __exportStar(require_indexResultLinks(), exports2);
65180
65553
  __exportStar(require_orionSnapshot(), exports2);
65181
65554
  __exportStar(require_wikiBundle(), exports2);
@@ -65425,6 +65798,89 @@ var require_interruptedTurn = __commonJS({
65425
65798
  }
65426
65799
  });
65427
65800
 
65801
+ // ../packages/orion-client-ui-core/dist/toolLabel.js
65802
+ var require_toolLabel = __commonJS({
65803
+ "../packages/orion-client-ui-core/dist/toolLabel.js"(exports2) {
65804
+ "use strict";
65805
+ Object.defineProperty(exports2, "__esModule", { value: true });
65806
+ exports2.toolDisplayName = toolDisplayName6;
65807
+ var TOOL_WORDS = {
65808
+ lsp: "LSP",
65809
+ mcp: "MCP",
65810
+ ovault: "O-Vault",
65811
+ oauth: "OAuth",
65812
+ powershell: "PowerShell",
65813
+ goto: "Go to",
65814
+ dir: "Directory",
65815
+ url: "URL",
65816
+ api: "API",
65817
+ ide: "IDE",
65818
+ cli: "CLI",
65819
+ db: "DB",
65820
+ sql: "SQL",
65821
+ github: "GitHub",
65822
+ gitlab: "GitLab",
65823
+ aws: "AWS",
65824
+ gcp: "GCP"
65825
+ };
65826
+ var SMALL_WORDS = /* @__PURE__ */ new Set([
65827
+ "a",
65828
+ "an",
65829
+ "and",
65830
+ "at",
65831
+ "by",
65832
+ "for",
65833
+ "in",
65834
+ "of",
65835
+ "on",
65836
+ "or",
65837
+ "the",
65838
+ "to",
65839
+ "vs",
65840
+ "with"
65841
+ ]);
65842
+ var MCP_PREFIX = "mcp__";
65843
+ function titleToken(token, first) {
65844
+ if (token.length === 0)
65845
+ return token;
65846
+ const lower = token.toLowerCase();
65847
+ const known = TOOL_WORDS[lower];
65848
+ if (known)
65849
+ return known;
65850
+ if (token.includes("-")) {
65851
+ return token.split("-").map((part) => part.length > 0 ? titleToken(part, first) : part).join("-");
65852
+ }
65853
+ if (!first && SMALL_WORDS.has(lower))
65854
+ return lower;
65855
+ return token.charAt(0).toUpperCase() + token.slice(1);
65856
+ }
65857
+ function titleCase(raw) {
65858
+ const tokens = raw.split(/[\s_]+/).filter((t) => t.length > 0);
65859
+ if (tokens.length === 0)
65860
+ return "";
65861
+ return tokens.map((t, i2) => titleToken(t, i2 === 0)).join(" ");
65862
+ }
65863
+ function toolDisplayName6(name2) {
65864
+ if (typeof name2 !== "string")
65865
+ return "";
65866
+ const raw = name2.trim();
65867
+ if (raw.length === 0)
65868
+ return name2;
65869
+ if (raw.toLowerCase().startsWith(MCP_PREFIX)) {
65870
+ const parts2 = raw.slice(MCP_PREFIX.length).split("__").filter((p) => p.length > 0);
65871
+ const words = (segment) => titleCase(segment.replace(/-+/g, "_"));
65872
+ if (parts2.length >= 2) {
65873
+ return `${words(parts2[0])}: ${words(parts2.slice(1).join("_"))}`;
65874
+ }
65875
+ if (parts2.length === 1)
65876
+ return words(parts2[0]);
65877
+ return raw;
65878
+ }
65879
+ return titleCase(raw) || raw;
65880
+ }
65881
+ }
65882
+ });
65883
+
65428
65884
  // ../packages/orion-client-ui-core/dist/permissionCard.js
65429
65885
  var require_permissionCard = __commonJS({
65430
65886
  "../packages/orion-client-ui-core/dist/permissionCard.js"(exports2) {
@@ -65435,6 +65891,7 @@ var require_permissionCard = __commonJS({
65435
65891
  exports2.editDiffLines = editDiffLines2;
65436
65892
  exports2.resolveCardChoice = resolveCardChoice2;
65437
65893
  var client_core_1 = require_dist();
65894
+ var toolLabel_1 = require_toolLabel();
65438
65895
  exports2.TURBO_CONFIRM_MESSAGE = "Enable Turbo mode for this user? Every tool call \u2014 protected paths included \u2014 is auto-approved in every project until you turn it off.";
65439
65896
  exports2.DESTINATIONS = [
65440
65897
  { source: "local", label: "This project (local)" },
@@ -65506,7 +65963,7 @@ var require_permissionCard = __commonJS({
65506
65963
  header = { verb: "Fetch", subject: urlHost(url) };
65507
65964
  body2 = { kind: "fetch", url };
65508
65965
  } else {
65509
- header = { verb: "Use", subject: tool };
65966
+ header = { verb: "Use", subject: (0, toolLabel_1.toolDisplayName)(tool) };
65510
65967
  body2 = { kind: "tool", toolName: tool, inputPreview: inputPreview(input) };
65511
65968
  }
65512
65969
  const suggestions = req.suggestions ?? [];
@@ -65776,6 +66233,225 @@ var require_planCard = __commonJS({
65776
66233
  }
65777
66234
  });
65778
66235
 
66236
+ // ../packages/orion-client-ui-core/dist/feedbackCard.js
66237
+ var require_feedbackCard = __commonJS({
66238
+ "../packages/orion-client-ui-core/dist/feedbackCard.js"(exports2) {
66239
+ "use strict";
66240
+ Object.defineProperty(exports2, "__esModule", { value: true });
66241
+ exports2.FEEDBACK_WORDING = exports2.FEEDBACK_WHY_MAX_CHARS = exports2.FEEDBACK_SCHEMA_VERSION = void 0;
66242
+ exports2.feedbackWhyLabel = feedbackWhyLabel2;
66243
+ exports2.createFeedbackCard = createFeedbackCard2;
66244
+ exports2.feedbackSelectScore = feedbackSelectScore2;
66245
+ exports2.feedbackSetWhy = feedbackSetWhy2;
66246
+ exports2.feedbackBackToScore = feedbackBackToScore;
66247
+ exports2.isFeedbackReady = isFeedbackReady;
66248
+ exports2.buildFeedbackSubmission = buildFeedbackSubmission2;
66249
+ exports2.FEEDBACK_SCHEMA_VERSION = 1;
66250
+ exports2.FEEDBACK_WHY_MAX_CHARS = 2e3;
66251
+ exports2.FEEDBACK_WORDING = {
66252
+ title: "How is Orion doing?",
66253
+ scoreHint: "1 = poor, 5 = excellent",
66254
+ whyLabel: "What made it a {score}?",
66255
+ whyPlaceholder: "Optional \u2014 a sentence helps",
66256
+ submit: "Send",
66257
+ dismiss: "Dismiss",
66258
+ settledThanks: "Thanks \u2014 feedback sent.",
66259
+ /** The TUI's dim transcript note after a submission. */
66260
+ transcriptNote: "Feedback sent - thank you."
66261
+ };
66262
+ function feedbackWhyLabel2(score) {
66263
+ return exports2.FEEDBACK_WORDING.whyLabel.replace("{score}", String(score));
66264
+ }
66265
+ function createFeedbackCard2() {
66266
+ return { score: 0, why: "", stage: "score" };
66267
+ }
66268
+ function feedbackSelectScore2(state, score) {
66269
+ if (!Number.isInteger(score) || score < 1 || score > 5)
66270
+ return state;
66271
+ return { ...state, score, stage: "why" };
66272
+ }
66273
+ function feedbackSetWhy2(state, why) {
66274
+ return { ...state, why: typeof why === "string" ? why : "" };
66275
+ }
66276
+ function feedbackBackToScore(state) {
66277
+ return { ...state, stage: "score" };
66278
+ }
66279
+ function isFeedbackReady(state) {
66280
+ return Number.isInteger(state.score) && state.score >= 1 && state.score <= 5;
66281
+ }
66282
+ function buildFeedbackSubmission2(state, meta) {
66283
+ const why = state.why.trim().slice(0, exports2.FEEDBACK_WHY_MAX_CHARS);
66284
+ return {
66285
+ schema: exports2.FEEDBACK_SCHEMA_VERSION,
66286
+ type: "submission",
66287
+ submission_id: meta.submissionId,
66288
+ score: state.score,
66289
+ ...why ? { why } : {},
66290
+ shown_because: "prompted",
66291
+ session_id: meta.sessionId,
66292
+ ...meta.turnId ? { turn_id: meta.turnId } : {},
66293
+ client: meta.client,
66294
+ client_version: meta.clientVersion,
66295
+ ...meta.model ? { model: meta.model } : {},
66296
+ ...meta.provider ? { provider: meta.provider } : {}
66297
+ };
66298
+ }
66299
+ }
66300
+ });
66301
+
66302
+ // ../packages/orion-client-ui-core/dist/feedbackPolicy.js
66303
+ var require_feedbackPolicy = __commonJS({
66304
+ "../packages/orion-client-ui-core/dist/feedbackPolicy.js"(exports2) {
66305
+ "use strict";
66306
+ Object.defineProperty(exports2, "__esModule", { value: true });
66307
+ exports2.FEEDBACK_SAMPLE_RATE = exports2.FEEDBACK_JITTER_MAX_DAYS = exports2.FEEDBACK_STOP_AFTER_DISMISSALS = exports2.FEEDBACK_IGNORED_RETRY_MAX_DAYS = exports2.FEEDBACK_IGNORED_RETRY_MIN_DAYS = exports2.FEEDBACK_COOLDOWN_AFTER_DISMISS_DAYS = exports2.FEEDBACK_COOLDOWN_AFTER_SUBMIT_DAYS = exports2.FEEDBACK_MIN_TURNS_PER_SESSION = exports2.FEEDBACK_MIN_INSTALL_AGE_DAYS = void 0;
66308
+ exports2.feedbackDaysBetween = feedbackDaysBetween;
66309
+ exports2.feedbackJitterDays = feedbackJitterDays;
66310
+ exports2.feedbackIgnoredRetryDays = feedbackIgnoredRetryDays;
66311
+ exports2.emptyFeedbackPolicyState = emptyFeedbackPolicyState;
66312
+ exports2.normalizeFeedbackPolicyState = normalizeFeedbackPolicyState;
66313
+ exports2.shouldOfferFeedback = shouldOfferFeedback2;
66314
+ exports2.feedbackStateFromScalars = feedbackStateFromScalars2;
66315
+ exports2.feedbackScalarsFromState = feedbackScalarsFromState2;
66316
+ exports2.mintFeedbackSeed = mintFeedbackSeed2;
66317
+ exports2.applyFeedbackShown = applyFeedbackShown2;
66318
+ exports2.applyFeedbackSubmitted = applyFeedbackSubmitted2;
66319
+ exports2.applyFeedbackDismissed = applyFeedbackDismissed2;
66320
+ exports2.FEEDBACK_MIN_INSTALL_AGE_DAYS = 7;
66321
+ exports2.FEEDBACK_MIN_TURNS_PER_SESSION = 5;
66322
+ exports2.FEEDBACK_COOLDOWN_AFTER_SUBMIT_DAYS = 90;
66323
+ exports2.FEEDBACK_COOLDOWN_AFTER_DISMISS_DAYS = 60;
66324
+ exports2.FEEDBACK_IGNORED_RETRY_MIN_DAYS = 4;
66325
+ exports2.FEEDBACK_IGNORED_RETRY_MAX_DAYS = 7;
66326
+ exports2.FEEDBACK_STOP_AFTER_DISMISSALS = 2;
66327
+ exports2.FEEDBACK_JITTER_MAX_DAYS = 4;
66328
+ exports2.FEEDBACK_SAMPLE_RATE = 1;
66329
+ var DAY_MS = 864e5;
66330
+ function feedbackDaysBetween(earlier, later) {
66331
+ if (!Number.isFinite(earlier) || !Number.isFinite(later))
66332
+ return 0;
66333
+ return Math.max(0, Math.floor((later - earlier) / DAY_MS));
66334
+ }
66335
+ function feedbackMix32(seed, salt) {
66336
+ const basis = Number.isFinite(seed) ? Math.abs(Math.trunc(seed)) : 0;
66337
+ const s = Number.isFinite(salt) ? Math.trunc(salt) : 0;
66338
+ let h = basis + Math.imul(s >>> 0, 2654435761) >>> 0;
66339
+ h ^= h >>> 16;
66340
+ h = Math.imul(h, 2246822519) >>> 0;
66341
+ return h;
66342
+ }
66343
+ function feedbackJitterDays(seed, salt) {
66344
+ return feedbackMix32(seed, salt) % (exports2.FEEDBACK_JITTER_MAX_DAYS + 1);
66345
+ }
66346
+ function feedbackIgnoredRetryDays(seed, lastShownAt) {
66347
+ const span = exports2.FEEDBACK_IGNORED_RETRY_MAX_DAYS - exports2.FEEDBACK_IGNORED_RETRY_MIN_DAYS + 1;
66348
+ return exports2.FEEDBACK_IGNORED_RETRY_MIN_DAYS + feedbackMix32(seed, lastShownAt) % span;
66349
+ }
66350
+ function emptyFeedbackPolicyState(now2, seed) {
66351
+ return {
66352
+ firstSeenAt: now2,
66353
+ lastShownAt: 0,
66354
+ lastOutcome: "",
66355
+ dismissStreak: 0,
66356
+ stopped: false,
66357
+ seed: Number.isFinite(seed) ? seed : 0
66358
+ };
66359
+ }
66360
+ function normalizeFeedbackPolicyState(raw, now2, seedFallback) {
66361
+ if (typeof raw !== "object" || raw === null) {
66362
+ return emptyFeedbackPolicyState(now2, seedFallback);
66363
+ }
66364
+ const r2 = raw;
66365
+ const num = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
66366
+ const outcome = r2.lastOutcome === "submitted" || r2.lastOutcome === "dismissed" ? r2.lastOutcome : "";
66367
+ return {
66368
+ firstSeenAt: num(r2.firstSeenAt, now2) || now2,
66369
+ lastShownAt: num(r2.lastShownAt, 0),
66370
+ lastOutcome: outcome,
66371
+ dismissStreak: Math.min(exports2.FEEDBACK_STOP_AFTER_DISMISSALS, Math.trunc(num(r2.dismissStreak, 0))),
66372
+ stopped: r2.stopped === true,
66373
+ seed: typeof r2.seed === "number" && Number.isFinite(r2.seed) ? r2.seed : Number.isFinite(seedFallback) ? seedFallback : 0
66374
+ };
66375
+ }
66376
+ function cooldownDaysFor(outcome) {
66377
+ return outcome === "submitted" ? exports2.FEEDBACK_COOLDOWN_AFTER_SUBMIT_DAYS : exports2.FEEDBACK_COOLDOWN_AFTER_DISMISS_DAYS;
66378
+ }
66379
+ function sampledIn(seed) {
66380
+ if (exports2.FEEDBACK_SAMPLE_RATE >= 1)
66381
+ return true;
66382
+ return feedbackJitterDays(seed, 97) / (exports2.FEEDBACK_JITTER_MAX_DAYS + 1) < exports2.FEEDBACK_SAMPLE_RATE;
66383
+ }
66384
+ function shouldOfferFeedback2(state, ctx) {
66385
+ if (!ctx.turnCompletedCleanly || ctx.blockingCardOpen || !ctx.attended || !ctx.signedIn) {
66386
+ return false;
66387
+ }
66388
+ if (ctx.forced === true)
66389
+ return true;
66390
+ if (state.stopped)
66391
+ return false;
66392
+ if (ctx.completedTurnsThisSession < exports2.FEEDBACK_MIN_TURNS_PER_SESSION)
66393
+ return false;
66394
+ if (!sampledIn(state.seed))
66395
+ return false;
66396
+ const age = feedbackDaysBetween(state.firstSeenAt, ctx.now);
66397
+ if (age < exports2.FEEDBACK_MIN_INSTALL_AGE_DAYS + feedbackJitterDays(state.seed, 1)) {
66398
+ return false;
66399
+ }
66400
+ if (state.lastShownAt > 0) {
66401
+ const rested = feedbackDaysBetween(state.lastShownAt, ctx.now);
66402
+ const needed = state.lastOutcome === "" ? feedbackIgnoredRetryDays(state.seed, state.lastShownAt) : cooldownDaysFor(state.lastOutcome) + feedbackJitterDays(state.seed, 2);
66403
+ if (rested < needed)
66404
+ return false;
66405
+ }
66406
+ return true;
66407
+ }
66408
+ function feedbackStateFromScalars2(scalars, now2) {
66409
+ return normalizeFeedbackPolicyState({
66410
+ firstSeenAt: scalars.feedbackFirstSeenAt,
66411
+ lastShownAt: scalars.feedbackLastShownAt,
66412
+ lastOutcome: scalars.feedbackLastOutcome,
66413
+ dismissStreak: scalars.feedbackDismissStreak,
66414
+ stopped: scalars.feedbackStopped,
66415
+ seed: scalars.feedbackSeed
66416
+ }, now2, 1);
66417
+ }
66418
+ function feedbackScalarsFromState2(state) {
66419
+ return {
66420
+ feedbackFirstSeenAt: state.firstSeenAt,
66421
+ feedbackLastShownAt: state.lastShownAt,
66422
+ feedbackLastOutcome: state.lastOutcome,
66423
+ feedbackDismissStreak: state.dismissStreak,
66424
+ feedbackStopped: state.stopped,
66425
+ feedbackSeed: state.seed
66426
+ };
66427
+ }
66428
+ function mintFeedbackSeed2(random = Math.random) {
66429
+ return 1 + Math.floor(random() * (2 ** 31 - 1));
66430
+ }
66431
+ function applyFeedbackShown2(state, now2) {
66432
+ return { ...state, lastShownAt: now2, lastOutcome: "" };
66433
+ }
66434
+ function applyFeedbackSubmitted2(state, now2) {
66435
+ return {
66436
+ ...state,
66437
+ lastShownAt: state.lastShownAt || now2,
66438
+ lastOutcome: "submitted",
66439
+ dismissStreak: 0
66440
+ };
66441
+ }
66442
+ function applyFeedbackDismissed2(state, now2) {
66443
+ const streak = state.dismissStreak + 1;
66444
+ return {
66445
+ ...state,
66446
+ lastShownAt: state.lastShownAt || now2,
66447
+ lastOutcome: "dismissed",
66448
+ dismissStreak: streak,
66449
+ stopped: state.stopped || streak >= exports2.FEEDBACK_STOP_AFTER_DISMISSALS
66450
+ };
66451
+ }
66452
+ }
66453
+ });
66454
+
65779
66455
  // ../packages/orion-client-ui-core/dist/modelLabel.js
65780
66456
  var require_modelLabel = __commonJS({
65781
66457
  "../packages/orion-client-ui-core/dist/modelLabel.js"(exports2) {
@@ -65812,6 +66488,24 @@ var require_modelLabel = __commonJS({
65812
66488
  }
65813
66489
  });
65814
66490
 
66491
+ // ../packages/orion-client-ui-core/dist/toolVisibility.js
66492
+ var require_toolVisibility = __commonJS({
66493
+ "../packages/orion-client-ui-core/dist/toolVisibility.js"(exports2) {
66494
+ "use strict";
66495
+ Object.defineProperty(exports2, "__esModule", { value: true });
66496
+ exports2.SILENT_TOOLS = void 0;
66497
+ exports2.isSilentTool = isSilentTool3;
66498
+ exports2.SILENT_TOOLS = /* @__PURE__ */ new Set([
66499
+ "ask_user",
66500
+ "exit_plan_mode",
66501
+ "await_agents"
66502
+ ]);
66503
+ function isSilentTool3(name2) {
66504
+ return typeof name2 === "string" && exports2.SILENT_TOOLS.has(name2);
66505
+ }
66506
+ }
66507
+ });
66508
+
65815
66509
  // ../packages/orion-client-ui-core/dist/subagentRow.js
65816
66510
  var require_subagentRow = __commonJS({
65817
66511
  "../packages/orion-client-ui-core/dist/subagentRow.js"(exports2) {
@@ -65873,7 +66567,11 @@ var require_dist2 = __commonJS({
65873
66567
  __exportStar(require_permissionCard(), exports2);
65874
66568
  __exportStar(require_askCard(), exports2);
65875
66569
  __exportStar(require_planCard(), exports2);
66570
+ __exportStar(require_feedbackCard(), exports2);
66571
+ __exportStar(require_feedbackPolicy(), exports2);
65876
66572
  __exportStar(require_modelLabel(), exports2);
66573
+ __exportStar(require_toolLabel(), exports2);
66574
+ __exportStar(require_toolVisibility(), exports2);
65877
66575
  __exportStar(require_subagentRow(), exports2);
65878
66576
  var client_core_1 = require_dist();
65879
66577
  Object.defineProperty(exports2, "parseTrust", { enumerable: true, get: function() {
@@ -81436,11 +82134,11 @@ var Box2 = Box_default;
81436
82134
  var ScrollBox2 = ScrollBox_default;
81437
82135
 
81438
82136
  // src/main.tsx
81439
- var import_client_core38 = __toESM(require_dist(), 1);
81440
82137
  var import_client_core39 = __toESM(require_dist(), 1);
82138
+ var import_client_core40 = __toESM(require_dist(), 1);
81441
82139
  import { fileURLToPath as fileURLToPath3 } from "url";
81442
82140
  import * as os7 from "os";
81443
- import { randomUUID as randomUUID2 } from "crypto";
82141
+ import { randomUUID as randomUUID3 } from "crypto";
81444
82142
 
81445
82143
  // src/services/importOffer.ts
81446
82144
  var import_client_core = __toESM(require_dist(), 1);
@@ -82145,7 +82843,13 @@ function defaults() {
82145
82843
  brainPath: process.env.ORION_BRAIN_PATH ?? "",
82146
82844
  brainTopology: (0, import_client_core6.normalizeBrainTopology)(process.env.ORION_BRAIN_TOPOLOGY, "process"),
82147
82845
  bell: process.env.ORION_BELL === "1",
82148
- bellThresholdMs: Number(process.env.ORION_BELL_THRESHOLD_MS) || 1e4
82846
+ bellThresholdMs: Number(process.env.ORION_BELL_THRESHOLD_MS) || 1e4,
82847
+ feedbackFirstSeenAt: 0,
82848
+ feedbackLastShownAt: 0,
82849
+ feedbackLastOutcome: "",
82850
+ feedbackDismissStreak: 0,
82851
+ feedbackStopped: false,
82852
+ feedbackSeed: 0
82149
82853
  };
82150
82854
  }
82151
82855
  var FILE_OVERRIDABLE = [
@@ -82169,7 +82873,13 @@ var FILE_OVERRIDABLE = [
82169
82873
  "brainPath",
82170
82874
  "brainTopology",
82171
82875
  "bell",
82172
- "bellThresholdMs"
82876
+ "bellThresholdMs",
82877
+ "feedbackFirstSeenAt",
82878
+ "feedbackLastShownAt",
82879
+ "feedbackLastOutcome",
82880
+ "feedbackDismissStreak",
82881
+ "feedbackStopped",
82882
+ "feedbackSeed"
82173
82883
  ];
82174
82884
  function loadConfig() {
82175
82885
  const base = defaults();
@@ -82722,9 +83432,10 @@ function createStore(initial, onChange) {
82722
83432
  }
82723
83433
 
82724
83434
  // src/state/transcriptStore.ts
82725
- var import_client_ui_core = __toESM(require_dist2(), 1);
83435
+ var import_client_ui_core2 = __toESM(require_dist2(), 1);
82726
83436
 
82727
83437
  // src/types/message.ts
83438
+ var import_client_ui_core = __toESM(require_dist2(), 1);
82728
83439
  function groupToolRuns(items) {
82729
83440
  const out2 = [];
82730
83441
  let run3 = [];
@@ -82815,6 +83526,7 @@ function projectMessages(messages) {
82815
83526
  if (b2.type === "text" && typeof b2.text === "string" && b2.text.length > 0) {
82816
83527
  out2.push({ kind: role === "user" ? "user" : "assistant", id: `m${n++}`, text: b2.text });
82817
83528
  } else if (b2.type === "tool_use" && typeof b2.name === "string") {
83529
+ if ((0, import_client_ui_core.isSilentTool)(b2.name)) continue;
82818
83530
  const id = typeof b2.id === "string" ? b2.id : "";
82819
83531
  out2.push({
82820
83532
  kind: "tool",
@@ -82846,7 +83558,7 @@ function initialTranscript() {
82846
83558
  return {
82847
83559
  sessionId: null,
82848
83560
  messages: [],
82849
- clientState: (0, import_client_ui_core.emptyClientState)(),
83561
+ clientState: (0, import_client_ui_core2.emptyClientState)(),
82850
83562
  settled: [],
82851
83563
  committedCount: 0,
82852
83564
  evictedCount: 0,
@@ -83037,7 +83749,7 @@ function applyTurnComplete(s, data) {
83037
83749
  const flushed = flushLive(s);
83038
83750
  const messages = Array.isArray(data.messages) ? data.messages : flushed.messages;
83039
83751
  const clientState = { ...flushed.clientState, total_usage: { ...flushed.clientState.total_usage } };
83040
- (0, import_client_ui_core.mergeTurnComplete)(clientState, data);
83752
+ (0, import_client_ui_core2.mergeTurnComplete)(clientState, data);
83041
83753
  return {
83042
83754
  ...flushed,
83043
83755
  messages,
@@ -83057,7 +83769,7 @@ function applyTurnInterrupted(s, prompt, partialReply = "") {
83057
83769
  const flushed = flushLive(s);
83058
83770
  return {
83059
83771
  ...flushed,
83060
- messages: (0, import_client_ui_core.interruptedTurnMessages)(flushed.messages, prompt, partial),
83772
+ messages: (0, import_client_ui_core2.interruptedTurnMessages)(flushed.messages, prompt, partial),
83061
83773
  committedCount: flushed.settled.length,
83062
83774
  live: null
83063
83775
  };
@@ -83068,7 +83780,7 @@ function hydrate(sessionId, messages, clientState) {
83068
83780
  return {
83069
83781
  sessionId,
83070
83782
  messages: msgs,
83071
- clientState: (0, import_client_ui_core.reviveClientState)(clientState),
83783
+ clientState: (0, import_client_ui_core2.reviveClientState)(clientState),
83072
83784
  settled,
83073
83785
  committedCount: settled.length,
83074
83786
  // resumed history is all committed
@@ -83128,7 +83840,7 @@ function clearHistory(s) {
83128
83840
  return {
83129
83841
  ...s,
83130
83842
  messages: [],
83131
- clientState: (0, import_client_ui_core.emptyClientState)(),
83843
+ clientState: (0, import_client_ui_core2.emptyClientState)(),
83132
83844
  settled: [],
83133
83845
  committedCount: 0,
83134
83846
  evictedCount: 0,
@@ -85760,6 +86472,7 @@ function initialAppState(partial) {
85760
86472
  pendingPlanApproval: null,
85761
86473
  pendingAskUser: null,
85762
86474
  pendingWorkPlan: null,
86475
+ pendingFeedback: null,
85763
86476
  workRun: null,
85764
86477
  plan: null,
85765
86478
  subAgents: [],
@@ -85849,6 +86562,7 @@ function resumedRouting(current2, saved) {
85849
86562
 
85850
86563
  // src/events/renderLane.ts
85851
86564
  var import_client_core19 = __toESM(require_dist(), 1);
86565
+ var import_client_ui_core3 = __toESM(require_dist2(), 1);
85852
86566
 
85853
86567
  // src/services/loadingAnimation.ts
85854
86568
  var LOADING_WORDS = [
@@ -85981,14 +86695,6 @@ var RICH_CARD_TOOLS = /* @__PURE__ */ new Set([
85981
86695
  "edit_file",
85982
86696
  "multi_edit",
85983
86697
  "update_plan",
85984
- // exit_plan_mode is represented by the plan card + the approval prompt, so its
85985
- // raw rail-marked "exit_plan_mode(plan=…)" log line (truncated plan arg) is suppressed.
85986
- "exit_plan_mode",
85987
- // ask_user is represented by the question card, which shows the question and every
85988
- // choice verbatim. A rail-marked "ask_user(questions=…)" line above it would dump the same JSON
85989
- // the card renders properly — and would linger in the transcript after the card is gone,
85990
- // reading as a question the user was never actually asked.
85991
- "ask_user",
85992
86698
  // work_plan_submit is represented by the work-graph approval card, which shows
85993
86699
  // every phase and every gate command — a log line above it says it twice (and
85994
86700
  // would dump a truncated plan blob).
@@ -86055,7 +86761,9 @@ function renderLane(transcript, app, ev) {
86055
86761
  break;
86056
86762
  case "tool_use_start": {
86057
86763
  const name2 = typeof d2.name === "string" ? d2.name : "tool";
86058
- if (!RICH_CARD_TOOLS.has(name2)) transcript.setState((s) => startTool(s, name2, d2.input));
86764
+ if (!RICH_CARD_TOOLS.has(name2) && !(0, import_client_ui_core3.isSilentTool)(name2)) {
86765
+ transcript.setState((s) => startTool(s, name2, d2.input));
86766
+ }
86059
86767
  break;
86060
86768
  }
86061
86769
  case "tool_use_end": {
@@ -86322,7 +87030,7 @@ function settleSteerQueue(outcome, deps2) {
86322
87030
 
86323
87031
  // src/events/boundaryHandlers.ts
86324
87032
  var import_client_core21 = __toESM(require_dist(), 1);
86325
- var import_client_ui_core2 = __toESM(require_dist2(), 1);
87033
+ var import_client_ui_core4 = __toESM(require_dist2(), 1);
86326
87034
  function createBoundaryHandlers(deps2) {
86327
87035
  const {
86328
87036
  bridge,
@@ -86400,10 +87108,10 @@ function createBoundaryHandlers(deps2) {
86400
87108
  },
86401
87109
  onPlanApproval: (req) => {
86402
87110
  if (deps2.planningRunActive?.(sid)) {
86403
- return Promise.resolve((0, import_client_ui_core2.planDeferredForGraph)());
87111
+ return Promise.resolve((0, import_client_ui_core4.planDeferredForGraph)());
86404
87112
  }
86405
87113
  if (deps2.agentsRunning?.(sid)) {
86406
- return Promise.resolve((0, import_client_ui_core2.planDeferredForAgents)());
87114
+ return Promise.resolve((0, import_client_ui_core4.planDeferredForAgents)());
86407
87115
  }
86408
87116
  const plan = typeof req.plan === "string" ? req.plan : "";
86409
87117
  appStore.setState((s) => ({
@@ -86459,7 +87167,7 @@ function createBoundaryHandlers(deps2) {
86459
87167
  permissionResolvers.delete(requestId);
86460
87168
  const pending = appStore.getState().pendingPermissions.find((p) => p.data.request_id === requestId);
86461
87169
  const ctx = { workspaceRoot, homeDir };
86462
- const resolved = (0, import_client_ui_core2.resolveCardChoice)(
87170
+ const resolved = (0, import_client_ui_core4.resolveCardChoice)(
86463
87171
  outcome.kind === "allow" ? { kind: "allow" } : outcome,
86464
87172
  ctx
86465
87173
  );
@@ -86730,7 +87438,7 @@ var WorkPlanApprovalBridge = class {
86730
87438
  };
86731
87439
 
86732
87440
  // src/main.tsx
86733
- var import_client_ui_core10 = __toESM(require_dist2(), 1);
87441
+ var import_client_ui_core19 = __toESM(require_dist2(), 1);
86734
87442
 
86735
87443
  // src/components/layout/Transcript.tsx
86736
87444
  var import_react27 = __toESM(require_react(), 1);
@@ -102215,6 +102923,9 @@ function Note({
102215
102923
  }) });
102216
102924
  }
102217
102925
 
102926
+ // src/components/tools/ToolLogLine.tsx
102927
+ var import_client_ui_core5 = __toESM(require_dist2(), 1);
102928
+
102218
102929
  // src/components/tools/ResultRow.tsx
102219
102930
  var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
102220
102931
  function ResultRow({ children }) {
@@ -102254,7 +102965,7 @@ function ToolLogLine({
102254
102965
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
102255
102966
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Box2, { flexDirection: "row", children: [
102256
102967
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Box2, { minWidth: 2, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThemedText, { colorKey: toolMarkerColorKey(status), children: glyphs.tool }) }),
102257
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: name2 }) }),
102968
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: (0, import_client_ui_core5.toolDisplayName)(name2) }) }),
102258
102969
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Box2, { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Text2, { wrap: "wrap", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(ThemedText, { colorKey: "toolArgs", children: [
102259
102970
  "(",
102260
102971
  verbose ? args2 : truncate2(args2, 80),
@@ -102640,6 +103351,7 @@ function DiffCard({
102640
103351
  }
102641
103352
 
102642
103353
  // src/components/tools/TerminalCard.tsx
103354
+ var import_client_ui_core6 = __toESM(require_dist2(), 1);
102643
103355
  var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
102644
103356
  var MAX_LINES = 200;
102645
103357
  var PREVIEW_LINES = 3;
@@ -102675,7 +103387,7 @@ function TerminalCard({
102675
103387
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
102676
103388
  /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Box2, { flexDirection: "row", children: [
102677
103389
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Box2, { minWidth: 2, flexShrink: 0, children: running ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(RunningMarker, {}) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ThemedText, { colorKey: terminalMarkerColorKey(exitCode), children: glyphs.tool }) }),
102678
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: "bash" }) }),
103390
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: (0, import_client_ui_core6.toolDisplayName)("bash") }) }),
102679
103391
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Box2, { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(ThemedText, { colorKey: "toolArgs", wrap: "wrap", children: [
102680
103392
  "(",
102681
103393
  verbose ? command : collapseCommand(command),
@@ -102709,6 +103421,7 @@ function TerminalCard({
102709
103421
  }
102710
103422
 
102711
103423
  // src/components/tools/WebSearchCard.tsx
103424
+ var import_client_ui_core7 = __toESM(require_dist2(), 1);
102712
103425
  var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
102713
103426
  function WebSearchCard({
102714
103427
  query,
@@ -102717,7 +103430,7 @@ function WebSearchCard({
102717
103430
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
102718
103431
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Box2, { flexDirection: "row", children: [
102719
103432
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Box2, { minWidth: 2, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ThemedText, { colorKey: "chatMarker", children: glyphs.tool }) }),
102720
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: "web search" }) }),
103433
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: (0, import_client_ui_core7.toolDisplayName)("web_search") }) }),
102721
103434
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Box2, { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(ThemedText, { colorKey: "toolArgs", wrap: "wrap", children: [
102722
103435
  "(",
102723
103436
  query,
@@ -102772,14 +103485,14 @@ function QuotaWarning({ refusal }) {
102772
103485
  // src/components/tools/SubAgentTree.tsx
102773
103486
  var import_react22 = __toESM(require_react(), 1);
102774
103487
  var import_client_core23 = __toESM(require_dist(), 1);
102775
- var import_client_ui_core3 = __toESM(require_dist2(), 1);
103488
+ var import_client_ui_core8 = __toESM(require_dist2(), 1);
102776
103489
  var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
102777
103490
  function agentLabel(agent) {
102778
103491
  const type = agent.agentType.trim();
102779
103492
  if (type && type !== "general" && type !== "agent") return type;
102780
103493
  return typeof agent.ordinal === "number" ? `subagent ${agent.ordinal}` : "subagent";
102781
103494
  }
102782
- var rowMeta = import_client_ui_core3.subagentRowMeta;
103495
+ var rowMeta = import_client_ui_core8.subagentRowMeta;
102783
103496
  function rowStatus(agent) {
102784
103497
  if (agent.phase === "finished") {
102785
103498
  if (agent.status === "failed") return "Failed";
@@ -103012,7 +103725,7 @@ function OrionRing() {
103012
103725
 
103013
103726
  // src/services/version.ts
103014
103727
  function tuiVersion() {
103015
- return "0.1.15".length > 0 ? "0.1.15" : null;
103728
+ return "0.1.16".length > 0 ? "0.1.16" : null;
103016
103729
  }
103017
103730
 
103018
103731
  // src/components/layout/WelcomeCard.tsx
@@ -103046,6 +103759,9 @@ function WelcomeCard({ cwd, signedIn }) {
103046
103759
  ] });
103047
103760
  }
103048
103761
 
103762
+ // src/components/layout/LiveTurn.tsx
103763
+ var import_client_ui_core9 = __toESM(require_dist2(), 1);
103764
+
103049
103765
  // src/components/messages/Thinking.tsx
103050
103766
  var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
103051
103767
  var LIVE_LINES = 12;
@@ -103088,7 +103804,7 @@ function LiveTurn({
103088
103804
  live.assistantText.trim() ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AssistantText, { text: live.assistantText }) : null,
103089
103805
  showRunningTool && live.runningTool ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(Box2, { flexDirection: "row", marginTop: 1, children: [
103090
103806
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Box2, { minWidth: 2, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ThemedText, { colorKey: runningMarkerColorKey(spinner), children: glyphs.tool }) }),
103091
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: live.runningTool.name }) }),
103807
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: (0, import_client_ui_core9.toolDisplayName)(live.runningTool.name) }) }),
103092
103808
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Box2, { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(Text2, { wrap: "wrap", children: [
103093
103809
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(ThemedText, { colorKey: "toolArgs", children: [
103094
103810
  "(",
@@ -103127,7 +103843,7 @@ function LiveCode({
103127
103843
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
103128
103844
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(Box2, { flexDirection: "row", children: [
103129
103845
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Box2, { minWidth: 2, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ThemedText, { colorKey: runningMarkerColorKey(spinner), children: glyphs.tool }) }),
103130
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: code.name }) }),
103846
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ThemedText, { colorKey: "toolName", bold: true, children: (0, import_client_ui_core9.toolDisplayName)(code.name) }) }),
103131
103847
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Box2, { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(Text2, { wrap: "wrap", children: [
103132
103848
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(ThemedText, { colorKey: "toolArgs", children: [
103133
103849
  "(",
@@ -103346,11 +104062,11 @@ function PlanCard({ plan }) {
103346
104062
  // src/components/tools/SubAgentCard.tsx
103347
104063
  var import_react29 = __toESM(require_react(), 1);
103348
104064
  var import_client_core24 = __toESM(require_dist(), 1);
103349
- var import_client_ui_core4 = __toESM(require_dist2(), 1);
104065
+ var import_client_ui_core10 = __toESM(require_dist2(), 1);
103350
104066
  var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
103351
104067
  function SubAgentCard({ agent, now: now2 }) {
103352
104068
  const elapsed = (0, import_client_core24.formatElapsed)((now2 ?? Date.now()) - agent.startedAt);
103353
- const metrics = [elapsed, (0, import_client_ui_core4.subagentTokenLabel)(agent.contextTokens)].filter(Boolean).join(" \xB7 ");
104069
+ const metrics = [elapsed, (0, import_client_ui_core10.subagentTokenLabel)(agent.contextTokens)].filter(Boolean).join(" \xB7 ");
103354
104070
  return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Box2, { flexDirection: "row", children: [
103355
104071
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { flexShrink: 0, marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ThemedText, { colorKey: "dim", children: glyphs.subagent }) }),
103356
104072
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box2, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ThemedText, { colorKey: rowColorKey(agent), bold: true, wrap: "truncate", children: agentLabel(agent) }) }),
@@ -104644,7 +105360,7 @@ function StatusBar({
104644
105360
 
104645
105361
  // src/components/dialogs/AskUserPrompt.tsx
104646
105362
  var import_react32 = __toESM(require_react(), 1);
104647
- var import_client_ui_core5 = __toESM(require_dist2(), 1);
105363
+ var import_client_ui_core11 = __toESM(require_dist2(), 1);
104648
105364
 
104649
105365
  // src/components/dialogs/LineEditor.tsx
104650
105366
  var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
@@ -104683,7 +105399,7 @@ function QuestionChips({
104683
105399
  selections
104684
105400
  }) {
104685
105401
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Box2, { flexDirection: "row", children: questions.map((question, i2) => {
104686
- const mark = (0, import_client_ui_core5.isAnswered)(selections[i2] ?? import_client_ui_core5.EMPTY_SELECTION) ? "\u2713 " : "";
105402
+ const mark = (0, import_client_ui_core11.isAnswered)(selections[i2] ?? import_client_ui_core11.EMPTY_SELECTION) ? "\u2713 " : "";
104687
105403
  const label = `${mark}${question.header}`;
104688
105404
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Box2, { marginRight: 2, children: i2 === index ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(GradientText, { text: `[${label}]` }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: ` ${label} ` }) }, `${question.header}-${i2}`);
104689
105405
  }) });
@@ -104695,10 +105411,10 @@ function AskUserPrompt({
104695
105411
  guardMs = 250
104696
105412
  }) {
104697
105413
  const { requestId, sessionId } = pending;
104698
- const card = (0, import_react32.useMemo)(() => (0, import_client_ui_core5.buildAskCard)(pending.request), [pending.request]);
105414
+ const card = (0, import_react32.useMemo)(() => (0, import_client_ui_core11.buildAskCard)(pending.request), [pending.request]);
104699
105415
  const questions = card.questions;
104700
105416
  const [selections, setSelections] = (0, import_react32.useState)(
104701
- () => questions.map(() => import_client_ui_core5.EMPTY_SELECTION)
105417
+ () => questions.map(() => import_client_ui_core11.EMPTY_SELECTION)
104702
105418
  );
104703
105419
  const [index, setIndex] = (0, import_react32.useState)(0);
104704
105420
  const [cursor, setCursor] = (0, import_react32.useState)(0);
@@ -104712,7 +105428,7 @@ function AskUserPrompt({
104712
105428
  const theme = useTheme();
104713
105429
  const ruleWidth = Math.max(20, Math.min(MAX_RULE, columns - 8));
104714
105430
  const question = questions[index];
104715
- const submit = (finalSelections) => onRespond(requestId, (0, import_client_ui_core5.buildAnswers)(card, finalSelections), sessionId);
105431
+ const submit = (finalSelections) => onRespond(requestId, (0, import_client_ui_core11.buildAnswers)(card, finalSelections), sessionId);
104716
105432
  const commit = (next) => {
104717
105433
  const updated = selections.map((s, i2) => i2 === index ? next : s);
104718
105434
  setSelections(updated);
@@ -104738,7 +105454,7 @@ function AskUserPrompt({
104738
105454
  setDraft(selections[index]?.writeIn ?? "");
104739
105455
  return;
104740
105456
  }
104741
- const next = (0, import_client_ui_core5.toggleChoice)(selections[index] ?? import_client_ui_core5.EMPTY_SELECTION, choice, question.multiSelect);
105457
+ const next = (0, import_client_ui_core11.toggleChoice)(selections[index] ?? import_client_ui_core11.EMPTY_SELECTION, choice, question.multiSelect);
104742
105458
  if (question.multiSelect) {
104743
105459
  setSelections(selections.map((s, i2) => i2 === index ? next : s));
104744
105460
  return;
@@ -104760,8 +105476,8 @@ function AskUserPrompt({
104760
105476
  if (input === " " && question.multiSelect) return activate(cursor);
104761
105477
  if (key.return) {
104762
105478
  if (question.multiSelect) {
104763
- const current2 = selections[index] ?? import_client_ui_core5.EMPTY_SELECTION;
104764
- if ((0, import_client_ui_core5.isAnswered)(current2)) return commit(current2);
105479
+ const current2 = selections[index] ?? import_client_ui_core11.EMPTY_SELECTION;
105480
+ if ((0, import_client_ui_core11.isAnswered)(current2)) return commit(current2);
104765
105481
  if (question.choices[cursor]?.isWriteIn) return activate(cursor);
104766
105482
  return;
104767
105483
  }
@@ -104771,7 +105487,7 @@ function AskUserPrompt({
104771
105487
  if (!question) {
104772
105488
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: "(no question to answer \u2014 press esc)" }) });
104773
105489
  }
104774
- const answeredHere = (0, import_client_ui_core5.isAnswered)(selections[index] ?? import_client_ui_core5.EMPTY_SELECTION);
105490
+ const answeredHere = (0, import_client_ui_core11.isAnswered)(selections[index] ?? import_client_ui_core11.EMPTY_SELECTION);
104775
105491
  const step = questions.length > 1 ? `${index + 1} of ${questions.length}` : "";
104776
105492
  const hint = question.multiSelect ? `space toggle \xB7 enter confirm${questions.length > 1 ? " \xB7 tab next" : ""} \xB7 esc dismiss` : `enter select \xB7 \u2191\u2193 move${questions.length > 1 ? " \xB7 tab next" : ""} \xB7 esc dismiss`;
104777
105493
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
@@ -104790,8 +105506,8 @@ function AskUserPrompt({
104790
105506
  /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { bold: true, wrap: "wrap", children: question.question }),
104791
105507
  draft === null ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
104792
105508
  question.choices.map((choice, i2) => {
104793
- const picked = (selections[index] ?? import_client_ui_core5.EMPTY_SELECTION).picked.includes(choice.value);
104794
- const writtenIn = choice.isWriteIn && (selections[index] ?? import_client_ui_core5.EMPTY_SELECTION).writeIn !== "";
105509
+ const picked = (selections[index] ?? import_client_ui_core11.EMPTY_SELECTION).picked.includes(choice.value);
105510
+ const writtenIn = choice.isWriteIn && (selections[index] ?? import_client_ui_core11.EMPTY_SELECTION).writeIn !== "";
104795
105511
  const box = question.multiSelect ? picked ? "[x] " : "[ ] " : "";
104796
105512
  const mark = !question.multiSelect && (picked || writtenIn) ? "\u2713 " : "";
104797
105513
  const label = `${box}${mark}${i2 + 1}. ${choice.label}`;
@@ -104814,12 +105530,12 @@ function AskUserPrompt({
104814
105530
  hint: "enter save \xB7 esc back",
104815
105531
  onChange: setDraft,
104816
105532
  onSubmit: () => {
104817
- const next = (0, import_client_ui_core5.setWriteIn)(
104818
- selections[index] ?? import_client_ui_core5.EMPTY_SELECTION,
105533
+ const next = (0, import_client_ui_core11.setWriteIn)(
105534
+ selections[index] ?? import_client_ui_core11.EMPTY_SELECTION,
104819
105535
  draft,
104820
105536
  question.multiSelect
104821
105537
  );
104822
- if (!(0, import_client_ui_core5.isAnswered)(next)) return setDraft(null);
105538
+ if (!(0, import_client_ui_core11.isAnswered)(next)) return setDraft(null);
104823
105539
  if (question.multiSelect) {
104824
105540
  setSelections(selections.map((s, i2) => i2 === index ? next : s));
104825
105541
  setDraft(null);
@@ -104848,15 +105564,77 @@ function writtenInPreview(selection) {
104848
105564
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: ` + ${writeIn}` }) });
104849
105565
  }
104850
105566
 
105567
+ // src/components/dialogs/FeedbackPrompt.tsx
105568
+ var import_react33 = __toESM(require_react(), 1);
105569
+ var import_client_ui_core12 = __toESM(require_dist2(), 1);
105570
+ var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
105571
+ function FeedbackPrompt({
105572
+ pending,
105573
+ onSubmit,
105574
+ onDismiss,
105575
+ guardMs = 250
105576
+ }) {
105577
+ const { requestId } = pending;
105578
+ const [score, setScore] = (0, import_react33.useState)(0);
105579
+ const [why, setWhy] = (0, import_react33.useState)(null);
105580
+ const theme = useTheme();
105581
+ const guard = (0, import_react33.useRef)({ id: requestId, at: Date.now() });
105582
+ if (guard.current.id !== requestId) {
105583
+ guard.current = { id: requestId, at: Date.now() };
105584
+ }
105585
+ const guarded = () => Date.now() - guard.current.at < guardMs;
105586
+ use_input_default((input, key) => {
105587
+ if (why !== null || guarded()) return;
105588
+ if (key.escape) return onDismiss(requestId, true);
105589
+ if (/^[1-5]$/.test(input)) {
105590
+ setScore(parseInt(input, 10));
105591
+ setWhy("");
105592
+ return;
105593
+ }
105594
+ if (input) return onDismiss(requestId, false);
105595
+ });
105596
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
105597
+ Box2,
105598
+ {
105599
+ flexDirection: "column",
105600
+ marginTop: 1,
105601
+ borderStyle: "round",
105602
+ borderColor: theme.planMode,
105603
+ paddingX: 1,
105604
+ children: [
105605
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { bold: true, children: import_client_ui_core12.FEEDBACK_WORDING.title }),
105606
+ why === null ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
105607
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(GradientText, { text: " 1 2 3 4 5" }) }),
105608
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { dim: true, children: ` ${import_client_ui_core12.FEEDBACK_WORDING.scoreHint}` }),
105609
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { dim: true, children: "press 1-5 \xB7 esc dismiss \xB7 any key skip" }) })
105610
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
105611
+ LineEditor,
105612
+ {
105613
+ label: (0, import_client_ui_core12.feedbackWhyLabel)(score),
105614
+ value: why,
105615
+ hint: "enter send \xB7 esc back",
105616
+ onChange: setWhy,
105617
+ onSubmit: () => onSubmit(requestId, score, why),
105618
+ onCancel: () => {
105619
+ setWhy(null);
105620
+ setScore(0);
105621
+ }
105622
+ }
105623
+ )
105624
+ ]
105625
+ }
105626
+ );
105627
+ }
105628
+
104851
105629
  // src/components/dialogs/PermissionPrompt.tsx
104852
- var import_react34 = __toESM(require_react(), 1);
104853
- var import_client_ui_core6 = __toESM(require_dist2(), 1);
104854
- var import_client_ui_core7 = __toESM(require_dist2(), 1);
105630
+ var import_react35 = __toESM(require_react(), 1);
105631
+ var import_client_ui_core13 = __toESM(require_dist2(), 1);
105632
+ var import_client_ui_core14 = __toESM(require_dist2(), 1);
104855
105633
  var import_client_core26 = __toESM(require_dist(), 1);
104856
105634
 
104857
105635
  // src/components/dialogs/SelectList.tsx
104858
- var import_react33 = __toESM(require_react(), 1);
104859
- var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
105636
+ var import_react34 = __toESM(require_react(), 1);
105637
+ var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
104860
105638
  function SelectList({
104861
105639
  title,
104862
105640
  options,
@@ -104867,17 +105645,17 @@ function SelectList({
104867
105645
  maxVisible
104868
105646
  }) {
104869
105647
  const { rows } = useTerminalSize();
104870
- const [query, setQuery] = (0, import_react33.useState)("");
104871
- const view = (0, import_react33.useMemo)(() => {
105648
+ const [query, setQuery] = (0, import_react34.useState)("");
105649
+ const view = (0, import_react34.useMemo)(() => {
104872
105650
  if (!filterable) return options;
104873
105651
  const q2 = query.trim().toLowerCase();
104874
105652
  if (!q2) return options;
104875
105653
  return options.filter((o) => !o.separator && o.label.toLowerCase().includes(q2));
104876
105654
  }, [options, query, filterable]);
104877
105655
  const selectable = view.flatMap((o, i2) => o.separator ? [] : [i2]);
104878
- const [idx, setIdx] = (0, import_react33.useState)(selectable[0] ?? 0);
105656
+ const [idx, setIdx] = (0, import_react34.useState)(selectable[0] ?? 0);
104879
105657
  const safeIdx = selectable.includes(idx) ? idx : selectable[0] ?? 0;
104880
- (0, import_react33.useEffect)(() => {
105658
+ (0, import_react34.useEffect)(() => {
104881
105659
  if (filterable) setIdx(selectable[0] ?? 0);
104882
105660
  }, [query, filterable]);
104883
105661
  const move = (dir) => {
@@ -104916,17 +105694,17 @@ function SelectList({
104916
105694
  const start2 = windowed ? Math.max(0, Math.min(safeIdx - Math.floor(maxRows / 2), view.length - maxRows)) : 0;
104917
105695
  const end = windowed ? Math.min(start2 + maxRows, view.length) : view.length;
104918
105696
  const totalSelectable = filterable ? options.filter((o) => !o.separator).length : 0;
104919
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
104920
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: title }),
104921
- filterable ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(Box2, { children: [
104922
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { dim: true, children: "Search: " }),
104923
- query.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { children: query }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { dim: true, children: "type to filter" }),
104924
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { colorKey: "listSelection", children: "\u258F" }),
104925
- totalSelectable > 1 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { dim: true, children: ` ${selectable.length}/${totalSelectable}` }) : null
105697
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105698
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: title }),
105699
+ filterable ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(Box2, { children: [
105700
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { dim: true, children: "Search: " }),
105701
+ query.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { children: query }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { dim: true, children: "type to filter" }),
105702
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { colorKey: "listSelection", children: "\u258F" }),
105703
+ totalSelectable > 1 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { dim: true, children: ` ${selectable.length}/${totalSelectable}` }) : null
104926
105704
  ] }) : null,
104927
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(Box2, { flexDirection: columns ? "row" : "column", marginTop: columns ? 0 : 1, children: [
104928
- filterable && selectable.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { dim: true, children: "No matches." }) : null,
104929
- windowed && start2 > 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(ThemedText, { dim: true, children: [
105705
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(Box2, { flexDirection: columns ? "row" : "column", marginTop: columns ? 0 : 1, children: [
105706
+ filterable && selectable.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { dim: true, children: "No matches." }) : null,
105707
+ windowed && start2 > 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { dim: true, children: [
104930
105708
  "\u2191 ",
104931
105709
  start2,
104932
105710
  " more"
@@ -104934,29 +105712,29 @@ function SelectList({
104934
105712
  view.slice(start2, end).map((o, vi) => {
104935
105713
  const i2 = start2 + vi;
104936
105714
  const ordinal = numbered && !o.separator ? `${selectable.indexOf(i2) + 1}. ` : "";
104937
- return o.separator ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Box2, { marginTop: i2 > start2 ? 1 : 0, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ThemedText, { dim: true, bold: true, children: o.label }) }, `sep-${i2}`) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Box2, { flexDirection: "row", marginRight: columns ? 3 : 0, children: i2 === safeIdx ? (
105715
+ return o.separator ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Box2, { marginTop: i2 > start2 ? 1 : 0, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { dim: true, bold: true, children: o.label }) }, `sep-${i2}`) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Box2, { flexDirection: "row", marginRight: columns ? 3 : 0, children: i2 === safeIdx ? (
104938
105716
  // Selected row: the slogan's purple→lavender gradient (matches the
104939
105717
  // typing-/ menu); the hint rides the same ramp.
104940
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(GradientText, { text: `\u276F ${ordinal}${o.label}${o.hint ? ` ${o.hint}` : ""}` })
104941
- ) : /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
104942
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(ThemedText, { children: [
105718
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(GradientText, { text: `\u276F ${ordinal}${o.label}${o.hint ? ` ${o.hint}` : ""}` })
105719
+ ) : /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_jsx_runtime50.Fragment, { children: [
105720
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { children: [
104943
105721
  " ",
104944
105722
  ordinal,
104945
105723
  o.label
104946
105724
  ] }),
104947
- o.hint ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(ThemedText, { dim: true, children: [
105725
+ o.hint ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { dim: true, children: [
104948
105726
  "\xA0\xA0",
104949
105727
  o.hint
104950
105728
  ] }) : null
104951
105729
  ] }) }, o.value);
104952
105730
  }),
104953
- windowed && end < view.length ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(ThemedText, { dim: true, children: [
105731
+ windowed && end < view.length ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { dim: true, children: [
104954
105732
  "\u2193 ",
104955
105733
  view.length - end,
104956
105734
  " more"
104957
105735
  ] }) : null
104958
105736
  ] }),
104959
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(ThemedText, { dim: true, children: [
105737
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { dim: true, children: [
104960
105738
  "\u2191/\u2193 move \xB7 enter select \xB7 esc cancel",
104961
105739
  filterable ? " \xB7 type to filter" : ""
104962
105740
  ] })
@@ -104964,7 +105742,7 @@ function SelectList({
104964
105742
  }
104965
105743
 
104966
105744
  // src/components/dialogs/PermissionPrompt.tsx
104967
- var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
105745
+ var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
104968
105746
  function PermissionPrompt({
104969
105747
  pending,
104970
105748
  onRespond,
@@ -104972,12 +105750,12 @@ function PermissionPrompt({
104972
105750
  guardMs = 250
104973
105751
  }) {
104974
105752
  const { data, sessionId } = pending;
104975
- const model = (0, import_react34.useMemo)(
104976
- () => (0, import_client_ui_core6.buildPermissionCard)(data, { agentLabel: pending.agentLabel ?? null }),
105753
+ const model = (0, import_react35.useMemo)(
105754
+ () => (0, import_client_ui_core13.buildPermissionCard)(data, { agentLabel: pending.agentLabel ?? null }),
104977
105755
  [data, pending.agentLabel]
104978
105756
  );
104979
- const [stage, setStage] = (0, import_react34.useState)({ kind: "choose" });
104980
- const guard = (0, import_react34.useRef)({ id: data.request_id, at: Date.now() });
105757
+ const [stage, setStage] = (0, import_react35.useState)({ kind: "choose" });
105758
+ const guard = (0, import_react35.useRef)({ id: data.request_id, at: Date.now() });
104981
105759
  if (guard.current.id !== data.request_id) {
104982
105760
  guard.current = { id: data.request_id, at: Date.now() };
104983
105761
  if (stage.kind !== "choose") setStage({ kind: "choose" });
@@ -105021,9 +105799,9 @@ function PermissionPrompt({
105021
105799
  const bodyBlock = (() => {
105022
105800
  if (body2.kind === "command") {
105023
105801
  const { shown, more } = cap(body2.command.split("\n"));
105024
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(Box2, { flexDirection: "column", children: [
105025
- shown.map((line2, i2) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { colorKey: "toolArgs", wrap: "truncate-end", children: line2 || " " }, i2)),
105026
- more > 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { dim: true, children: [
105802
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { flexDirection: "column", children: [
105803
+ shown.map((line2, i2) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: "toolArgs", wrap: "truncate-end", children: line2 || " " }, i2)),
105804
+ more > 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(ThemedText, { dim: true, children: [
105027
105805
  "\u2026 (+",
105028
105806
  more,
105029
105807
  " more lines)"
@@ -105031,10 +105809,10 @@ function PermissionPrompt({
105031
105809
  ] });
105032
105810
  }
105033
105811
  if (body2.kind === "edit") {
105034
- const { shown, more } = cap((0, import_client_ui_core7.editDiffLines)(body2, 60));
105035
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(Box2, { flexDirection: "column", children: [
105036
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { dim: true, wrap: "truncate-middle", children: body2.path }),
105037
- shown.map((line2, i2) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
105812
+ const { shown, more } = cap((0, import_client_ui_core14.editDiffLines)(body2, 60));
105813
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { flexDirection: "column", children: [
105814
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, wrap: "truncate-middle", children: body2.path }),
105815
+ shown.map((line2, i2) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
105038
105816
  ThemedText,
105039
105817
  {
105040
105818
  colorKey: line2.startsWith("+") ? "success" : line2.startsWith("-") ? "error" : void 0,
@@ -105043,7 +105821,7 @@ function PermissionPrompt({
105043
105821
  },
105044
105822
  i2
105045
105823
  )),
105046
- more > 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { dim: true, children: [
105824
+ more > 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(ThemedText, { dim: true, children: [
105047
105825
  "\u2026 (+",
105048
105826
  more,
105049
105827
  " more lines)"
@@ -105052,10 +105830,10 @@ function PermissionPrompt({
105052
105830
  }
105053
105831
  if (body2.kind === "content") {
105054
105832
  const { shown, more } = cap(body2.content.split("\n"));
105055
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(Box2, { flexDirection: "column", children: [
105056
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { dim: true, wrap: "truncate-middle", children: body2.path }),
105057
- shown.map((line2, i2) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { colorKey: "toolArgs", wrap: "truncate-end", children: line2 || " " }, i2)),
105058
- more > 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { dim: true, children: [
105833
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { flexDirection: "column", children: [
105834
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, wrap: "truncate-middle", children: body2.path }),
105835
+ shown.map((line2, i2) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: "toolArgs", wrap: "truncate-end", children: line2 || " " }, i2)),
105836
+ more > 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(ThemedText, { dim: true, children: [
105059
105837
  "\u2026 (+",
105060
105838
  more,
105061
105839
  " more lines)"
@@ -105063,11 +105841,11 @@ function PermissionPrompt({
105063
105841
  ] });
105064
105842
  }
105065
105843
  const line = body2.kind === "path" ? body2.path : body2.kind === "fetch" ? body2.url : body2.inputPreview;
105066
- return line ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { colorKey: "toolArgs", wrap: "truncate-end", children: line }) : null;
105844
+ return line ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: "toolArgs", wrap: "truncate-end", children: line }) : null;
105067
105845
  })();
105068
105846
  const question = body2.kind === "command" ? "Do you want to run this command?" : body2.kind === "edit" ? "Do you want to make this edit?" : body2.kind === "content" ? "Do you want to create this file?" : "Do you want to proceed?";
105069
105847
  const theme = useTheme();
105070
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
105848
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
105071
105849
  Box2,
105072
105850
  {
105073
105851
  flexDirection: "column",
@@ -105076,27 +105854,27 @@ function PermissionPrompt({
105076
105854
  borderColor: theme.permissionMarker,
105077
105855
  paddingX: 1,
105078
105856
  children: [
105079
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(Box2, { flexDirection: "row", children: [
105080
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { colorKey: "warning", bold: true, children: `${model.attribution ? `${model.attribution} \u2014 ` : ""}${model.header.verb}${count > 1 ? ` (1 of ${count})` : ""} ` }),
105081
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { colorKey: "toolName", bold: true, wrap: "truncate-end", children: model.header.subject })
105857
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { flexDirection: "row", children: [
105858
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: "warning", bold: true, children: `${model.attribution ? `${model.attribution} \u2014 ` : ""}${model.header.verb}${count > 1 ? ` (1 of ${count})` : ""} ` }),
105859
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: "toolName", bold: true, wrap: "truncate-end", children: model.header.subject })
105082
105860
  ] }),
105083
- bodyBlock ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Box2, { paddingLeft: 2, marginTop: 1, flexDirection: "column", children: bodyBlock }) : null,
105084
- model.reason ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { dim: true, wrap: "wrap", children: model.reason }) }) : null,
105085
- model.outside ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { dim: true, children: [
105861
+ bodyBlock ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Box2, { paddingLeft: 2, marginTop: 1, flexDirection: "column", children: bodyBlock }) : null,
105862
+ model.reason ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, wrap: "wrap", children: model.reason }) }) : null,
105863
+ model.outside ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(ThemedText, { dim: true, children: [
105086
105864
  "blocked: ",
105087
105865
  model.outside.blockedPath,
105088
105866
  " \xB7 grants ",
105089
105867
  model.outside.grantDir
105090
105868
  ] }) }) : null,
105091
- data.consecutive_denials > 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(ThemedText, { dim: true, children: [
105869
+ data.consecutive_denials > 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Box2, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(ThemedText, { dim: true, children: [
105092
105870
  "(denied ",
105093
105871
  data.consecutive_denials,
105094
105872
  "\xD7 in a row)"
105095
105873
  ] }) }) : null,
105096
- stage.kind === "choose" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105097
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(ThemedText, { bold: true, children: question }),
105098
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(SelectList, { title: "", options, onSelect: choose, numbered: true, maxVisible: 6 })
105099
- ] }) : stage.kind === "edit-rule" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
105874
+ stage.kind === "choose" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105875
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { bold: true, children: question }),
105876
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(SelectList, { title: "", options, onSelect: choose, numbered: true, maxVisible: 6 })
105877
+ ] }) : stage.kind === "edit-rule" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
105100
105878
  LineEditor,
105101
105879
  {
105102
105880
  label: "Don't ask again for",
@@ -105116,11 +105894,11 @@ function PermissionPrompt({
105116
105894
  },
105117
105895
  onCancel: () => setStage({ kind: "choose" })
105118
105896
  }
105119
- ) : stage.kind === "pick-destination" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
105897
+ ) : stage.kind === "pick-destination" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
105120
105898
  SelectList,
105121
105899
  {
105122
105900
  title: `Save "${stage.rule}" to\u2026`,
105123
- options: import_client_ui_core6.DESTINATIONS.map((d2) => ({
105901
+ options: import_client_ui_core13.DESTINATIONS.map((d2) => ({
105124
105902
  value: d2.source,
105125
105903
  label: d2.source === stage.defaultDestination ? `${d2.label} (default)` : d2.label
105126
105904
  })),
@@ -105133,7 +105911,7 @@ function PermissionPrompt({
105133
105911
  });
105134
105912
  }
105135
105913
  }
105136
- ) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
105914
+ ) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
105137
105915
  LineEditor,
105138
105916
  {
105139
105917
  label: "Tell Orion what to do differently",
@@ -105152,8 +105930,8 @@ function PermissionPrompt({
105152
105930
  }
105153
105931
 
105154
105932
  // src/components/dialogs/EndpointsPanel.tsx
105155
- var import_react35 = __toESM(require_react(), 1);
105156
- var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
105933
+ var import_react36 = __toESM(require_react(), 1);
105934
+ var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
105157
105935
  function maskedKeyState(e) {
105158
105936
  if (e.apiKey) return `key \u2022\u2022\u2022\u2022${e.apiKey.slice(-4)}`;
105159
105937
  if (e.apiKeyHelper) return "key via helper";
@@ -105182,20 +105960,20 @@ function EndpointsPanel({
105182
105960
  deps: deps2,
105183
105961
  onClose
105184
105962
  }) {
105185
- const [overlay, setOverlay] = (0, import_react35.useState)(null);
105186
- const [name2, setName] = (0, import_react35.useState)("");
105187
- const [url, setUrl] = (0, import_react35.useState)("");
105188
- const [wire, setWire] = (0, import_react35.useState)("openai");
105189
- const [key, setKey] = (0, import_react35.useState)("");
105190
- const [selected, setSelected] = (0, import_react35.useState)(/* @__PURE__ */ new Set());
105191
- const [discovered, setDiscovered] = (0, import_react35.useState)(null);
105192
- const [modelConfig, setModelConfig] = (0, import_react35.useState)({});
105193
- const [editing, setEditing] = (0, import_react35.useState)(null);
105194
- const [configDraft, setConfigDraft] = (0, import_react35.useState)("");
105195
- const [savedPins, setSavedPins] = (0, import_react35.useState)(/* @__PURE__ */ new Set());
105196
- const [savedConfig, setSavedConfig] = (0, import_react35.useState)({});
105197
- const [fetching, setFetching] = (0, import_react35.useState)(false);
105198
- const [note, setNote] = (0, import_react35.useState)(null);
105963
+ const [overlay, setOverlay] = (0, import_react36.useState)(null);
105964
+ const [name2, setName] = (0, import_react36.useState)("");
105965
+ const [url, setUrl] = (0, import_react36.useState)("");
105966
+ const [wire, setWire] = (0, import_react36.useState)("openai");
105967
+ const [key, setKey] = (0, import_react36.useState)("");
105968
+ const [selected, setSelected] = (0, import_react36.useState)(/* @__PURE__ */ new Set());
105969
+ const [discovered, setDiscovered] = (0, import_react36.useState)(null);
105970
+ const [modelConfig, setModelConfig] = (0, import_react36.useState)({});
105971
+ const [editing, setEditing] = (0, import_react36.useState)(null);
105972
+ const [configDraft, setConfigDraft] = (0, import_react36.useState)("");
105973
+ const [savedPins, setSavedPins] = (0, import_react36.useState)(/* @__PURE__ */ new Set());
105974
+ const [savedConfig, setSavedConfig] = (0, import_react36.useState)({});
105975
+ const [fetching, setFetching] = (0, import_react36.useState)(false);
105976
+ const [note, setNote] = (0, import_react36.useState)(null);
105199
105977
  const slots = [
105200
105978
  ...deps2.entries.map((_2, index) => ({ kind: "entry", index })),
105201
105979
  { kind: "field", field: "name" },
@@ -105205,9 +105983,9 @@ function EndpointsPanel({
105205
105983
  { kind: "action", action: "fetch" },
105206
105984
  { kind: "action", action: "save" }
105207
105985
  ];
105208
- const [at, setAt] = (0, import_react35.useState)(deps2.entries.length);
105986
+ const [at, setAt] = (0, import_react36.useState)(deps2.entries.length);
105209
105987
  const slot = slots[Math.min(at, slots.length - 1)];
105210
- const [verifiedFor, setVerifiedFor] = (0, import_react35.useState)(null);
105988
+ const [verifiedFor, setVerifiedFor] = (0, import_react36.useState)(null);
105211
105989
  const fingerprint = `${url.trim()}\0${key}`;
105212
105990
  const verified = verifiedFor === fingerprint;
105213
105991
  const resetForm = () => {
@@ -105325,7 +106103,7 @@ function EndpointsPanel({
105325
106103
  }
105326
106104
  });
105327
106105
  if (overlay?.kind === "busy") {
105328
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: overlay.note }) });
106106
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: overlay.note }) });
105329
106107
  }
105330
106108
  if (overlay?.kind === "pick-models") {
105331
106109
  const list = overlay.discovered;
@@ -105343,7 +106121,7 @@ function EndpointsPanel({
105343
106121
  label: `${selected.has(model.id) ? "[x]" : "[ ]"} ${model.id}${describeWindow(model)}`
105344
106122
  }))
105345
106123
  ];
105346
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106124
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105347
106125
  SelectList,
105348
106126
  {
105349
106127
  title: `${list.length} models found \xB7 enter toggles \xB7 Done returns to the page`,
@@ -105373,7 +106151,7 @@ function EndpointsPanel({
105373
106151
  }
105374
106152
  if (overlay?.kind === "pick-model-config") {
105375
106153
  const list = overlay.discovered;
105376
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106154
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105377
106155
  SelectList,
105378
106156
  {
105379
106157
  title: "Which model? \xB7 leave a field empty to use what the endpoint reports",
@@ -105403,7 +106181,7 @@ function EndpointsPanel({
105403
106181
  const id = overlay.id;
105404
106182
  const probed = discovered?.find((model) => model.id === id);
105405
106183
  const back = () => setOverlay({ kind: "pick-model-config", discovered: discovered ?? [] });
105406
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106184
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105407
106185
  LineEditor,
105408
106186
  {
105409
106187
  label: `Context window for ${id}`,
@@ -105435,7 +106213,7 @@ function EndpointsPanel({
105435
106213
  if (overlay?.kind === "saved-models") {
105436
106214
  const { entry, models } = overlay;
105437
106215
  if (models.length === 0) {
105438
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106216
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105439
106217
  SelectList,
105440
106218
  {
105441
106219
  title: `${entry.name} \u2014 no models discovered (unreachable, or it lists none)`,
@@ -105453,7 +106231,7 @@ function EndpointsPanel({
105453
106231
  }
105454
106232
  return "";
105455
106233
  };
105456
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106234
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105457
106235
  SelectList,
105458
106236
  {
105459
106237
  title: `${entry.name} \xB7 ${savedPins.size ? `${savedPins.size} of ${models.length} pinned` : `all ${models.length} in the picker`}`,
@@ -105493,7 +106271,7 @@ function EndpointsPanel({
105493
106271
  const mine = savedConfig[id]?.contextWindow;
105494
106272
  const reported = models.find((m2) => m2.id === id);
105495
106273
  const windowNote = mine !== void 0 ? `${mine.toLocaleString()} (yours)` : reported?.source === "endpoint" && reported.contextWindow !== void 0 ? `${reported.contextWindow.toLocaleString()} (from endpoint)` : "not set";
105496
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106274
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105497
106275
  SelectList,
105498
106276
  {
105499
106277
  title: `${id} \xB7 context window ${windowNote}`,
@@ -105522,7 +106300,7 @@ function EndpointsPanel({
105522
106300
  const { entry, models, id } = overlay;
105523
106301
  const reported = models.find((m2) => m2.id === id);
105524
106302
  const back = () => setOverlay({ kind: "saved-models", entry, models });
105525
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106303
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105526
106304
  LineEditor,
105527
106305
  {
105528
106306
  label: `Context window for ${id}`,
@@ -105551,7 +106329,7 @@ function EndpointsPanel({
105551
106329
  );
105552
106330
  }
105553
106331
  if (overlay?.kind === "confirm-remove") {
105554
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106332
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105555
106333
  SelectList,
105556
106334
  {
105557
106335
  title: `Remove '${overlay.entry.name}' (${overlay.entry.baseUrl})?`,
@@ -105575,7 +106353,7 @@ function EndpointsPanel({
105575
106353
  );
105576
106354
  }
105577
106355
  if (overlay?.kind === "pick-model") {
105578
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106356
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105579
106357
  SelectList,
105580
106358
  {
105581
106359
  title: `'${overlay.entry.name}' \u2014 switch to which model?`,
@@ -105592,7 +106370,7 @@ function EndpointsPanel({
105592
106370
  }
105593
106371
  if (overlay?.kind === "entry-actions") {
105594
106372
  const entry = overlay.entry;
105595
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106373
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105596
106374
  SelectList,
105597
106375
  {
105598
106376
  title: `${entry.name} \u2014 ${entry.baseUrl}`,
@@ -105640,45 +106418,45 @@ function EndpointsPanel({
105640
106418
  const fieldRow = (field2, label, value, hint) => {
105641
106419
  const focused = focusField === field2;
105642
106420
  const shown = field2 === "wire" ? value === "openai" ? "OpenAI-compatible" : "Messages wire" : value;
105643
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { children: [
105644
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: focused ? "listSelection" : void 0, bold: focused, children: `${focused ? "\u276F" : " "} ${label.padEnd(8)} ` }),
105645
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: "toolArgs", children: field2 === "wire" ? `\u2039 ${shown} \u203A` : `[ ${shown}${focused ? "\u2588" : ""} ]` }),
105646
- focused ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: ` ${hint}` }) : null
106421
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { children: [
106422
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { colorKey: focused ? "listSelection" : void 0, bold: focused, children: `${focused ? "\u276F" : " "} ${label.padEnd(8)} ` }),
106423
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { colorKey: "toolArgs", children: field2 === "wire" ? `\u2039 ${shown} \u203A` : `[ ${shown}${focused ? "\u2588" : ""} ]` }),
106424
+ focused ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: ` ${hint}` }) : null
105647
106425
  ] }, field2);
105648
106426
  };
105649
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105650
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { bold: true, children: "Model endpoints" }),
105651
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: "Connect your own model servers or providers. Applies app-wide \u2014 also available in the Orion IDE and desktop app." }),
105652
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105653
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { children: [
105654
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { children: ` Orion (default) ${deps2.defaultApiUrl} ` }),
105655
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: "success", children: "Connected" })
106427
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106428
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { bold: true, children: "Model endpoints" }),
106429
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: "Connect your own model servers or providers. Applies app-wide \u2014 also available in the Orion IDE and desktop app." }),
106430
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106431
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { children: [
106432
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { children: ` Orion (default) ${deps2.defaultApiUrl} ` }),
106433
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { colorKey: "success", children: "Connected" })
105656
106434
  ] }),
105657
- deps2.entries.map((e, index) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { children: [
105658
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: focusEntry === index ? "listSelection" : void 0, bold: focusEntry === index, children: `${focusEntry === index ? "\u276F" : " "} ${e.name} ` }),
105659
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: `${e.baseUrl} \xB7 ${e.wire} \xB7 ${maskedKeyState(e)} \xB7 ${e.models?.length ? `${e.models.length} pinned model${e.models.length === 1 ? "" : "s"}` : "models via /models"}` })
106435
+ deps2.entries.map((e, index) => /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { children: [
106436
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { colorKey: focusEntry === index ? "listSelection" : void 0, bold: focusEntry === index, children: `${focusEntry === index ? "\u276F" : " "} ${e.name} ` }),
106437
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: `${e.baseUrl} \xB7 ${e.wire} \xB7 ${maskedKeyState(e)} \xB7 ${e.models?.length ? `${e.models.length} pinned model${e.models.length === 1 ? "" : "s"}` : "models via /models"}` })
105660
106438
  ] }, e.name))
105661
106439
  ] }),
105662
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105663
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { bold: true, children: "How to connect" }),
105664
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: "1. Name it and paste the base URL including its version path." }),
105665
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: "2. Wire: almost everything is OpenAI-compatible (Ollama, LM Studio, vLLM, OpenRouter\u2026)." }),
105666
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: "3. Paste the API key if the server needs one (local servers usually don't)." }),
105667
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: "4. Fetch models verifies the endpoint answers and lists what it offers (Add stays locked until it succeeds); optionally pin a subset." }),
105668
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: "5. Add endpoint \u2014 then pick its models from the model picker." })
106440
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106441
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { bold: true, children: "How to connect" }),
106442
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: "1. Name it and paste the base URL including its version path." }),
106443
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: "2. Wire: almost everything is OpenAI-compatible (Ollama, LM Studio, vLLM, OpenRouter\u2026)." }),
106444
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: "3. Paste the API key if the server needs one (local servers usually don't)." }),
106445
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: "4. Fetch models verifies the endpoint answers and lists what it offers (Add stays locked until it succeeds); optionally pin a subset." }),
106446
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: "5. Add endpoint \u2014 then pick its models from the model picker." })
105669
106447
  ] }),
105670
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105671
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { bold: true, children: editing === null ? "Add an endpoint" : `Edit '${editing}'` }),
106448
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106449
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { bold: true, children: editing === null ? "Add an endpoint" : `Edit '${editing}'` }),
105672
106450
  fieldRow("name", "Name", name2, "e.g. openrouter, ollama"),
105673
106451
  fieldRow("url", "Base URL", url, "e.g. https://openrouter.ai/api/v1 \xB7 http://localhost:11434/v1"),
105674
106452
  fieldRow("wire", "Wire", wire, "\u2190/\u2192 toggles"),
105675
106453
  fieldRow("key", "API key", key, "optional"),
105676
- Object.keys(modelConfig).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: `per-model limits set for ${Object.keys(modelConfig).length} model${Object.keys(modelConfig).length === 1 ? "" : "s"}` }) }) : null,
105677
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(Box2, { children: [
105678
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: focusAction === "fetch" ? "listSelection" : void 0, bold: focusAction === "fetch", children: `${focusAction === "fetch" ? "\u276F" : " "} ${fetching ? "Fetching\u2026" : "Fetch models"}` }),
105679
- discovered?.length ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: ` ${selected.size ? `${selected.size} of ${discovered.length} pinned` : `${discovered.length} found`}` }) : null
106454
+ Object.keys(modelConfig).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: `per-model limits set for ${Object.keys(modelConfig).length} model${Object.keys(modelConfig).length === 1 ? "" : "s"}` }) }) : null,
106455
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { children: [
106456
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { colorKey: focusAction === "fetch" ? "listSelection" : void 0, bold: focusAction === "fetch", children: `${focusAction === "fetch" ? "\u276F" : " "} ${fetching ? "Fetching\u2026" : "Fetch models"}` }),
106457
+ discovered?.length ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: ` ${selected.size ? `${selected.size} of ${discovered.length} pinned` : `${discovered.length} found`}` }) : null
105680
106458
  ] }),
105681
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Box2, { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
106459
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Box2, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
105682
106460
  ThemedText,
105683
106461
  {
105684
106462
  colorKey: focusAction === "save" ? "listSelection" : void 0,
@@ -105688,23 +106466,23 @@ function EndpointsPanel({
105688
106466
  }
105689
106467
  ) })
105690
106468
  ] }),
105691
- note ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { colorKey: note.error ? "error" : void 0, dim: !note.error, children: note.text }) }) : null,
105692
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ThemedText, { dim: true, children: "\u2191/\u2193 move \xB7 enter opens/runs \xB7 type to fill the focused field \xB7 esc closes" }) })
106469
+ note ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { colorKey: note.error ? "error" : void 0, dim: !note.error, children: note.text }) }) : null,
106470
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: "\u2191/\u2193 move \xB7 enter opens/runs \xB7 type to fill the focused field \xB7 esc closes" }) })
105693
106471
  ] });
105694
106472
  }
105695
106473
 
105696
106474
  // src/components/dialogs/PermissionRulesPanel.tsx
105697
- var import_react36 = __toESM(require_react(), 1);
106475
+ var import_react37 = __toESM(require_react(), 1);
105698
106476
  var import_client_core27 = __toESM(require_dist(), 1);
105699
- var import_client_ui_core8 = __toESM(require_dist2(), 1);
105700
- var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
106477
+ var import_client_ui_core15 = __toESM(require_dist2(), 1);
106478
+ var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
105701
106479
  function PermissionRulesPanel({
105702
106480
  rules,
105703
106481
  remove,
105704
106482
  add,
105705
106483
  onClose
105706
106484
  }) {
105707
- const [stage, setStage] = (0, import_react36.useState)({ kind: "list" });
106485
+ const [stage, setStage] = (0, import_react37.useState)({ kind: "list" });
105708
106486
  use_input_default((input, key) => {
105709
106487
  if (stage.kind !== "list") {
105710
106488
  if (stage.kind === "add-rule") {
@@ -105723,15 +106501,15 @@ function PermissionRulesPanel({
105723
106501
  });
105724
106502
  if (stage.kind === "add-rule") {
105725
106503
  const verdict = (0, import_client_core27.validateRule)(stage.draft);
105726
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105727
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { bold: true, children: "Add a permission rule" }),
105728
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { colorKey: "toolArgs", children: `[ ${stage.draft}\u2588 ]` }),
105729
- !verdict.ok && stage.draft.trim() !== "" ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { colorKey: "error", children: verdict.reason }) : null,
105730
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, children: "e.g. bash(npm run:*) \xB7 edit_file(src/**) \xB7 enter next \xB7 esc back" })
106504
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106505
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { bold: true, children: "Add a permission rule" }),
106506
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { colorKey: "toolArgs", children: `[ ${stage.draft}\u2588 ]` }),
106507
+ !verdict.ok && stage.draft.trim() !== "" ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { colorKey: "error", children: verdict.reason }) : null,
106508
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { dim: true, children: "e.g. bash(npm run:*) \xB7 edit_file(src/**) \xB7 enter next \xB7 esc back" })
105731
106509
  ] });
105732
106510
  }
105733
106511
  if (stage.kind === "add-behavior") {
105734
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
106512
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
105735
106513
  SelectList,
105736
106514
  {
105737
106515
  title: `"${stage.rule}" should\u2026`,
@@ -105752,11 +106530,11 @@ function PermissionRulesPanel({
105752
106530
  );
105753
106531
  }
105754
106532
  if (stage.kind === "add-destination") {
105755
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
106533
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
105756
106534
  SelectList,
105757
106535
  {
105758
106536
  title: `Save "${stage.rule}" to\u2026`,
105759
- options: import_client_ui_core8.DESTINATIONS.map((d2) => ({ value: d2.source, label: d2.label })),
106537
+ options: import_client_ui_core15.DESTINATIONS.map((d2) => ({ value: d2.source, label: d2.label })),
105760
106538
  onSelect: (value) => {
105761
106539
  if (value === null) return setStage({ kind: "list" });
105762
106540
  void add(stage.rule, stage.behavior, value).then(
@@ -105767,7 +106545,7 @@ function PermissionRulesPanel({
105767
106545
  );
105768
106546
  }
105769
106547
  if (stage.kind === "confirm-delete") {
105770
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
106548
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
105771
106549
  SelectList,
105772
106550
  {
105773
106551
  title: `Delete ${stage.rule.behavior} rule "${stage.rule.rule}" (${stage.rule.source})?`,
@@ -105789,7 +106567,7 @@ function PermissionRulesPanel({
105789
106567
  value: String(index),
105790
106568
  label: `[${rule.source}] ${rule.behavior} ${rule.rule}`
105791
106569
  }));
105792
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Box2, { flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
106570
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Box2, { flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
105793
106571
  SelectList,
105794
106572
  {
105795
106573
  title: rules.length > 0 ? "Permission rules \u2014 enter deletes \xB7 a adds \xB7 esc closes" : "No permission rules yet \u2014 a adds one \xB7 esc closes",
@@ -105804,8 +106582,8 @@ function PermissionRulesPanel({
105804
106582
  }
105805
106583
 
105806
106584
  // src/components/dialogs/PlanApprovalPrompt.tsx
105807
- var import_react37 = __toESM(require_react(), 1);
105808
- var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
106585
+ var import_react38 = __toESM(require_react(), 1);
106586
+ var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
105809
106587
  function PlanApprovalPrompt({
105810
106588
  pending,
105811
106589
  onRespond,
@@ -105813,7 +106591,7 @@ function PlanApprovalPrompt({
105813
106591
  guardMs = 250
105814
106592
  }) {
105815
106593
  const { requestId, sessionId } = pending;
105816
- const guard = (0, import_react37.useRef)({ id: requestId, at: Date.now() });
106594
+ const guard = (0, import_react38.useRef)({ id: requestId, at: Date.now() });
105817
106595
  if (guard.current.id !== requestId) guard.current = { id: requestId, at: Date.now() };
105818
106596
  use_input_default((input, key) => {
105819
106597
  if (key.ctrl && input === "c") {
@@ -105826,30 +106604,30 @@ function PlanApprovalPrompt({
105826
106604
  else if (c3 === "m") onRespond(requestId, "manual", sessionId);
105827
106605
  else if (c3 === "k" || key.escape) onRespond(requestId, "keep", sessionId);
105828
106606
  });
105829
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105830
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Box2, { flexDirection: "row", children: [
105831
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(ThemedText, { colorKey: "planMode", bold: true, children: [
106607
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106608
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(Box2, { flexDirection: "row", children: [
106609
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(ThemedText, { colorKey: "planMode", bold: true, children: [
105832
106610
  glyphs.planMode,
105833
106611
  " Plan ready \u2014 proceed?"
105834
106612
  ] }),
105835
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { dim: true, children: " (full plan above \u2191)" })
106613
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: " (full plan above \u2191)" })
105836
106614
  ] }),
105837
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Box2, { marginTop: 1, flexDirection: "row", children: [
105838
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { colorKey: "autoAccept", bold: true, children: "[a]" }),
105839
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { dim: true, children: " auto-accept edits\xA0\xA0\xA0" }),
105840
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { colorKey: "planMode", bold: true, children: "[m]" }),
105841
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { dim: true, children: " approve edits\xA0\xA0\xA0" }),
105842
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { colorKey: "dim", bold: true, children: "[k]" }),
105843
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { dim: true, children: " keep planning\xA0\xA0\xA0" }),
105844
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ThemedText, { dim: true, children: "ctrl+c cancel" })
106615
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(Box2, { marginTop: 1, flexDirection: "row", children: [
106616
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { colorKey: "autoAccept", bold: true, children: "[a]" }),
106617
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: " auto-accept edits\xA0\xA0\xA0" }),
106618
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { colorKey: "planMode", bold: true, children: "[m]" }),
106619
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: " approve edits\xA0\xA0\xA0" }),
106620
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { colorKey: "dim", bold: true, children: "[k]" }),
106621
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: " keep planning\xA0\xA0\xA0" }),
106622
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: "ctrl+c cancel" })
105845
106623
  ] })
105846
106624
  ] });
105847
106625
  }
105848
106626
 
105849
106627
  // src/components/dialogs/WorkPlanApprovalPrompt.tsx
105850
- var import_react38 = __toESM(require_react(), 1);
106628
+ var import_react39 = __toESM(require_react(), 1);
105851
106629
  var import_client_core28 = __toESM(require_dist(), 1);
105852
- var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
106630
+ var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
105853
106631
  function WorkPlanApprovalPrompt({
105854
106632
  pending,
105855
106633
  onRespond,
@@ -105857,7 +106635,7 @@ function WorkPlanApprovalPrompt({
105857
106635
  guardMs = 250
105858
106636
  }) {
105859
106637
  const { requestId, plan } = pending;
105860
- const guard = (0, import_react38.useRef)({ id: requestId, at: Date.now() });
106638
+ const guard = (0, import_react39.useRef)({ id: requestId, at: Date.now() });
105861
106639
  if (guard.current.id !== requestId) guard.current = { id: requestId, at: Date.now() };
105862
106640
  use_input_default((input, key) => {
105863
106641
  if (key.ctrl && input === "c") {
@@ -105870,64 +106648,64 @@ function WorkPlanApprovalPrompt({
105870
106648
  else if (c3 === "n" || key.escape) onRespond(requestId, false);
105871
106649
  });
105872
106650
  const worktreeCandidates = (0, import_client_core28.planWorktreeCount)(plan);
105873
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105874
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Box2, { flexDirection: "row", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { colorKey: "planMode", bold: true, children: "Work graph \u2014 run this plan in the background?" }) }),
105875
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: plan.goal }) }),
105876
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Box2, { flexDirection: "column", marginTop: 1, marginLeft: 2, children: (0, import_client_core28.planFlowLines)(plan).map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { colorKey: "planMode", children: line }, index)) }),
105877
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Box2, { marginTop: 1, flexDirection: "column", children: plan.phases.map((phase) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(PhaseRow, { phase }, phase.id)) }),
105878
- worktreeCandidates > 0 && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: `${worktreeCandidates} isolated worktree${worktreeCandidates === 1 ? "" : "s"} will be created; changed ones are kept for review.` }) }),
105879
- /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(Box2, { marginTop: 1, flexDirection: "row", children: [
105880
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { colorKey: "autoAccept", bold: true, children: "[y]" }),
105881
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: " run it\xA0\xA0\xA0" }),
105882
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { colorKey: "dim", bold: true, children: "[n]" }),
105883
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: " decline\xA0\xA0\xA0" }),
105884
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: "ctrl+c cancel" })
106651
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106652
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Box2, { flexDirection: "row", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { colorKey: "planMode", bold: true, children: "Work graph \u2014 run this plan in the background?" }) }),
106653
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { dim: true, children: plan.goal }) }),
106654
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Box2, { flexDirection: "column", marginTop: 1, marginLeft: 2, children: (0, import_client_core28.planFlowLines)(plan).map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { colorKey: "planMode", children: line }, index)) }),
106655
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Box2, { marginTop: 1, flexDirection: "column", children: plan.phases.map((phase) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(PhaseRow, { phase }, phase.id)) }),
106656
+ worktreeCandidates > 0 && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { dim: true, children: `${worktreeCandidates} isolated worktree${worktreeCandidates === 1 ? "" : "s"} will be created; changed ones are kept for review.` }) }),
106657
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(Box2, { marginTop: 1, flexDirection: "row", children: [
106658
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { colorKey: "autoAccept", bold: true, children: "[y]" }),
106659
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { dim: true, children: " run it\xA0\xA0\xA0" }),
106660
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { colorKey: "dim", bold: true, children: "[n]" }),
106661
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { dim: true, children: " decline\xA0\xA0\xA0" }),
106662
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { dim: true, children: "ctrl+c cancel" })
105885
106663
  ] })
105886
106664
  ] });
105887
106665
  }
105888
106666
  function PhaseRow({ phase }) {
105889
106667
  const heading = phase.title && phase.title !== phase.id ? `${phase.id} \u2014 ${phase.title}` : phase.id;
105890
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(Box2, { flexDirection: "column", marginLeft: 2, marginTop: 1, children: [
105891
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { bold: true, children: heading }),
105892
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { dim: true, children: (0, import_client_core28.phaseTraits)(phase).join(" \xB7 ") }) }),
105893
- phase.gate && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Box2, { marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ThemedText, { colorKey: "planMode", children: `gate: ${phase.gate.cmd}${(0, import_client_core28.gateRetrySuffix)(phase.gate)}` }) })
106668
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(Box2, { flexDirection: "column", marginLeft: 2, marginTop: 1, children: [
106669
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { bold: true, children: heading }),
106670
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { dim: true, children: (0, import_client_core28.phaseTraits)(phase).join(" \xB7 ") }) }),
106671
+ phase.gate && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Box2, { marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { colorKey: "planMode", children: `gate: ${phase.gate.cmd}${(0, import_client_core28.gateRetrySuffix)(phase.gate)}` }) })
105894
106672
  ] });
105895
106673
  }
105896
106674
 
105897
106675
  // src/components/dialogs/ModelPicker.tsx
105898
- var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
106676
+ var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
105899
106677
  function ModelPicker({ dialog }) {
105900
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(SelectList, { title: dialog.title, options: dialog.options, onSelect: dialog.onSelect, filterable: true });
106678
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectList, { title: dialog.title, options: dialog.options, onSelect: dialog.onSelect, filterable: true });
105901
106679
  }
105902
106680
 
105903
106681
  // src/components/dialogs/ResumePicker.tsx
105904
- var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
106682
+ var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
105905
106683
  function ResumePicker({ dialog }) {
105906
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectList, { title: dialog.title, options: dialog.options, onSelect: dialog.onSelect, filterable: true });
106684
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(SelectList, { title: dialog.title, options: dialog.options, onSelect: dialog.onSelect, filterable: true });
105907
106685
  }
105908
106686
 
105909
106687
  // src/components/dialogs/ConfirmDialog.tsx
105910
- var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
106688
+ var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
105911
106689
  function ConfirmDialog({ dialog }) {
105912
106690
  use_input_default((input, key) => {
105913
106691
  const c3 = (input ?? "").toLowerCase();
105914
106692
  if (c3 === "y" || key.return) dialog.onSelect("yes");
105915
106693
  else if (c3 === "n" || key.escape) dialog.onSelect("no");
105916
106694
  });
105917
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105918
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { colorKey: "warning", bold: true, children: dialog.title }),
105919
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Box2, { marginTop: 1, flexDirection: "row", children: [
105920
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { colorKey: "success", bold: true, children: "[y]" }),
105921
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { dim: true, children: " yes\xA0\xA0\xA0" }),
105922
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { colorKey: "error", bold: true, children: "[n]" }),
105923
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { dim: true, children: " no" })
106695
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106696
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ThemedText, { colorKey: "warning", bold: true, children: dialog.title }),
106697
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Box2, { marginTop: 1, flexDirection: "row", children: [
106698
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ThemedText, { colorKey: "success", bold: true, children: "[y]" }),
106699
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ThemedText, { dim: true, children: " yes\xA0\xA0\xA0" }),
106700
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ThemedText, { colorKey: "error", bold: true, children: "[n]" }),
106701
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ThemedText, { dim: true, children: " no" })
105924
106702
  ] })
105925
106703
  ] });
105926
106704
  }
105927
106705
 
105928
106706
  // src/components/dialogs/HooksBrowser.tsx
105929
- var import_react39 = __toESM(require_react(), 1);
105930
- var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
106707
+ var import_react40 = __toESM(require_react(), 1);
106708
+ var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
105931
106709
  function matcherLabel(m2) {
105932
106710
  if (!m2 || typeof m2 !== "object") return "(any)";
105933
106711
  const parts2 = Object.entries(m2).map(([k, v2]) => `${k}=${String(v2)}`);
@@ -105946,64 +106724,64 @@ function HookDetail({ hook, onBack }) {
105946
106724
  if (key.escape || key.return) onBack();
105947
106725
  });
105948
106726
  const cmd = commandLabel(hook.command);
105949
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105950
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: "Hook detail" }),
105951
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
105952
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ThemedText, { children: [
106727
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106728
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: "Hook detail" }),
106729
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106730
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(ThemedText, { children: [
105953
106731
  "event: ",
105954
106732
  hook.event ?? "\u2014"
105955
106733
  ] }),
105956
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ThemedText, { children: [
106734
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(ThemedText, { children: [
105957
106735
  "type: ",
105958
106736
  hook.type ?? "command"
105959
106737
  ] }),
105960
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ThemedText, { children: [
106738
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(ThemedText, { children: [
105961
106739
  "matcher: ",
105962
106740
  matcherLabel(hook.matcher)
105963
106741
  ] }),
105964
- cmd ? /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ThemedText, { children: [
106742
+ cmd ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(ThemedText, { children: [
105965
106743
  "command: ",
105966
106744
  cmd
105967
106745
  ] }) : null,
105968
- hook.url ? /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ThemedText, { children: [
106746
+ hook.url ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(ThemedText, { children: [
105969
106747
  "url: ",
105970
106748
  hook.url
105971
106749
  ] }) : null,
105972
- hook.model ? /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ThemedText, { children: [
106750
+ hook.model ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(ThemedText, { children: [
105973
106751
  "model: ",
105974
106752
  hook.model
105975
106753
  ] }) : null,
105976
- hook.agent_kind ? /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ThemedText, { children: [
106754
+ hook.agent_kind ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(ThemedText, { children: [
105977
106755
  "agent: ",
105978
106756
  hook.agent_kind
105979
106757
  ] }) : null,
105980
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ThemedText, { children: [
106758
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(ThemedText, { children: [
105981
106759
  "blocking: ",
105982
106760
  hook.blocking ? "yes" : "no"
105983
106761
  ] }),
105984
- hook.timeout_ms != null ? /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ThemedText, { children: [
106762
+ hook.timeout_ms != null ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(ThemedText, { children: [
105985
106763
  "timeout: ",
105986
106764
  hook.timeout_ms,
105987
106765
  "ms"
105988
106766
  ] }) : null
105989
106767
  ] }),
105990
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ThemedText, { dim: true, children: "esc back" })
106768
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(ThemedText, { dim: true, children: "esc back" })
105991
106769
  ] });
105992
106770
  }
105993
106771
  function HooksBrowser({
105994
106772
  hooks,
105995
106773
  onClose
105996
106774
  }) {
105997
- const [event, setEvent] = (0, import_react39.useState)(null);
105998
- const [matcher, setMatcher] = (0, import_react39.useState)(null);
105999
- const [hookIdx, setHookIdx] = (0, import_react39.useState)(null);
106775
+ const [event, setEvent] = (0, import_react40.useState)(null);
106776
+ const [matcher, setMatcher] = (0, import_react40.useState)(null);
106777
+ const [hookIdx, setHookIdx] = (0, import_react40.useState)(null);
106000
106778
  if (event === null) {
106001
106779
  const events = [...new Set(hooks.map((h) => h.event ?? "(unknown)"))].sort();
106002
106780
  const options = events.map((e) => {
106003
106781
  const n = hooks.filter((h) => (h.event ?? "(unknown)") === e).length;
106004
106782
  return { label: e, value: e, hint: `${n} hook${n === 1 ? "" : "s"}` };
106005
106783
  });
106006
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
106784
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
106007
106785
  SelectList,
106008
106786
  {
106009
106787
  title: "Hooks \u2014 select an event",
@@ -106019,7 +106797,7 @@ function HooksBrowser({
106019
106797
  const n = inEvent.filter((h) => matcherLabel(h.matcher) === m2).length;
106020
106798
  return { label: m2, value: m2, hint: `${n} hook${n === 1 ? "" : "s"}` };
106021
106799
  });
106022
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
106800
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
106023
106801
  SelectList,
106024
106802
  {
106025
106803
  title: `Hooks \xB7 ${event} \u2014 select a matcher`,
@@ -106031,7 +106809,7 @@ function HooksBrowser({
106031
106809
  const inMatcher = inEvent.filter((h) => matcherLabel(h.matcher) === matcher);
106032
106810
  if (hookIdx === null) {
106033
106811
  const options = inMatcher.map((h, i2) => ({ label: hookSummary(h), value: String(i2) }));
106034
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
106812
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
106035
106813
  SelectList,
106036
106814
  {
106037
106815
  title: `Hooks \xB7 ${event} \xB7 ${matcher} \u2014 select a hook`,
@@ -106043,14 +106821,14 @@ function HooksBrowser({
106043
106821
  const hook = inMatcher[hookIdx];
106044
106822
  if (!hook) {
106045
106823
  setHookIdx(null);
106046
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Box2, {});
106824
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Box2, {});
106047
106825
  }
106048
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(HookDetail, { hook, onBack: () => setHookIdx(null) });
106826
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(HookDetail, { hook, onBack: () => setHookIdx(null) });
106049
106827
  }
106050
106828
 
106051
106829
  // src/components/dialogs/PluginManager.tsx
106052
- var import_react40 = __toESM(require_react(), 1);
106053
- var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
106830
+ var import_react41 = __toESM(require_react(), 1);
106831
+ var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
106054
106832
  function pluginId(p) {
106055
106833
  return p.id ?? p.name ?? "";
106056
106834
  }
@@ -106062,9 +106840,9 @@ function PluginManager({
106062
106840
  act,
106063
106841
  onClose
106064
106842
  }) {
106065
- const [selectedId, setSelectedId] = (0, import_react40.useState)(null);
106066
- const [confirming, setConfirming] = (0, import_react40.useState)(false);
106067
- const [busy, setBusy] = (0, import_react40.useState)(false);
106843
+ const [selectedId, setSelectedId] = (0, import_react41.useState)(null);
106844
+ const [confirming, setConfirming] = (0, import_react41.useState)(false);
106845
+ const [busy, setBusy] = (0, import_react41.useState)(false);
106068
106846
  const selected = plugins.find((p) => pluginId(p) === selectedId) ?? null;
106069
106847
  const run3 = (action) => {
106070
106848
  if (!selectedId) return;
@@ -106076,10 +106854,10 @@ function PluginManager({
106076
106854
  });
106077
106855
  };
106078
106856
  if (busy) {
106079
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(ThemedText, { dim: true, children: "Working\u2026" }) });
106857
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(ThemedText, { dim: true, children: "Working\u2026" }) });
106080
106858
  }
106081
106859
  if (confirming && selected) {
106082
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
106860
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
106083
106861
  ConfirmDialog,
106084
106862
  {
106085
106863
  dialog: {
@@ -106100,7 +106878,7 @@ function PluginManager({
106100
106878
  { label: "Update", value: "update" },
106101
106879
  { label: "Uninstall", value: "uninstall" }
106102
106880
  ];
106103
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
106881
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
106104
106882
  SelectList,
106105
106883
  {
106106
106884
  title: `Plugin: ${pluginLabel(selected)} (${selected.enabled ? "enabled" : "disabled"})`,
@@ -106118,7 +106896,7 @@ function PluginManager({
106118
106896
  value: pluginId(p),
106119
106897
  hint: p.enabled ? "enabled" : "disabled"
106120
106898
  }));
106121
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
106899
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
106122
106900
  SelectList,
106123
106901
  {
106124
106902
  title: "Plugins \u2014 select one to manage",
@@ -106129,8 +106907,8 @@ function PluginManager({
106129
106907
  }
106130
106908
 
106131
106909
  // src/components/dialogs/RewindPicker.tsx
106132
- var import_react41 = __toESM(require_react(), 1);
106133
- var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
106910
+ var import_react42 = __toESM(require_react(), 1);
106911
+ var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
106134
106912
  function statLabel(t) {
106135
106913
  if (!t.files) return "no code changes";
106136
106914
  return `${t.files} file${t.files === 1 ? "" : "s"} +${t.insertions}/-${t.deletions}`;
@@ -106144,10 +106922,10 @@ function RewindPicker({
106144
106922
  apply: apply2,
106145
106923
  onClose
106146
106924
  }) {
106147
- const [picked, setPicked] = (0, import_react41.useState)(null);
106148
- const [busy, setBusy] = (0, import_react41.useState)(false);
106925
+ const [picked, setPicked] = (0, import_react42.useState)(null);
106926
+ const [busy, setBusy] = (0, import_react42.useState)(false);
106149
106927
  if (busy) {
106150
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(ThemedText, { dim: true, children: "Working\u2026" }) });
106928
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(ThemedText, { dim: true, children: "Working\u2026" }) });
106151
106929
  }
106152
106930
  if (picked !== null) {
106153
106931
  const turn = turns[picked];
@@ -106158,7 +106936,7 @@ function RewindPicker({
106158
106936
  ...hasCode ? [{ label: "Restore code", value: "code" }] : [],
106159
106937
  { label: "Never mind", value: "cancel" }
106160
106938
  ];
106161
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
106939
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
106162
106940
  SelectList,
106163
106941
  {
106164
106942
  title: `Rewind to: ${preview(turn?.prompt ?? "")}`,
@@ -106172,7 +106950,7 @@ function RewindPicker({
106172
106950
  );
106173
106951
  }
106174
106952
  const options = turns.map((t, i2) => ({ t, i: i2 })).reverse().map(({ t, i: i2 }) => ({ label: preview(t.prompt), value: String(i2), hint: statLabel(t) }));
106175
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
106953
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
106176
106954
  SelectList,
106177
106955
  {
106178
106956
  title: "Rewind \u2014 pick a turn to return to",
@@ -106183,8 +106961,8 @@ function RewindPicker({
106183
106961
  }
106184
106962
 
106185
106963
  // src/components/dialogs/McpManager.tsx
106186
- var import_react42 = __toESM(require_react(), 1);
106187
- var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
106964
+ var import_react43 = __toESM(require_react(), 1);
106965
+ var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
106188
106966
  function serverHint(s) {
106189
106967
  const bits = [s.status ?? "?"];
106190
106968
  if (s.tools_count != null) bits.push(`${s.tools_count} tools`);
@@ -106196,11 +106974,11 @@ function McpManager({
106196
106974
  approve,
106197
106975
  onClose
106198
106976
  }) {
106199
- const [selected, setSelected] = (0, import_react42.useState)(null);
106200
- const [busy, setBusy] = (0, import_react42.useState)(false);
106977
+ const [selected, setSelected] = (0, import_react43.useState)(null);
106978
+ const [busy, setBusy] = (0, import_react43.useState)(false);
106201
106979
  const server = servers.find((s) => s.name === selected) ?? null;
106202
106980
  if (busy) {
106203
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(ThemedText, { dim: true, children: "Working\u2026" }) });
106981
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(ThemedText, { dim: true, children: "Working\u2026" }) });
106204
106982
  }
106205
106983
  if (server) {
106206
106984
  const canApprove = server.approved === false && !!server.fingerprint;
@@ -106208,31 +106986,31 @@ function McpManager({
106208
106986
  ...canApprove ? [{ label: "Approve this server", value: "approve" }] : [],
106209
106987
  { label: "Back", value: "back" }
106210
106988
  ];
106211
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106212
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: server.name }),
106213
- /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106214
- /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(ThemedText, { children: [
106989
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106990
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: server.name }),
106991
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106992
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(ThemedText, { children: [
106215
106993
  "status: ",
106216
106994
  server.status ?? "?"
106217
106995
  ] }),
106218
- server.transport ? /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(ThemedText, { children: [
106996
+ server.transport ? /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(ThemedText, { children: [
106219
106997
  "transport: ",
106220
106998
  server.transport
106221
106999
  ] }) : null,
106222
- server.scope ? /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(ThemedText, { children: [
107000
+ server.scope ? /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(ThemedText, { children: [
106223
107001
  "scope: ",
106224
107002
  server.scope
106225
107003
  ] }) : null,
106226
- server.tools_count != null ? /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(ThemedText, { children: [
107004
+ server.tools_count != null ? /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(ThemedText, { children: [
106227
107005
  "tools: ",
106228
107006
  server.tools_count
106229
107007
  ] }) : null,
106230
- /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(ThemedText, { children: [
107008
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(ThemedText, { children: [
106231
107009
  "approved: ",
106232
107010
  server.approved ? "yes" : "no"
106233
107011
  ] })
106234
107012
  ] }),
106235
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
107013
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
106236
107014
  SelectList,
106237
107015
  {
106238
107016
  title: "Actions",
@@ -106252,7 +107030,7 @@ function McpManager({
106252
107030
  ] });
106253
107031
  }
106254
107032
  const options = servers.map((s) => ({ label: s.name ?? "?", value: s.name ?? "", hint: serverHint(s) }));
106255
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
107033
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
106256
107034
  SelectList,
106257
107035
  {
106258
107036
  title: "MCP servers \u2014 select one",
@@ -106263,7 +107041,7 @@ function McpManager({
106263
107041
  }
106264
107042
 
106265
107043
  // src/components/dialogs/ModalFrame.tsx
106266
- var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
107044
+ var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
106267
107045
  var RAIL_BORDER2 = {
106268
107046
  topLeft: "\u258C",
106269
107047
  top: " ",
@@ -106276,7 +107054,7 @@ var RAIL_BORDER2 = {
106276
107054
  };
106277
107055
  function ModalFrame({ children }) {
106278
107056
  const theme = useTheme();
106279
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
107057
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
106280
107058
  Box2,
106281
107059
  {
106282
107060
  flexDirection: "column",
@@ -106293,7 +107071,7 @@ function ModalFrame({ children }) {
106293
107071
 
106294
107072
  // src/components/dialogs/UsageMetricsPanel.tsx
106295
107073
  var import_client_core29 = __toESM(require_dist(), 1);
106296
- var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
107074
+ var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
106297
107075
  function compactInt(value) {
106298
107076
  if (value >= 1e6) return `${(value / 1e6).toFixed(1)}m`;
106299
107077
  if (value >= 1e3) return `${(value / 1e3).toFixed(1)}k`;
@@ -106363,9 +107141,9 @@ function MetricBar({
106363
107141
  tone
106364
107142
  }) {
106365
107143
  const cells = barCells(value, max);
106366
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexShrink: 0, children: [
106367
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { colorKey: BAR_TONES2[tone % BAR_TONES2.length], children: "\u2588".repeat(cells.filled) }),
106368
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { dim: true, children: "\u2591".repeat(cells.empty) })
107144
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexShrink: 0, children: [
107145
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { colorKey: BAR_TONES2[tone % BAR_TONES2.length], children: "\u2588".repeat(cells.filled) }),
107146
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { dim: true, children: "\u2591".repeat(cells.empty) })
106369
107147
  ] });
106370
107148
  }
106371
107149
  function BarRow({
@@ -106375,25 +107153,25 @@ function BarRow({
106375
107153
  tone,
106376
107154
  children
106377
107155
  }) {
106378
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { children: [
106379
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Box2, { width: 18, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { wrap: "truncate", children: label }) }),
106380
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(MetricBar, { value, max, tone }),
106381
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Box2, { marginLeft: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { dim: true, children }) })
107156
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { children: [
107157
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Box2, { width: 18, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { wrap: "truncate", children: label }) }),
107158
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(MetricBar, { value, max, tone }),
107159
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Box2, { marginLeft: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { dim: true, children }) })
106382
107160
  ] });
106383
107161
  }
106384
107162
  function SummaryBlock({
106385
107163
  title,
106386
107164
  summary
106387
107165
  }) {
106388
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106389
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: title }),
106390
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(ThemedText, { children: [
107166
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107167
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: title }),
107168
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(ThemedText, { children: [
106391
107169
  summary.events,
106392
107170
  " turns \xB7 ",
106393
107171
  summary.calls,
106394
107172
  " model calls"
106395
107173
  ] }),
106396
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { dim: true, children: tokenLine(summary) })
107174
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { dim: true, children: tokenLine(summary) })
106397
107175
  ] });
106398
107176
  }
106399
107177
  function BreakdownRows({
@@ -106403,11 +107181,11 @@ function BreakdownRows({
106403
107181
  const rows = topRows(group);
106404
107182
  if (rows.length === 0) return null;
106405
107183
  const max = Math.max(...rows.map(([, item]) => (0, import_client_core29.meteredTokens)(item.tokens)), 1);
106406
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106407
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { bold: true, children: title }),
107184
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107185
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { bold: true, children: title }),
106408
107186
  rows.map(([key, item], index) => {
106409
107187
  const tokens = (0, import_client_core29.meteredTokens)(item.tokens);
106410
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(BarRow, { label: key, value: tokens, max, tone: index, children: [
107188
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(BarRow, { label: key, value: tokens, max, tone: index, children: [
106411
107189
  item.calls,
106412
107190
  " calls \xB7 in ",
106413
107191
  compactInt(item.tokens.input_tokens ?? 0),
@@ -106427,9 +107205,9 @@ function ContextRows({
106427
107205
  const rows = topContextRows(group);
106428
107206
  if (rows.length === 0) return null;
106429
107207
  const max = Math.max(...rows.map(([, value]) => value), 1);
106430
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106431
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { bold: true, children: title }),
106432
- rows.map(([key, value], index) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(BarRow, { label: contextLabel(key), value, max, tone: index, children: [
107208
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107209
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { bold: true, children: title }),
107210
+ rows.map(([key, value], index) => /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(BarRow, { label: contextLabel(key), value, max, tone: index, children: [
106433
107211
  compactInt(value),
106434
107212
  " tokens"
106435
107213
  ] }, key))
@@ -106442,11 +107220,11 @@ function SavingsRows({
106442
107220
  const rows = topSavingsRows(group);
106443
107221
  if (rows.length === 0) return null;
106444
107222
  const max = Math.max(...rows.map(([, item]) => totalSaved(item)), 1);
106445
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106446
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { bold: true, children: title }),
107223
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107224
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { bold: true, children: title }),
106447
107225
  rows.map(([key, item], index) => {
106448
107226
  const saved = totalSaved(item);
106449
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(BarRow, { label: key, value: saved, max, tone: index, children: [
107227
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(BarRow, { label: key, value: saved, max, tone: index, children: [
106450
107228
  "saved ",
106451
107229
  compactInt(saved),
106452
107230
  " \xB7 in ",
@@ -106471,9 +107249,9 @@ function ActivityRows({
106471
107249
  const rows = topActivityRows(group);
106472
107250
  if (rows.length === 0) return null;
106473
107251
  const max = Math.max(...rows.map(([, item]) => item.calls), 1);
106474
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106475
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { bold: true, children: title }),
106476
- rows.map(([key, item], index) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(BarRow, { label: key, value: item.calls, max, tone: index, children: [
107252
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107253
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { bold: true, children: title }),
107254
+ rows.map(([key, item], index) => /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(BarRow, { label: key, value: item.calls, max, tone: index, children: [
106477
107255
  item.calls,
106478
107256
  " calls \xB7 ",
106479
107257
  item.failures,
@@ -106487,14 +107265,14 @@ function EfficiencyRows({ summary }) {
106487
107265
  const rows = topEfficiencyRows(summary.efficiency.byModel);
106488
107266
  if (rows.length === 0) return null;
106489
107267
  const max = Math.max(...rows.map(([, item]) => item.calls), 1);
106490
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106491
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { bold: true, children: "Model efficiency" }),
106492
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(ThemedText, { dim: true, children: [
107268
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107269
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { bold: true, children: "Model efficiency" }),
107270
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(ThemedText, { dim: true, children: [
106493
107271
  "retry ",
106494
107272
  Math.round(summary.efficiency.retryRatePercent),
106495
107273
  "%"
106496
107274
  ] }),
106497
- rows.map(([key, item], index) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(BarRow, { label: key, value: item.calls, max, tone: index, children: [
107275
+ rows.map(([key, item], index) => /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(BarRow, { label: key, value: item.calls, max, tone: index, children: [
106498
107276
  item.calls,
106499
107277
  " calls \xB7 ",
106500
107278
  compactInt(item.outputTokensPerCall),
@@ -106512,11 +107290,11 @@ function RecentTurns({ rows }) {
106512
107290
  ...recent.map((turn) => turn.savedInputTokens + turn.savedOutputTokens + turn.savedToolResultTokens),
106513
107291
  1
106514
107292
  );
106515
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106516
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { bold: true, children: "Recent token-saving turns" }),
107293
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107294
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { bold: true, children: "Recent token-saving turns" }),
106517
107295
  recent.map((turn, index) => {
106518
107296
  const saved = turn.savedInputTokens + turn.savedOutputTokens + turn.savedToolResultTokens;
106519
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
107297
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
106520
107298
  BarRow,
106521
107299
  {
106522
107300
  label: turn.tokenSavingLevel || "off",
@@ -106540,9 +107318,9 @@ function DailyRows({ summary }) {
106540
107318
  const rows = summary.daily.slice(-5);
106541
107319
  if (rows.length === 0) return null;
106542
107320
  const max = Math.max(...rows.map((day) => (0, import_client_core29.meteredTokens)(day.tokens)), 1);
106543
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106544
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { bold: true, children: "Daily history" }),
106545
- rows.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(BarRow, { label: day.date, value: (0, import_client_core29.meteredTokens)(day.tokens), max, tone: index, children: [
107321
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107322
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { bold: true, children: "Daily history" }),
107323
+ rows.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(BarRow, { label: day.date, value: (0, import_client_core29.meteredTokens)(day.tokens), max, tone: index, children: [
106546
107324
  day.calls,
106547
107325
  " calls \xB7 in ",
106548
107326
  compactInt(day.tokens.input_tokens ?? 0),
@@ -106560,48 +107338,48 @@ function UsageMetricsPanel({
106560
107338
  use_input_default((input, key) => {
106561
107339
  if (key.escape || input === "q") onClose();
106562
107340
  });
106563
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
106564
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(ThemedText, { colorKey: "listSelection", bold: true, children: [
107341
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107342
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(ThemedText, { colorKey: "listSelection", bold: true, children: [
106565
107343
  "Token usage \xB7 ",
106566
107344
  workspace.period
106567
107345
  ] }),
106568
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SummaryBlock, { title: "Workspace", summary: workspace }),
106569
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SummaryBlock, { title: "All Orion tools", summary: global3 }),
106570
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BreakdownRows, { title: "Workspace by model", group: workspace.byModel }),
106571
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BreakdownRows, { title: "Workspace by token saving", group: workspace.byTokenSaving }),
106572
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SavingsRows, { title: "Savings by feature", group: workspace.savings.byFeature }),
106573
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SavingsRows, { title: "Savings by mode", group: workspace.savings.byTokenSavingLevel }),
106574
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ActivityRows, { title: "Tool activity", group: workspace.activity.byCategory }),
106575
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(EfficiencyRows, { summary: workspace }),
106576
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BreakdownRows, { title: "Workspace by agent type", group: workspace.byAgentType }),
106577
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BreakdownRows, { title: "Workspace by reasoning", group: workspace.byReasoningEffort }),
106578
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BreakdownRows, { title: "Workspace by task type", group: workspace.byTaskType }),
106579
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ContextRows, { title: "Workspace context", group: workspace.context }),
106580
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(RecentTurns, { rows: workspace.recentTurns }),
106581
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(DailyRows, { summary: workspace }),
106582
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BreakdownRows, { title: "Global by app", group: global3.byApp }),
106583
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BreakdownRows, { title: "Global by workspace", group: global3.byWorkspace }),
106584
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ThemedText, { dim: true, children: "esc/q close" })
107346
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SummaryBlock, { title: "Workspace", summary: workspace }),
107347
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SummaryBlock, { title: "All Orion tools", summary: global3 }),
107348
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(BreakdownRows, { title: "Workspace by model", group: workspace.byModel }),
107349
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(BreakdownRows, { title: "Workspace by token saving", group: workspace.byTokenSaving }),
107350
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SavingsRows, { title: "Savings by feature", group: workspace.savings.byFeature }),
107351
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(SavingsRows, { title: "Savings by mode", group: workspace.savings.byTokenSavingLevel }),
107352
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ActivityRows, { title: "Tool activity", group: workspace.activity.byCategory }),
107353
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(EfficiencyRows, { summary: workspace }),
107354
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(BreakdownRows, { title: "Workspace by agent type", group: workspace.byAgentType }),
107355
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(BreakdownRows, { title: "Workspace by reasoning", group: workspace.byReasoningEffort }),
107356
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(BreakdownRows, { title: "Workspace by task type", group: workspace.byTaskType }),
107357
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ContextRows, { title: "Workspace context", group: workspace.context }),
107358
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(RecentTurns, { rows: workspace.recentTurns }),
107359
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(DailyRows, { summary: workspace }),
107360
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(BreakdownRows, { title: "Global by app", group: global3.byApp }),
107361
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(BreakdownRows, { title: "Global by workspace", group: global3.byWorkspace }),
107362
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ThemedText, { dim: true, children: "esc/q close" })
106585
107363
  ] });
106586
107364
  }
106587
107365
 
106588
107366
  // src/components/status/WorkingStatus.tsx
106589
- var import_react43 = __toESM(require_react(), 1);
106590
- var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
107367
+ var import_react44 = __toESM(require_react(), 1);
107368
+ var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
106591
107369
  var FRAME_MS = 50;
106592
107370
  function WorkingStatus({
106593
107371
  store,
106594
107372
  label,
106595
107373
  now: now2 = Date.now
106596
107374
  }) {
106597
- const startRef = (0, import_react43.useRef)(now2());
106598
- const wordsRef = (0, import_react43.useRef)(shuffleWords(LOADING_WORDS));
106599
- const wordIdxRef = (0, import_react43.useRef)(0);
106600
- const wordStartRef = (0, import_react43.useRef)(startRef.current);
106601
- const dwellRef = (0, import_react43.useRef)(nextCycleMs());
106602
- const [, forceFrame] = (0, import_react43.useState)(0);
107375
+ const startRef = (0, import_react44.useRef)(now2());
107376
+ const wordsRef = (0, import_react44.useRef)(shuffleWords(LOADING_WORDS));
107377
+ const wordIdxRef = (0, import_react44.useRef)(0);
107378
+ const wordStartRef = (0, import_react44.useRef)(startRef.current);
107379
+ const dwellRef = (0, import_react44.useRef)(nextCycleMs());
107380
+ const [, forceFrame] = (0, import_react44.useState)(0);
106603
107381
  const tokens = useStoreSelector(store, (s) => s.turnOutputTokens);
106604
- (0, import_react43.useEffect)(() => {
107382
+ (0, import_react44.useEffect)(() => {
106605
107383
  const timer = setInterval(() => {
106606
107384
  const n2 = now2();
106607
107385
  if (!label && n2 - startRef.current < META_REVEAL_AFTER_MS && n2 - wordStartRef.current >= dwellRef.current) {
@@ -106624,10 +107402,10 @@ function WorkingStatus({
106624
107402
  const last = cells.length - 1;
106625
107403
  const hint = meterText(turnElapsed, tokens);
106626
107404
  const orb = orbCell(turnElapsed);
106627
- return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(Box2, { flexDirection: "row", marginTop: 1, marginLeft: 1, children: [
106628
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Box2, { width: 2, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Text2, { color: orb.color, children: orb.ch }) }),
106629
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Text2, { children: cells.map((c3, i2) => /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Text2, { color: shimmerColor(n, i2, last), children: c3.ch }, i2)) }),
106630
- hint ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(ThemedText, { dim: true, children: [
107405
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(Box2, { flexDirection: "row", marginTop: 1, marginLeft: 1, children: [
107406
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Box2, { width: 2, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Text2, { color: orb.color, children: orb.ch }) }),
107407
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Text2, { children: cells.map((c3, i2) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Text2, { color: shimmerColor(n, i2, last), children: c3.ch }, i2)) }),
107408
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(ThemedText, { dim: true, children: [
106631
107409
  "\xA0(",
106632
107410
  hint,
106633
107411
  ")"
@@ -106636,24 +107414,24 @@ function WorkingStatus({
106636
107414
  }
106637
107415
 
106638
107416
  // src/components/input/QueuedMessages.tsx
106639
- var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
107417
+ var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
106640
107418
  function QueuedMessages({ store }) {
106641
107419
  const queued = useStoreSelector(store, (s) => s.queuedMessages);
106642
107420
  if (queued.length === 0) return null;
106643
- return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Box2, { flexDirection: "column", children: queued.map((m2, i2) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(UserText, { text: m2 }, i2)) });
107421
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Box2, { flexDirection: "column", children: queued.map((m2, i2) => /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(UserText, { text: m2 }, i2)) });
106644
107422
  }
106645
107423
 
106646
107424
  // src/components/input/PendingAttachments.tsx
106647
- var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
107425
+ var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
106648
107426
  function PendingAttachments({ items: all }) {
106649
107427
  const items = all.filter((a) => a.inlineId === void 0);
106650
107428
  if (items.length === 0) return null;
106651
107429
  let imageN = 0;
106652
- return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(Box2, { flexDirection: "row", marginTop: 1, children: [
106653
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ThemedText, { dim: true, children: "Attachments\xA0\xA0" }),
107430
+ return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(Box2, { flexDirection: "row", marginTop: 1, children: [
107431
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ThemedText, { dim: true, children: "Attachments\xA0\xA0" }),
106654
107432
  items.map((a, i2) => {
106655
107433
  const label = a.kind === "video" ? a.name : a.mime.startsWith("image/") ? `Image ${++imageN}` : a.name;
106656
- return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Box2, { flexDirection: "row", marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(ThemedText, { colorKey: "attachmentBadge", children: [
107434
+ return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(Box2, { flexDirection: "row", marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(ThemedText, { colorKey: "attachmentBadge", children: [
106657
107435
  "[",
106658
107436
  label,
106659
107437
  "]"
@@ -106664,7 +107442,7 @@ function PendingAttachments({ items: all }) {
106664
107442
 
106665
107443
  // src/components/layout/ReplFooter.tsx
106666
107444
  var import_client_core30 = __toESM(require_dist(), 1);
106667
- var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
107445
+ var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
106668
107446
  function ReplFooter({
106669
107447
  appStore,
106670
107448
  onSubmit,
@@ -106674,6 +107452,8 @@ function ReplFooter({
106674
107452
  onPlanApproval,
106675
107453
  onAskUser,
106676
107454
  onWorkPlanApproval,
107455
+ onFeedbackSubmit,
107456
+ onFeedbackDismiss,
106677
107457
  bindings,
106678
107458
  getCompletions,
106679
107459
  slashTokenRanges,
@@ -106692,6 +107472,7 @@ function ReplFooter({
106692
107472
  const pendingPlanApproval = useStoreSelector(appStore, (s) => s.pendingPlanApproval);
106693
107473
  const pendingAskUser = useStoreSelector(appStore, (s) => s.pendingAskUser);
106694
107474
  const pendingWorkPlan = useStoreSelector(appStore, (s) => s.pendingWorkPlan);
107475
+ const pendingFeedback = useStoreSelector(appStore, (s) => s.pendingFeedback);
106695
107476
  const workRun = useStoreSelector(appStore, (s) => s.workRun);
106696
107477
  const plan = useStoreSelector(appStore, (s) => s.plan);
106697
107478
  const subAgents = useStoreSelector(appStore, (s) => s.subAgents);
@@ -106721,24 +107502,24 @@ function ReplFooter({
106721
107502
  (s) => s.pendingPermissions.length > 0 || !!s.pendingPlanApproval || !!s.pendingAskUser || !!s.pendingWorkPlan
106722
107503
  );
106723
107504
  const closePanel = () => appStore.setState((s) => ({ ...s, activePanel: null }));
106724
- return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(import_jsx_runtime67.Fragment, { children: [
106725
- streaming && !parked && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(WorkingStatus, { store: appStore }),
106726
- plan && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(PlanCard, { plan }),
106727
- pendingWorkPlan ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
107505
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
107506
+ streaming && !parked && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(WorkingStatus, { store: appStore }),
107507
+ plan && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(PlanCard, { plan }),
107508
+ pendingWorkPlan ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
106728
107509
  WorkPlanApprovalPrompt,
106729
107510
  {
106730
107511
  pending: pendingWorkPlan,
106731
107512
  onRespond: onWorkPlanApproval ?? (() => void 0),
106732
107513
  onCancel: onInterrupt
106733
107514
  }
106734
- ) : pendingPlanApproval ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
107515
+ ) : pendingPlanApproval ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
106735
107516
  PlanApprovalPrompt,
106736
107517
  {
106737
107518
  pending: pendingPlanApproval,
106738
107519
  onRespond: onPlanApproval ?? (() => void 0),
106739
107520
  onCancel: onInterrupt
106740
107521
  }
106741
- ) : pendingAskUser ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
107522
+ ) : pendingAskUser ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
106742
107523
  AskUserPrompt,
106743
107524
  {
106744
107525
  pending: pendingAskUser,
@@ -106746,14 +107527,14 @@ function ReplFooter({
106746
107527
  onCancel: onInterrupt
106747
107528
  },
106748
107529
  pendingAskUser.requestId
106749
- ) : pendingPermissions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
107530
+ ) : pendingPermissions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
106750
107531
  PermissionPrompt,
106751
107532
  {
106752
107533
  pending: pendingPermissions[0],
106753
107534
  count: pendingPermissions.length,
106754
107535
  onRespond: onPermission ?? (() => void 0)
106755
107536
  }
106756
- ) : activePanel ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ModalFrame, { children: activePanel.kind === "hooks" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(HooksBrowser, { hooks: activePanel.hooks, onClose: closePanel }) : activePanel.kind === "permissions" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
107537
+ ) : activePanel ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ModalFrame, { children: activePanel.kind === "hooks" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(HooksBrowser, { hooks: activePanel.hooks, onClose: closePanel }) : activePanel.kind === "permissions" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
106757
107538
  PermissionRulesPanel,
106758
107539
  {
106759
107540
  rules: activePanel.rules,
@@ -106761,7 +107542,7 @@ function ReplFooter({
106761
107542
  add: activePanel.add,
106762
107543
  onClose: closePanel
106763
107544
  }
106764
- ) : activePanel.kind === "plugin" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(PluginManager, { plugins: activePanel.plugins, act: activePanel.act, onClose: closePanel }) : activePanel.kind === "rewind" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(RewindPicker, { turns: activePanel.turns, apply: activePanel.apply, onClose: closePanel }) : activePanel.kind === "mcp" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(McpManager, { servers: activePanel.servers, approve: activePanel.approve, onClose: closePanel }) : activePanel.kind === "usage" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(UsageMetricsPanel, { workspace: activePanel.workspace, global: activePanel.global, onClose: closePanel }) : activePanel.kind === "endpoints" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(EndpointsPanel, { deps: activePanel.deps, onClose: closePanel }) : null }) : activeDialog ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ModalFrame, { children: activeDialog.kind === "model" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ModelPicker, { dialog: activeDialog }) : activeDialog.kind === "resume" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ResumePicker, { dialog: activeDialog }) : activeDialog.kind === "select" ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
107545
+ ) : activePanel.kind === "plugin" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(PluginManager, { plugins: activePanel.plugins, act: activePanel.act, onClose: closePanel }) : activePanel.kind === "rewind" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(RewindPicker, { turns: activePanel.turns, apply: activePanel.apply, onClose: closePanel }) : activePanel.kind === "mcp" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(McpManager, { servers: activePanel.servers, approve: activePanel.approve, onClose: closePanel }) : activePanel.kind === "usage" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(UsageMetricsPanel, { workspace: activePanel.workspace, global: activePanel.global, onClose: closePanel }) : activePanel.kind === "endpoints" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(EndpointsPanel, { deps: activePanel.deps, onClose: closePanel }) : null }) : activeDialog ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ModalFrame, { children: activeDialog.kind === "model" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ModelPicker, { dialog: activeDialog }) : activeDialog.kind === "resume" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ResumePicker, { dialog: activeDialog }) : activeDialog.kind === "select" ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
106765
107546
  SelectList,
106766
107547
  {
106767
107548
  title: activeDialog.title,
@@ -106769,14 +107550,28 @@ function ReplFooter({
106769
107550
  onSelect: activeDialog.onSelect,
106770
107551
  filterable: true
106771
107552
  }
106772
- ) : /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ConfirmDialog, { dialog: activeDialog }) }) : /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(import_jsx_runtime67.Fragment, { children: [
106773
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(QueuedMessages, { store: appStore }),
106774
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(PendingAttachments, { items: pendingAttachments }),
106775
- status === "error" && statusText ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(ThemedText, { colorKey: "error", bold: true, children: [
107553
+ ) : /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ConfirmDialog, { dialog: activeDialog }) }) : pendingFeedback ? (
107554
+ // The LOWEST ladder entrant: every parked boundary, panel, and dialog outranks
107555
+ // the feedback card, so it only ever appears at turn-complete idle. It takes the
107556
+ // input slot (never rendered beside PromptInput — stacked useInput handlers would
107557
+ // leak digits into the composer) and any stray keystroke gives the slot back.
107558
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
107559
+ FeedbackPrompt,
107560
+ {
107561
+ pending: pendingFeedback,
107562
+ onSubmit: onFeedbackSubmit ?? (() => void 0),
107563
+ onDismiss: onFeedbackDismiss ?? (() => void 0)
107564
+ },
107565
+ pendingFeedback.requestId
107566
+ )
107567
+ ) : /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
107568
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(QueuedMessages, { store: appStore }),
107569
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(PendingAttachments, { items: pendingAttachments }),
107570
+ status === "error" && statusText ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(ThemedText, { colorKey: "error", bold: true, children: [
106776
107571
  "Error: ",
106777
107572
  statusText
106778
107573
  ] }) }) : null,
106779
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
107574
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
106780
107575
  PromptInput,
106781
107576
  {
106782
107577
  onSubmit,
@@ -106804,15 +107599,15 @@ function ReplFooter({
106804
107599
  }
106805
107600
  )
106806
107601
  ] }),
106807
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(StatusBar, { store: appStore, indexBadge }),
106808
- workRun ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(WorkRunGraph, { view: workRun.view }) : null,
106809
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(SubAgentList, { agents: subAgents, awaiting: subagentsAwaiting > 0 })
107602
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(StatusBar, { store: appStore, indexBadge }),
107603
+ workRun ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(WorkRunGraph, { view: workRun.view }) : null,
107604
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(SubAgentList, { agents: subAgents, awaiting: subagentsAwaiting > 0 })
106810
107605
  ] });
106811
107606
  }
106812
107607
 
106813
107608
  // src/components/layout/FullscreenLayout.tsx
106814
- var import_react44 = __toESM(require_react(), 1);
106815
- var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
107609
+ var import_react45 = __toESM(require_react(), 1);
107610
+ var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
106816
107611
  function FullscreenLayout({
106817
107612
  appStore,
106818
107613
  transcriptStore,
@@ -106834,16 +107629,16 @@ function FullscreenLayout({
106834
107629
  onCycleMode
106835
107630
  }) {
106836
107631
  const { columns, rows } = useTerminalSize();
106837
- const scrollRef = (0, import_react44.useRef)(null);
107632
+ const scrollRef = (0, import_react45.useRef)(null);
106838
107633
  const onScroll = (delta) => {
106839
107634
  const sb = scrollRef.current;
106840
107635
  if (!sb) return;
106841
107636
  if (delta <= -1e6) sb.scrollToBottom();
106842
107637
  else sb.scrollBy(-delta);
106843
107638
  };
106844
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(Box2, { flexDirection: "column", width: columns, height: rows, children: [
106845
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ScrollBox2, { ref: scrollRef, flexGrow: 1, flexShrink: 1, flexDirection: "column", stickyScroll: true, children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Transcript, { appStore, transcriptStore }) }),
106846
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Box2, { flexShrink: 0, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
107639
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", width: columns, height: rows, children: [
107640
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ScrollBox2, { ref: scrollRef, flexGrow: 1, flexShrink: 1, flexDirection: "column", stickyScroll: true, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Transcript, { appStore, transcriptStore }) }),
107641
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Box2, { flexShrink: 0, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
106847
107642
  ReplFooter,
106848
107643
  {
106849
107644
  appStore,
@@ -106870,10 +107665,11 @@ function FullscreenLayout({
106870
107665
  }
106871
107666
 
106872
107667
  // src/components/dialogs/AgentsDashboard.tsx
106873
- var import_react45 = __toESM(require_react(), 1);
107668
+ var import_react46 = __toESM(require_react(), 1);
106874
107669
  var import_client_core31 = __toESM(require_dist(), 1);
107670
+ var import_client_ui_core16 = __toESM(require_dist2(), 1);
106875
107671
  var import_strip_ansi4 = __toESM(require_strip_ansi(), 1);
106876
- var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
107672
+ var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
106877
107673
  var POLL_MS = 2500;
106878
107674
  var FIELDS = ["repo_url", "task", "ticket_ref", "target_branch"];
106879
107675
  var FIELD_LABEL = {
@@ -106916,51 +107712,51 @@ function AgentsDashboard({
106916
107712
  onClose
106917
107713
  }) {
106918
107714
  const { rows } = useTerminalSize();
106919
- const [screen, setScreen] = (0, import_react45.useState)({ kind: "list" });
106920
- const [cursor, setCursor] = (0, import_react45.useState)(0);
106921
- const [busy, setBusy] = (0, import_react45.useState)(false);
106922
- const [error, setError] = (0, import_react45.useState)(null);
106923
- const [liveJob, setLiveJob] = (0, import_react45.useState)(null);
106924
- const [events, setEvents] = (0, import_react45.useState)([]);
106925
- const [pollError, setPollError] = (0, import_react45.useState)(null);
106926
- const [diff3, setDiff] = (0, import_react45.useState)(null);
106927
- const diffFetchedFor = (0, import_react45.useRef)(null);
106928
- const [liveItems, setLiveItems] = (0, import_react45.useState)([]);
106929
- const [liveTerm, setLiveTerm] = (0, import_react45.useState)("");
106930
- const [liveFrames, setLiveFrames] = (0, import_react45.useState)(0);
106931
- const liveIdRef = (0, import_react45.useRef)(0);
106932
- const [messaging, setMessaging] = (0, import_react45.useState)(false);
106933
- const [messageText, setMessageText] = (0, import_react45.useState)("");
106934
- const [messageNote, setMessageNote] = (0, import_react45.useState)(null);
106935
- const [tokenStatus, setTokenStatus] = (0, import_react45.useState)(null);
106936
- const [tokenBusy, setTokenBusy] = (0, import_react45.useState)(false);
106937
- const [tokenNote, setTokenNote] = (0, import_react45.useState)(null);
106938
- const [tokenInput, setTokenInput] = (0, import_react45.useState)(false);
106939
- const [tokenDraft, setTokenDraft] = (0, import_react45.useState)("");
106940
- const [jiraStatus, setJiraStatus] = (0, import_react45.useState)(null);
106941
- const [jiraBusy, setJiraBusy] = (0, import_react45.useState)(false);
106942
- const [jiraNote, setJiraNote] = (0, import_react45.useState)(null);
106943
- const [jiraInput, setJiraInput] = (0, import_react45.useState)(null);
106944
- const [form, setForm] = (0, import_react45.useState)(EMPTY_FORM);
106945
- const [field2, setField] = (0, import_react45.useState)(0);
107715
+ const [screen, setScreen] = (0, import_react46.useState)({ kind: "list" });
107716
+ const [cursor, setCursor] = (0, import_react46.useState)(0);
107717
+ const [busy, setBusy] = (0, import_react46.useState)(false);
107718
+ const [error, setError] = (0, import_react46.useState)(null);
107719
+ const [liveJob, setLiveJob] = (0, import_react46.useState)(null);
107720
+ const [events, setEvents] = (0, import_react46.useState)([]);
107721
+ const [pollError, setPollError] = (0, import_react46.useState)(null);
107722
+ const [diff3, setDiff] = (0, import_react46.useState)(null);
107723
+ const diffFetchedFor = (0, import_react46.useRef)(null);
107724
+ const [liveItems, setLiveItems] = (0, import_react46.useState)([]);
107725
+ const [liveTerm, setLiveTerm] = (0, import_react46.useState)("");
107726
+ const [liveFrames, setLiveFrames] = (0, import_react46.useState)(0);
107727
+ const liveIdRef = (0, import_react46.useRef)(0);
107728
+ const [messaging, setMessaging] = (0, import_react46.useState)(false);
107729
+ const [messageText, setMessageText] = (0, import_react46.useState)("");
107730
+ const [messageNote, setMessageNote] = (0, import_react46.useState)(null);
107731
+ const [tokenStatus, setTokenStatus] = (0, import_react46.useState)(null);
107732
+ const [tokenBusy, setTokenBusy] = (0, import_react46.useState)(false);
107733
+ const [tokenNote, setTokenNote] = (0, import_react46.useState)(null);
107734
+ const [tokenInput, setTokenInput] = (0, import_react46.useState)(false);
107735
+ const [tokenDraft, setTokenDraft] = (0, import_react46.useState)("");
107736
+ const [jiraStatus, setJiraStatus] = (0, import_react46.useState)(null);
107737
+ const [jiraBusy, setJiraBusy] = (0, import_react46.useState)(false);
107738
+ const [jiraNote, setJiraNote] = (0, import_react46.useState)(null);
107739
+ const [jiraInput, setJiraInput] = (0, import_react46.useState)(null);
107740
+ const [form, setForm] = (0, import_react46.useState)(EMPTY_FORM);
107741
+ const [field2, setField] = (0, import_react46.useState)(0);
106946
107742
  const jobs = panel.jobs;
106947
107743
  const safeCursor = Math.min(cursor, Math.max(0, jobs.length - 1));
106948
107744
  const detailId = screen.kind === "detail" ? screen.id : null;
106949
107745
  const detailJob = detailId ? liveJob ?? jobs.find((j2) => j2.id === detailId) ?? null : null;
106950
- const panelRef = (0, import_react45.useRef)(panel);
107746
+ const panelRef = (0, import_react46.useRef)(panel);
106951
107747
  panelRef.current = panel;
106952
- const screenRef = (0, import_react45.useRef)(screen);
107748
+ const screenRef = (0, import_react46.useRef)(screen);
106953
107749
  screenRef.current = screen;
106954
- const oauthAlive = (0, import_react45.useRef)(true);
106955
- const oauthTimer = (0, import_react45.useRef)(null);
106956
- (0, import_react45.useEffect)(
107750
+ const oauthAlive = (0, import_react46.useRef)(true);
107751
+ const oauthTimer = (0, import_react46.useRef)(null);
107752
+ (0, import_react46.useEffect)(
106957
107753
  () => () => {
106958
107754
  oauthAlive.current = false;
106959
107755
  if (oauthTimer.current) clearTimeout(oauthTimer.current);
106960
107756
  },
106961
107757
  []
106962
107758
  );
106963
- (0, import_react45.useEffect)(() => {
107759
+ (0, import_react46.useEffect)(() => {
106964
107760
  if (!detailId) return;
106965
107761
  let cancelled = false;
106966
107762
  let timer = null;
@@ -107002,7 +107798,7 @@ function AgentsDashboard({
107002
107798
  };
107003
107799
  }, [detailId]);
107004
107800
  const branchName = detailJob?.branch_name ?? null;
107005
- (0, import_react45.useEffect)(() => {
107801
+ (0, import_react46.useEffect)(() => {
107006
107802
  if (!detailId || !branchName) return;
107007
107803
  const key = `${detailId}:${branchName}`;
107008
107804
  if (diffFetchedFor.current === key) return;
@@ -107020,7 +107816,7 @@ function AgentsDashboard({
107020
107816
  };
107021
107817
  }, [detailId, branchName]);
107022
107818
  const liveSessionId = detailJob && !(0, import_client_core31.isTerminal)(detailJob.status) && detailJob.session_id ? detailJob.session_id : null;
107023
- (0, import_react45.useEffect)(() => {
107819
+ (0, import_react46.useEffect)(() => {
107024
107820
  if (!liveSessionId) return;
107025
107821
  liveIdRef.current = 0;
107026
107822
  setLiveItems([]);
@@ -107041,7 +107837,7 @@ function AgentsDashboard({
107041
107837
  });
107042
107838
  return () => sub.dispose();
107043
107839
  }, [liveSessionId]);
107044
- (0, import_react45.useEffect)(() => {
107840
+ (0, import_react46.useEffect)(() => {
107045
107841
  let cancelled = false;
107046
107842
  void (async () => {
107047
107843
  try {
@@ -107379,15 +108175,15 @@ function AgentsDashboard({
107379
108175
  return runAction(() => panel.cancel(here.id));
107380
108176
  }
107381
108177
  });
107382
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", height: rows, paddingX: 1, children: [
107383
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexShrink: 0, marginBottom: 1, children: [
107384
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "welcomeBanner", bold: true, children: "Cloud Agents" }),
107385
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: ` ${jobs.length} ${jobs.length === 1 ? "agent" : "agents"}` }),
107386
- busy ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "spinner", children: " working\u2026" }) : null
108178
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", height: rows, paddingX: 1, children: [
108179
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexShrink: 0, marginBottom: 1, children: [
108180
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "welcomeBanner", bold: true, children: "Cloud Agents" }),
108181
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: ` ${jobs.length} ${jobs.length === 1 ? "agent" : "agents"}` }),
108182
+ busy ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "spinner", children: " working\u2026" }) : null
107387
108183
  ] }),
107388
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexGrow: 1, flexDirection: "column", children: [
107389
- error ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Box2, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "error", children: error }) }) : null,
107390
- screen.kind === "launch" ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(LaunchFormView, { form, field: field2 }) : screen.kind === "detail" ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
108184
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexGrow: 1, flexDirection: "column", children: [
108185
+ error ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Box2, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "error", children: error }) }) : null,
108186
+ screen.kind === "launch" ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(LaunchFormView, { form, field: field2 }) : screen.kind === "detail" ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
107391
108187
  JobDetailView,
107392
108188
  {
107393
108189
  job: detailJob,
@@ -107410,7 +108206,7 @@ function AgentsDashboard({
107410
108206
  complete: detailJob?.status === "complete"
107411
108207
  }
107412
108208
  }
107413
- ) : screen.kind === "connections" ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
108209
+ ) : screen.kind === "connections" ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
107414
108210
  ConnectionsView,
107415
108211
  {
107416
108212
  token: {
@@ -107422,9 +108218,9 @@ function AgentsDashboard({
107422
108218
  },
107423
108219
  jira: { status: jiraStatus, busy: jiraBusy, input: jiraInput, note: jiraNote }
107424
108220
  }
107425
- ) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(JobListView, { jobs, cursor: safeCursor, rows })
108221
+ ) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(JobListView, { jobs, cursor: safeCursor, rows })
107426
108222
  ] }),
107427
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Box2, { flexShrink: 0, marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: footerHint(screen, screen.kind === "detail" ? detailJob : jobs[safeCursor] ?? null, messaging, {
108223
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Box2, { flexShrink: 0, marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: footerHint(screen, screen.kind === "detail" ? detailJob : jobs[safeCursor] ?? null, messaging, {
107428
108224
  input: tokenInput || jiraInput !== null,
107429
108225
  token: tokenStatus,
107430
108226
  jira: jiraStatus
@@ -107464,9 +108260,9 @@ function ConnectionsView({
107464
108260
  token,
107465
108261
  jira
107466
108262
  }) {
107467
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", children: [
107468
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "Connect the accounts your agents use. Both are optional \u2014 public repos need neither." }),
107469
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Box2, { marginTop: 1, children: token.status && token.status.storage_available ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
108263
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", children: [
108264
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "Connect the accounts your agents use. Both are optional \u2014 public repos need neither." }),
108265
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Box2, { marginTop: 1, children: token.status && token.status.storage_available ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
107470
108266
  TokenLine,
107471
108267
  {
107472
108268
  status: token.status,
@@ -107475,8 +108271,8 @@ function ConnectionsView({
107475
108271
  draft: token.draft,
107476
108272
  note: token.note
107477
108273
  }
107478
- ) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "GitHub connections are unavailable on this server." }) }),
107479
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Box2, { marginTop: 1, children: jira.status && jira.status.storage_available ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(JiraLine, { status: jira.status, busy: jira.busy, input: jira.input, note: jira.note }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "Jira connections are unavailable on this server." }) })
108274
+ ) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "GitHub connections are unavailable on this server." }) }),
108275
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Box2, { marginTop: 1, children: jira.status && jira.status.storage_available ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(JiraLine, { status: jira.status, busy: jira.busy, input: jira.input, note: jira.note }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "Jira connections are unavailable on this server." }) })
107480
108276
  ] });
107481
108277
  }
107482
108278
  function TokenLine({
@@ -107487,23 +108283,23 @@ function TokenLine({
107487
108283
  note
107488
108284
  }) {
107489
108285
  if (input) {
107490
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { children: [
107491
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "GitHub token: " }),
108286
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { children: [
108287
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "GitHub token: " }),
107492
108288
  "\u2022".repeat(draft.length),
107493
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" }),
107494
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: " enter save \xB7 esc cancel" })
108289
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" }),
108290
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: " enter save \xB7 esc cancel" })
107495
108291
  ] });
107496
108292
  }
107497
108293
  if (status.configured) {
107498
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { children: [
107499
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "success", children: "\u2713 GitHub connected" }),
107500
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: ` ${status.hint ?? "saved"} \xB7 x to remove` }),
107501
- note ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "info", children: ` ${note}` }) : null
108294
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { children: [
108295
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "success", children: "\u2713 GitHub connected" }),
108296
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: ` ${status.hint ?? "saved"} \xB7 x to remove` }),
108297
+ note ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "info", children: ` ${note}` }) : null
107502
108298
  ] });
107503
108299
  }
107504
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { children: [
107505
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "warning", children: "GitHub not connected" }),
107506
- note ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: ` ${note}` }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: busy ? " working\u2026" : status.oauth_available ? " \xB7 o to connect with GitHub (recommended) \xB7 g for a token" : " \xB7 g to connect for private repos" })
108300
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { children: [
108301
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "warning", children: "GitHub not connected" }),
108302
+ note ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: ` ${note}` }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: busy ? " working\u2026" : status.oauth_available ? " \xB7 o to connect with GitHub (recommended) \xB7 g for a token" : " \xB7 g to connect for private repos" })
107507
108303
  ] });
107508
108304
  }
107509
108305
  function JiraLine({
@@ -107515,23 +108311,23 @@ function JiraLine({
107515
108311
  if (input) {
107516
108312
  const label = input.step === "url" ? "Jira URL (https://\u2026): " : input.step === "email" ? "Jira email (empty = Server PAT): " : "Jira API token: ";
107517
108313
  const shown = input.step === "token" ? "\u2022".repeat(input.draft.length) : input.draft;
107518
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { children: [
107519
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: label }),
108314
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { children: [
108315
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: label }),
107520
108316
  shown,
107521
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" }),
107522
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: " enter next \xB7 esc cancel" })
108317
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" }),
108318
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: " enter next \xB7 esc cancel" })
107523
108319
  ] });
107524
108320
  }
107525
108321
  if (status.configured) {
107526
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { children: [
107527
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "success", children: "\u2713 Jira connected" }),
107528
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: ` ${status.base_url ?? ""} ${status.hint ?? ""} \xB7 t replace \xB7 T remove` }),
107529
- note ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "info", children: ` ${note}` }) : null
108322
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { children: [
108323
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "success", children: "\u2713 Jira connected" }),
108324
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: ` ${status.base_url ?? ""} ${status.hint ?? ""} \xB7 t replace \xB7 T remove` }),
108325
+ note ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "info", children: ` ${note}` }) : null
107530
108326
  ] });
107531
108327
  }
107532
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { children: [
107533
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "Jira not connected" }),
107534
- note ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: ` ${note}` }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: busy ? " working\u2026" : " \xB7 t to connect (launch agents from tickets)" })
108328
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { children: [
108329
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "Jira not connected" }),
108330
+ note ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: ` ${note}` }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: busy ? " working\u2026" : " \xB7 t to connect (launch agents from tickets)" })
107535
108331
  ] });
107536
108332
  }
107537
108333
  function JobListView({
@@ -107540,14 +108336,14 @@ function JobListView({
107540
108336
  rows
107541
108337
  }) {
107542
108338
  if (jobs.length === 0) {
107543
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "No cloud agents yet. Press n to launch one." });
108339
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "No cloud agents yet. Press n to launch one." });
107544
108340
  }
107545
108341
  const maxRows = Math.max(3, rows - 6);
107546
108342
  const windowed = jobs.length > maxRows;
107547
108343
  const start2 = windowed ? Math.max(0, Math.min(cursor - Math.floor(maxRows / 2), jobs.length - maxRows)) : 0;
107548
108344
  const end = windowed ? Math.min(start2 + maxRows, jobs.length) : jobs.length;
107549
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", children: [
107550
- windowed && start2 > 0 ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { dim: true, children: [
108345
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", children: [
108346
+ windowed && start2 > 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { dim: true, children: [
107551
108347
  "\u2191 ",
107552
108348
  start2,
107553
108349
  " more"
@@ -107557,14 +108353,14 @@ function JobListView({
107557
108353
  const selected = i2 === cursor;
107558
108354
  const label = jobTitle(job);
107559
108355
  const repo = job.repo_url ? ` ${job.repo_url}` : "";
107560
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "row", children: [
107561
- selected ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(GradientText, { text: "\u276F " }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { children: " " }),
107562
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Box2, { width: 18, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: statusColorKey(job.status), wrap: "truncate", children: job.status }) }),
107563
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { wrap: "truncate-end", children: label }),
107564
- repo ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: repo }) : null
108356
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "row", children: [
108357
+ selected ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(GradientText, { text: "\u276F " }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { children: " " }),
108358
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Box2, { width: 18, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: statusColorKey(job.status), wrap: "truncate", children: job.status }) }),
108359
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { wrap: "truncate-end", children: label }),
108360
+ repo ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: repo }) : null
107565
108361
  ] }, job.id);
107566
108362
  }),
107567
- windowed && end < jobs.length ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { dim: true, children: [
108363
+ windowed && end < jobs.length ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { dim: true, children: [
107568
108364
  "\u2193 ",
107569
108365
  jobs.length - end,
107570
108366
  " more"
@@ -107572,12 +108368,12 @@ function JobListView({
107572
108368
  ] });
107573
108369
  }
107574
108370
  function ChangedFileRow({ file }) {
107575
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { wrap: "truncate-end", children: [
107576
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: fileStatusColor(file.status), bold: true, children: (file.status[0] ?? "?").toUpperCase() }),
108371
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { wrap: "truncate-end", children: [
108372
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: fileStatusColor(file.status), bold: true, children: (file.status[0] ?? "?").toUpperCase() }),
107577
108373
  ` ${file.path} `,
107578
- file.additions > 0 ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "success", children: `+${file.additions}` }) : null,
108374
+ file.additions > 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "success", children: `+${file.additions}` }) : null,
107579
108375
  file.additions > 0 && file.deletions > 0 ? " " : "",
107580
- file.deletions > 0 ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "error", children: `\u2212${file.deletions}` }) : null
108376
+ file.deletions > 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "error", children: `\u2212${file.deletions}` }) : null
107581
108377
  ] });
107582
108378
  }
107583
108379
  function JobDetailView({
@@ -107590,103 +108386,103 @@ function JobDetailView({
107590
108386
  frames,
107591
108387
  composer
107592
108388
  }) {
107593
- if (!job) return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "Job not found." });
108389
+ if (!job) return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "Job not found." });
107594
108390
  const terminal = (0, import_client_core31.isTerminal)(job.status);
107595
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", children: [
107596
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: jobTitle(job) }),
107597
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107598
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { children: [
108391
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", children: [
108392
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: jobTitle(job) }),
108393
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
108394
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { children: [
107599
108395
  "status:",
107600
108396
  " ",
107601
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: statusColorKey(job.status), bold: true, children: job.status }),
108397
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: statusColorKey(job.status), bold: true, children: job.status }),
107602
108398
  ` \xB7 iteration ${job.iteration}`
107603
108399
  ] }),
107604
- job.repo_url ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { dim: true, children: [
108400
+ job.repo_url ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { dim: true, children: [
107605
108401
  "repo: ",
107606
108402
  job.repo_url
107607
108403
  ] }) : null,
107608
- job.target_branch ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { dim: true, children: [
108404
+ job.target_branch ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { dim: true, children: [
107609
108405
  "target: ",
107610
108406
  job.target_branch
107611
108407
  ] }) : null,
107612
- job.branch_name ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { dim: true, children: [
108408
+ job.branch_name ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { dim: true, children: [
107613
108409
  "branch: ",
107614
108410
  job.branch_name
107615
108411
  ] }) : null,
107616
- job.pr_url ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { colorKey: "info", underline: true, children: [
108412
+ job.pr_url ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { colorKey: "info", underline: true, children: [
107617
108413
  "PR: ",
107618
108414
  job.pr_url
107619
108415
  ] }) : null,
107620
- job.error ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { colorKey: "error", children: [
108416
+ job.error ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { colorKey: "error", children: [
107621
108417
  "error: ",
107622
108418
  job.error
107623
108419
  ] }) : null
107624
108420
  ] }),
107625
- job.report ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexShrink: 0, flexDirection: "column", marginTop: 1, children: [
107626
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { bold: true, children: "Summary" }),
107627
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { children: job.report })
108421
+ job.report ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexShrink: 0, flexDirection: "column", marginTop: 1, children: [
108422
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { bold: true, children: "Summary" }),
108423
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { children: job.report })
107628
108424
  ] }) : null,
107629
- job.branch_name ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107630
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { bold: true, children: [
108425
+ job.branch_name ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
108426
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { bold: true, children: [
107631
108427
  "Changed files",
107632
108428
  diff3 ? ` (${diff3.total})` : ""
107633
108429
  ] }),
107634
- !diff3 ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "loading\u2026" }) : diff3.files.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "No file changes." }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
107635
- diff3.files.map((f) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ChangedFileRow, { file: f }, `${f.old_path ?? ""}:${f.path}`)),
107636
- diff3.truncated ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "\u2026more files changed than shown." }) : null
108430
+ !diff3 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "loading\u2026" }) : diff3.files.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "No file changes." }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
108431
+ diff3.files.map((f) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ChangedFileRow, { file: f }, `${f.old_path ?? ""}:${f.path}`)),
108432
+ diff3.truncated ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "\u2026more files changed than shown." }) : null
107637
108433
  ] })
107638
108434
  ] }) : null,
107639
- !terminal ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107640
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { bold: true, children: "Live" }),
107641
- live.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: "Waiting for the agent\u2026" }) : (
108435
+ !terminal ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
108436
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { bold: true, children: "Live" }),
108437
+ live.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: "Waiting for the agent\u2026" }) : (
107642
108438
  // The detail view lives inside a fixed-height column (`height={rows}`) — when the
107643
108439
  // terminal tail is showing, the thread cedes rows to it so yoga never has to
107644
108440
  // shrink the section headers away on a small terminal.
107645
108441
  live.slice(term ? -4 : -8).map(
107646
- (it) => it.kind === "text" ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { wrap: "truncate-end", children: it.text.length > 500 ? `\u2026${it.text.slice(-500)}` : it.text }, it.id) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: `\u2192 ${it.name}` }, it.id)
108442
+ (it) => it.kind === "text" ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { wrap: "truncate-end", children: it.text.length > 500 ? `\u2026${it.text.slice(-500)}` : it.text }, it.id) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: `\u2192 ${(0, import_client_ui_core16.toolDisplayName)(it.name)}` }, it.id)
107647
108443
  )
107648
108444
  ),
107649
- frames > 0 ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: `\u{1F5A5} screen streaming \xB7 ${frames} frame${frames === 1 ? "" : "s"} (view in the desktop app)` }) : null,
107650
- term ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
107651
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { bold: true, children: "Terminal" }),
107652
- term.split("\n").slice(-4).map((line, i2) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: (line.split("\r").pop() ?? "").replace(
108445
+ frames > 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: `\u{1F5A5} screen streaming \xB7 ${frames} frame${frames === 1 ? "" : "s"} (view in the desktop app)` }) : null,
108446
+ term ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
108447
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { bold: true, children: "Terminal" }),
108448
+ term.split("\n").slice(-4).map((line, i2) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: (line.split("\r").pop() ?? "").replace(
107653
108449
  // eslint-disable-next-line no-control-regex
107654
108450
  /[\u0000-\u0008\u000b-\u001f\u007f]/g,
107655
108451
  ""
107656
108452
  ) || " " }, i2))
107657
108453
  ] }) : null
107658
108454
  ] }) : null,
107659
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107660
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { bold: true, children: "Timeline" }),
107661
- events.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: terminal ? "No events." : "Waiting for events\u2026" }) : events.map((e) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { wrap: "truncate-end", children: `\u2022 ${formatEvent(e)}` }, e.id)),
107662
- !terminal ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: pollError ? `polling\u2026 (${pollError})` : "polling\u2026" }) : null
108455
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
108456
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { bold: true, children: "Timeline" }),
108457
+ events.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: terminal ? "No events." : "Waiting for events\u2026" }) : events.map((e) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { wrap: "truncate-end", children: `\u2022 ${formatEvent(e)}` }, e.id)),
108458
+ !terminal ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: pollError ? `polling\u2026 (${pollError})` : "polling\u2026" }) : null
107663
108459
  ] }),
107664
- composer.live ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
107665
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { bold: true, children: composer.complete ? "Follow up on this run" : composer.parked ? "Resume the agent" : "Message the agent" }),
107666
- composer.messaging ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { children: [
108460
+ composer.live ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
108461
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { bold: true, children: composer.complete ? "Follow up on this run" : composer.parked ? "Resume the agent" : "Message the agent" }),
108462
+ composer.messaging ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { children: [
107667
108463
  "\u276F ",
107668
108464
  composer.text,
107669
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" })
107670
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { dim: true, children: composer.complete ? "press m to start a follow-up run (same branch/PR while it's open)" : composer.parked ? "press m to resume with an optional direction" : "press m to steer the agent without stopping it" }),
107671
- composer.note ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "info", children: composer.note }) : null
108465
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" })
108466
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { dim: true, children: composer.complete ? "press m to start a follow-up run (same branch/PR while it's open)" : composer.parked ? "press m to resume with an optional direction" : "press m to steer the agent without stopping it" }),
108467
+ composer.note ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "info", children: composer.note }) : null
107672
108468
  ] }) : null
107673
108469
  ] });
107674
108470
  }
107675
108471
  function LaunchFormView({ form, field: field2 }) {
107676
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "column", children: [
107677
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: "Launch a cloud agent" }),
107678
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Box2, { flexDirection: "column", marginTop: 1, children: FIELDS.map((name2, i2) => {
108472
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", children: [
108473
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: "Launch a cloud agent" }),
108474
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Box2, { flexDirection: "column", marginTop: 1, children: FIELDS.map((name2, i2) => {
107679
108475
  const focused = i2 === field2;
107680
108476
  const value = form[name2];
107681
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(Box2, { flexDirection: "row", children: [
107682
- focused ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(GradientText, { text: "\u276F " }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { children: " " }),
107683
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Box2, { width: 26, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: focused ? "accent" : void 0, children: FIELD_LABEL[name2] }) }),
107684
- value ? /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { children: [
108477
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "row", children: [
108478
+ focused ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(GradientText, { text: "\u276F " }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { children: " " }),
108479
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Box2, { width: 26, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: focused ? "accent" : void 0, children: FIELD_LABEL[name2] }) }),
108480
+ value ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { children: [
107685
108481
  value,
107686
- focused ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" }) : null
107687
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
107688
- focused ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" }) : null,
107689
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ThemedText, { dim: true, children: [
108482
+ focused ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" }) : null
108483
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
108484
+ focused ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ThemedText, { colorKey: "chatInputBox", children: "\u258F" }) : null,
108485
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(ThemedText, { dim: true, children: [
107690
108486
  " ",
107691
108487
  focused ? "type a value" : "\u2014"
107692
108488
  ] })
@@ -107697,14 +108493,14 @@ function LaunchFormView({ form, field: field2 }) {
107697
108493
  }
107698
108494
 
107699
108495
  // src/components/layout/TerminalTitle.tsx
107700
- var import_react47 = __toESM(require_react(), 1);
108496
+ var import_react48 = __toESM(require_react(), 1);
107701
108497
 
107702
108498
  // src/vendor/ink/hooks/use-terminal-title.ts
107703
- var import_react46 = __toESM(require_react(), 1);
108499
+ var import_react47 = __toESM(require_react(), 1);
107704
108500
  var import_strip_ansi5 = __toESM(require_strip_ansi(), 1);
107705
108501
  function useTerminalTitle(title) {
107706
- const writeRaw = (0, import_react46.useContext)(TerminalWriteContext);
107707
- (0, import_react46.useEffect)(() => {
108502
+ const writeRaw = (0, import_react47.useContext)(TerminalWriteContext);
108503
+ (0, import_react47.useEffect)(() => {
107708
108504
  if (title === null || !writeRaw) return;
107709
108505
  const clean = (0, import_strip_ansi5.default)(title);
107710
108506
  if (process.platform === "win32") {
@@ -107730,8 +108526,8 @@ function composeTerminalTitle(sessionTitle, streaming, frame) {
107730
108526
  function TerminalTitle({ appStore }) {
107731
108527
  const sessionTitle = useStoreSelector(appStore, (s) => s.sessionTitle);
107732
108528
  const streaming = useStoreSelector(appStore, (s) => s.status === "streaming");
107733
- const [frame, setFrame] = (0, import_react47.useState)(0);
107734
- (0, import_react47.useEffect)(() => {
108529
+ const [frame, setFrame] = (0, import_react48.useState)(0);
108530
+ (0, import_react48.useEffect)(() => {
107735
108531
  if (!streaming) return;
107736
108532
  const id = setInterval(
107737
108533
  () => setFrame((f) => (f + 1) % TITLE_ANIMATION_FRAMES.length),
@@ -107744,20 +108540,20 @@ function TerminalTitle({ appStore }) {
107744
108540
  }
107745
108541
 
107746
108542
  // src/components/layout/ReplLayout.tsx
107747
- var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
108543
+ var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
107748
108544
  function ReplLayout(props) {
107749
108545
  const panel = useStoreSelector(props.appStore, (s) => s.activePanel);
107750
- const title = /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(TerminalTitle, { appStore: props.appStore });
108546
+ const title = /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(TerminalTitle, { appStore: props.appStore });
107751
108547
  if (panel?.kind === "agents") {
107752
108548
  const closePanel = () => props.appStore.setState((s) => ({ ...s, activePanel: null }));
107753
- return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
108549
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_jsx_runtime71.Fragment, { children: [
107754
108550
  title,
107755
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(AgentsDashboard, { panel, onClose: closePanel })
108551
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(AgentsDashboard, { panel, onClose: closePanel })
107756
108552
  ] });
107757
108553
  }
107758
- return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
108554
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_jsx_runtime71.Fragment, { children: [
107759
108555
  title,
107760
- isFullscreen() ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(FullscreenLayout, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(NativeLayout, { ...props })
108556
+ isFullscreen() ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(FullscreenLayout, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(NativeLayout, { ...props })
107761
108557
  ] });
107762
108558
  }
107763
108559
  function NativeLayout({
@@ -107770,6 +108566,8 @@ function NativeLayout({
107770
108566
  onPlanApproval,
107771
108567
  onAskUser,
107772
108568
  onWorkPlanApproval,
108569
+ onFeedbackSubmit,
108570
+ onFeedbackDismiss,
107773
108571
  bindings,
107774
108572
  getCompletions,
107775
108573
  slashTokenRanges,
@@ -107782,9 +108580,9 @@ function NativeLayout({
107782
108580
  onCycleMode
107783
108581
  }) {
107784
108582
  const { columns } = useTerminalSize();
107785
- return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(Box2, { flexDirection: "column", width: columns, children: [
107786
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Transcript, { appStore, transcriptStore, evictionEnabled: true }),
107787
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Box2, { flexShrink: 0, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
108583
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(Box2, { flexDirection: "column", width: columns, children: [
108584
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Transcript, { appStore, transcriptStore, evictionEnabled: true }),
108585
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Box2, { flexShrink: 0, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
107788
108586
  ReplFooter,
107789
108587
  {
107790
108588
  appStore,
@@ -107795,6 +108593,8 @@ function NativeLayout({
107795
108593
  onPlanApproval,
107796
108594
  onAskUser,
107797
108595
  onWorkPlanApproval,
108596
+ onFeedbackSubmit,
108597
+ onFeedbackDismiss,
107798
108598
  bindings,
107799
108599
  getCompletions,
107800
108600
  slashTokenRanges,
@@ -107811,10 +108611,10 @@ function NativeLayout({
107811
108611
  }
107812
108612
 
107813
108613
  // src/app.tsx
107814
- var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
108614
+ var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
107815
108615
  function App2(props) {
107816
108616
  const themeName = useStoreSelector(props.appStore, (s) => s.themeName);
107817
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ThemeProvider, { value: getTheme(themeName), children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(ReplLayout, { ...props }) });
108617
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ThemeProvider, { value: getTheme(themeName), children: /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ReplLayout, { ...props }) });
107818
108618
  }
107819
108619
 
107820
108620
  // src/components/Root.tsx
@@ -107828,11 +108628,11 @@ function Root({
107828
108628
  }
107829
108629
 
107830
108630
  // src/components/layout/SignInScreen.tsx
107831
- var import_react49 = __toESM(require_react(), 1);
108631
+ var import_react50 = __toESM(require_react(), 1);
107832
108632
  var import_client_core32 = __toESM(require_dist(), 1);
107833
108633
 
107834
108634
  // src/components/layout/splash/Splash.tsx
107835
- var import_react48 = __toESM(require_react(), 1);
108635
+ var import_react49 = __toESM(require_react(), 1);
107836
108636
 
107837
108637
  // src/components/layout/splash/halfblock.ts
107838
108638
  var BLOCK = [" ", "\u2580", "\u2584", "\u2588"];
@@ -108124,7 +108924,7 @@ function toSpans(row) {
108124
108924
  }
108125
108925
 
108126
108926
  // src/components/layout/splash/Splash.tsx
108127
- var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
108927
+ var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
108128
108928
  var TONE = {
108129
108929
  starBright: "welcomeBanner",
108130
108930
  starMid: "accent",
@@ -108151,18 +108951,18 @@ var TONE = {
108151
108951
  function Splash({ columns, rows, frame, copy }) {
108152
108952
  const theme = useTheme();
108153
108953
  const height = splashHeight(rows);
108154
- const shell2 = import_react48.default.useMemo(() => orbShell(), []);
108954
+ const shell2 = import_react49.default.useMemo(() => orbShell(), []);
108155
108955
  const grid = splashFrame({ width: columns, rows: height, frame, shell: shell2, copy });
108156
- return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Box2, { flexDirection: "column", children: grid.map((spans, y2) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Text2, { wrap: "truncate", children: spans.length === 0 ? " " : spans.map((span, i2) => renderSpan(span, i2, theme)) }, y2)) });
108956
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Box2, { flexDirection: "column", children: grid.map((spans, y2) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Text2, { wrap: "truncate", children: spans.length === 0 ? " " : spans.map((span, i2) => renderSpan(span, i2, theme)) }, y2)) });
108157
108957
  }
108158
108958
  function renderSpan(span, key, theme) {
108159
- if (span.tone === void 0) return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Text2, { children: span.text }, key);
108959
+ if (span.tone === void 0) return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Text2, { children: span.text }, key);
108160
108960
  if (span.tone === "tagline") {
108161
108961
  const chars = [...span.text];
108162
108962
  const last = Math.max(1, chars.length - 1);
108163
- return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Text2, { children: chars.map((ch, i2) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Text2, { color: gradientAt(i2 / last), children: ch }, i2)) }, key);
108963
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Text2, { children: chars.map((ch, i2) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Text2, { color: gradientAt(i2 / last), children: ch }, i2)) }, key);
108164
108964
  }
108165
- return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Text2, { color: theme[TONE[span.tone]], bold: span.bold, children: span.text }, key);
108965
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Text2, { color: theme[TONE[span.tone]], bold: span.bold, children: span.text }, key);
108166
108966
  }
108167
108967
 
108168
108968
  // src/services/terminal.ts
@@ -108184,7 +108984,7 @@ function detectTerminal2(env3 = process.env, platform2 = process.platform) {
108184
108984
  }
108185
108985
 
108186
108986
  // src/components/layout/SignInScreen.tsx
108187
- var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
108987
+ var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);
108188
108988
  var TICK_MS = 150;
108189
108989
  function splashDisabled() {
108190
108990
  const v2 = (process.env.ORION_SPLASH ?? "").toLowerCase();
@@ -108197,15 +108997,15 @@ function SignInScreen({
108197
108997
  onSignedIn
108198
108998
  }) {
108199
108999
  const { exit } = use_app_default();
108200
- const [phase, setPhase] = import_react49.default.useState("idle");
108201
- const [url, setUrl] = import_react49.default.useState(null);
108202
- const [error, setError] = import_react49.default.useState(null);
108203
- const [frame, setFrame] = import_react49.default.useState(0);
109000
+ const [phase, setPhase] = import_react50.default.useState("idle");
109001
+ const [url, setUrl] = import_react50.default.useState(null);
109002
+ const [error, setError] = import_react50.default.useState(null);
109003
+ const [frame, setFrame] = import_react50.default.useState(0);
108204
109004
  const { columns, rows } = useTerminalSize();
108205
- const caps = import_react49.default.useMemo(() => detectTerminal2(), []);
109005
+ const caps = import_react50.default.useMemo(() => detectTerminal2(), []);
108206
109006
  const copy = splashCopy(phase, error, url, columns);
108207
109007
  const useSplash = !splashDisabled() && caps.unicode && splashFits(columns, rows, copy.length);
108208
- import_react49.default.useEffect(() => {
109008
+ import_react50.default.useEffect(() => {
108209
109009
  if (!useSplash || phase !== "idle") return;
108210
109010
  const t = setInterval(() => setFrame((f) => f + 1), TICK_MS);
108211
109011
  return () => clearInterval(t);
@@ -108237,9 +109037,9 @@ function SignInScreen({
108237
109037
  if (key.ctrl && input === "c") exit();
108238
109038
  });
108239
109039
  if (useSplash) {
108240
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemeProvider, { value: darkTheme, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Splash, { columns, rows, frame, copy }) });
109040
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeProvider, { value: darkTheme, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(Splash, { columns, rows, frame, copy }) });
108241
109041
  }
108242
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemeProvider, { value: darkTheme, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(SignInCard, { phase, url, error }) });
109042
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeProvider, { value: darkTheme, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SignInCard, { phase, url, error }) });
108243
109043
  }
108244
109044
  function splashCopy(phase, error, url, columns) {
108245
109045
  const version = tuiVersion();
@@ -108285,39 +109085,39 @@ function SignInCard({
108285
109085
  error
108286
109086
  }) {
108287
109087
  const version = tuiVersion();
108288
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(Box2, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [
108289
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(Box2, { flexDirection: "row", children: [
108290
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Box2, { marginRight: 2, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(OrionRing, {}) }),
108291
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(Box2, { flexDirection: "column", justifyContent: "center", children: [
108292
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(ThemedText, { colorKey: "welcomeBanner", bold: true, children: [
109088
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(Box2, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [
109089
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(Box2, { flexDirection: "row", children: [
109090
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(Box2, { marginRight: 2, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(OrionRing, {}) }),
109091
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(Box2, { flexDirection: "column", justifyContent: "center", children: [
109092
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(ThemedText, { colorKey: "welcomeBanner", bold: true, children: [
108293
109093
  CHANNEL.displayName,
108294
- version ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemedText, { dim: true, children: ` v${version}` }) : null
109094
+ version ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemedText, { dim: true, children: ` v${version}` }) : null
108295
109095
  ] }),
108296
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(GradientText, { text: "Your engineering team all in one" })
109096
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(GradientText, { text: "Your engineering team all in one" })
108297
109097
  ] })
108298
109098
  ] }),
108299
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
108300
- phase === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_jsx_runtime73.Fragment, { children: [
108301
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemedText, { children: "Sign in with your Orion account to start." }),
108302
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(Box2, { flexDirection: "row", marginTop: 1, children: [
108303
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemedText, { colorKey: "accent", bold: true, children: "\u203A Press Enter" }),
108304
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemedText, { dim: true, children: " to sign in via your browser" })
109099
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
109100
+ phase === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
109101
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemedText, { children: "Sign in with your Orion account to start." }),
109102
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(Box2, { flexDirection: "row", marginTop: 1, children: [
109103
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemedText, { colorKey: "accent", bold: true, children: "\u203A Press Enter" }),
109104
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemedText, { dim: true, children: " to sign in via your browser" })
108305
109105
  ] })
108306
109106
  ] }) : null,
108307
- phase === "signing" ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_jsx_runtime73.Fragment, { children: [
108308
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemedText, { children: "Opening your browser\u2026" }),
108309
- url ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
108310
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemedText, { dim: true, children: "If it didn't open, open this link to finish signing in:" }),
108311
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemedText, { colorKey: "accent", children: url })
109107
+ phase === "signing" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
109108
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemedText, { children: "Opening your browser\u2026" }),
109109
+ url ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
109110
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemedText, { dim: true, children: "If it didn't open, open this link to finish signing in:" }),
109111
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemedText, { colorKey: "accent", children: url })
108312
109112
  ] }) : null,
108313
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemedText, { dim: true, children: "Press Esc to cancel." }) })
109113
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemedText, { dim: true, children: "Press Esc to cancel." }) })
108314
109114
  ] }) : null,
108315
- phase === "error" ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_jsx_runtime73.Fragment, { children: [
108316
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(ThemedText, { colorKey: "error", children: [
109115
+ phase === "error" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
109116
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(ThemedText, { colorKey: "error", children: [
108317
109117
  "Sign-in failed: ",
108318
109118
  error
108319
109119
  ] }),
108320
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemedText, { dim: true, children: "\u203A Press Enter to try again." }) })
109120
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemedText, { dim: true, children: "\u203A Press Enter to try again." }) })
108321
109121
  ] }) : null
108322
109122
  ] })
108323
109123
  ] });
@@ -108934,7 +109734,7 @@ function shouldAutoApprove(fullyAutomatic, configAutoApprove) {
108934
109734
 
108935
109735
  // src/headless/runHeadless.ts
108936
109736
  var import_client_core37 = __toESM(require_dist(), 1);
108937
- var import_client_ui_core9 = __toESM(require_dist2(), 1);
109737
+ var import_client_ui_core17 = __toESM(require_dist2(), 1);
108938
109738
  import * as os6 from "os";
108939
109739
  import { randomUUID } from "crypto";
108940
109740
  var HEADLESS_RESULT_PREFIX = "ORION_HEADLESS_RESULT ";
@@ -109115,7 +109915,7 @@ async function runHeadless(flags2) {
109115
109915
  };
109116
109916
  const sessionId = randomUUID();
109117
109917
  let messages = [];
109118
- const clientState = (0, import_client_ui_core9.emptyClientState)();
109918
+ const clientState = (0, import_client_ui_core17.emptyClientState)();
109119
109919
  const runTurn = async (prompt) => {
109120
109920
  const ac = new AbortController();
109121
109921
  const snapshot = [...messages];
@@ -109164,9 +109964,125 @@ async function runHeadless(flags2) {
109164
109964
  return { ok: endReason === "done", endReason, turns, sessionId, goal: flags2.goal };
109165
109965
  }
109166
109966
 
109967
+ // src/services/feedbackGate.ts
109968
+ var import_client_core38 = __toESM(require_dist(), 1);
109969
+ var import_client_ui_core18 = __toESM(require_dist2(), 1);
109970
+ import { randomUUID as randomUUID2 } from "crypto";
109971
+ var TuiFeedbackGate = class {
109972
+ constructor(deps2) {
109973
+ this.deps = deps2;
109974
+ }
109975
+ turnsBySession = /* @__PURE__ */ new Map();
109976
+ pendingId = null;
109977
+ now() {
109978
+ return this.deps.now?.() ?? Date.now();
109979
+ }
109980
+ /** Count a CLEAN completion (callers only invoke this on `turn_complete`). */
109981
+ noteTurnCompleted(sessionId) {
109982
+ this.turnsBySession.set(sessionId, (this.turnsBySession.get(sessionId) ?? 0) + 1);
109983
+ }
109984
+ /** Post-turn trigger. Persists the first-seen/seed stamps on first run, and stamps
109985
+ * shown-BEFORE-showing so a crash between the two costs an offer, never a double. */
109986
+ maybeOffer(sessionId, turnId) {
109987
+ const now2 = this.now();
109988
+ const config = this.deps.loadConfig();
109989
+ let state = (0, import_client_ui_core18.feedbackStateFromScalars)(config, now2);
109990
+ if (config.feedbackFirstSeenAt <= 0 || config.feedbackSeed === 0) {
109991
+ state = { ...state, seed: (0, import_client_ui_core18.mintFeedbackSeed)() };
109992
+ this.safeSave((0, import_client_ui_core18.feedbackScalarsFromState)(state));
109993
+ }
109994
+ const pendings = this.deps.getPendings();
109995
+ const offer = (0, import_client_ui_core18.shouldOfferFeedback)(state, {
109996
+ now: now2,
109997
+ completedTurnsThisSession: this.turnsBySession.get(sessionId) ?? 0,
109998
+ turnCompletedCleanly: true,
109999
+ blockingCardOpen: pendings.permissions > 0 || pendings.planApproval || pendings.askUser || pendings.workPlan || pendings.feedback,
110000
+ attended: true,
110001
+ // headless exits before any UI wiring; this path is interactive
110002
+ signedIn: this.deps.signedIn(),
110003
+ forced: this.deps.forced
110004
+ });
110005
+ if (!offer) return;
110006
+ state = (0, import_client_ui_core18.applyFeedbackShown)(state, now2);
110007
+ this.safeSave((0, import_client_ui_core18.feedbackScalarsFromState)(state));
110008
+ const routing = this.deps.getRouting();
110009
+ const requestId = randomUUID2();
110010
+ this.pendingId = requestId;
110011
+ this.deps.setPendingFeedback({
110012
+ requestId,
110013
+ sessionId,
110014
+ turnId,
110015
+ model: routing.model,
110016
+ provider: routing.provider
110017
+ });
110018
+ void (0, import_client_core38.sendFeedbackImpression)(this.deps.submit, "shown", "tui");
110019
+ }
110020
+ /** The user rated. Snapshot the transcript SYNCHRONOUSLY (before any await), then
110021
+ * scrub + assemble + send off the interactive path. Idempotent per requestId. */
110022
+ settleSubmit(requestId, score, why, meta) {
110023
+ if (this.pendingId !== requestId) return false;
110024
+ this.pendingId = null;
110025
+ this.deps.setPendingFeedback(null);
110026
+ const snapshot = this.deps.getMessages().slice();
110027
+ const now2 = this.now();
110028
+ const config = this.deps.loadConfig();
110029
+ const state = (0, import_client_ui_core18.applyFeedbackSubmitted)((0, import_client_ui_core18.feedbackStateFromScalars)(config, now2), now2);
110030
+ this.safeSave((0, import_client_ui_core18.feedbackScalarsFromState)(state));
110031
+ const card = (0, import_client_ui_core18.feedbackSetWhy)((0, import_client_ui_core18.feedbackSelectScore)((0, import_client_ui_core18.createFeedbackCard)(), score), why);
110032
+ const body2 = (0, import_client_ui_core18.buildFeedbackSubmission)(card, {
110033
+ submissionId: randomUUID2(),
110034
+ sessionId: meta.sessionId,
110035
+ turnId: meta.turnId,
110036
+ client: "tui",
110037
+ clientVersion: this.deps.clientVersion,
110038
+ model: meta.model,
110039
+ provider: meta.provider
110040
+ });
110041
+ const { conversation, truncated } = (0, import_client_core38.scrubFeedbackConversation)(snapshot);
110042
+ void (0, import_client_core38.sendFeedbackSubmission)(this.deps.submit, {
110043
+ ...body2,
110044
+ conversation,
110045
+ conversation_truncated: truncated
110046
+ });
110047
+ this.deps.appendNote(import_client_ui_core18.FEEDBACK_WORDING.transcriptNote);
110048
+ return true;
110049
+ }
110050
+ /** The session/transcript under a pending card is going away (new chat, resume) —
110051
+ * drop the card with no strike and no ping (the shown stamp's ignored cooldown
110052
+ * already covers it). A no-op when nothing is pending. */
110053
+ invalidate() {
110054
+ if (this.pendingId === null) return;
110055
+ this.pendingId = null;
110056
+ this.deps.setPendingFeedback(null);
110057
+ }
110058
+ /** The card went away unanswered. `explicit` (Esc) strikes + pings; type-through does
110059
+ * neither — the shown stamp's short "ignored" cooldown already covers it. */
110060
+ settleDismiss(requestId, explicit) {
110061
+ if (this.pendingId !== requestId) return false;
110062
+ this.pendingId = null;
110063
+ this.deps.setPendingFeedback(null);
110064
+ if (explicit) {
110065
+ const now2 = this.now();
110066
+ const state = (0, import_client_ui_core18.applyFeedbackDismissed)(
110067
+ (0, import_client_ui_core18.feedbackStateFromScalars)(this.deps.loadConfig(), now2),
110068
+ now2
110069
+ );
110070
+ this.safeSave((0, import_client_ui_core18.feedbackScalarsFromState)(state));
110071
+ void (0, import_client_core38.sendFeedbackImpression)(this.deps.submit, "dismissed", "tui");
110072
+ }
110073
+ return true;
110074
+ }
110075
+ safeSave(patch) {
110076
+ try {
110077
+ this.deps.saveConfig(patch);
110078
+ } catch {
110079
+ }
110080
+ }
110081
+ };
110082
+
109167
110083
  // src/main.tsx
109168
- var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);
109169
- var SANDBOX_AVAILABLE = (0, import_client_core38.probeSandboxAvailable)();
110084
+ var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1);
110085
+ var SANDBOX_AVAILABLE = (0, import_client_core39.probeSandboxAvailable)();
109170
110086
  async function main() {
109171
110087
  let headlessFlags = null;
109172
110088
  try {
@@ -109218,8 +110134,8 @@ async function main() {
109218
110134
  }
109219
110135
  });
109220
110136
  void (0, import_client_core8.refreshEndpointRouting)(config.provider, { workspaceRoot: config.workspaceRoot });
109221
- void (0, import_client_core39.prewarmInterimModels)(config.workspaceRoot);
109222
- void (0, import_client_core39.prewarmRepoIdentity)(config.workspaceRoot);
110137
+ void (0, import_client_core40.prewarmInterimModels)(config.workspaceRoot);
110138
+ void (0, import_client_core40.prewarmRepoIdentity)(config.workspaceRoot);
109223
110139
  const setSessionTitle = (title) => {
109224
110140
  appStore.setState((s) => s.sessionTitle === title ? s : { ...s, sessionTitle: title });
109225
110141
  };
@@ -109243,11 +110159,41 @@ async function main() {
109243
110159
  }
109244
110160
  });
109245
110161
  const secrets = createSecretStore();
109246
- const session = (0, import_client_core39.createAgentSession)(secrets, config);
109247
- const outcomes = new import_client_core39.OutcomeReporter({
110162
+ const session = (0, import_client_core40.createAgentSession)(secrets, config);
110163
+ const outcomes = new import_client_core40.OutcomeReporter({
109248
110164
  apiBaseUrl: () => config.accountsApiUrl,
109249
110165
  accessToken: () => session.currentAccessToken()
109250
110166
  });
110167
+ const feedbackGate = new TuiFeedbackGate({
110168
+ loadConfig,
110169
+ saveConfig,
110170
+ getMessages: () => transcriptStore.getState().messages,
110171
+ getPendings: () => {
110172
+ const a = appStore.getState();
110173
+ return {
110174
+ permissions: a.pendingPermissions.length,
110175
+ planApproval: !!a.pendingPlanApproval,
110176
+ askUser: !!a.pendingAskUser,
110177
+ workPlan: !!a.pendingWorkPlan,
110178
+ feedback: !!a.pendingFeedback
110179
+ };
110180
+ },
110181
+ setPendingFeedback: (pending) => appStore.setState((s) => ({ ...s, pendingFeedback: pending })),
110182
+ getRouting: () => {
110183
+ const a = appStore.getState();
110184
+ return { model: a.model || void 0, provider: a.provider || void 0 };
110185
+ },
110186
+ appendNote: (text) => transcriptStore.setState((s) => appendNote(s, text)),
110187
+ submit: {
110188
+ apiBaseUrl: () => config.accountsApiUrl,
110189
+ accessToken: () => session.currentAccessToken()
110190
+ },
110191
+ clientVersion: tuiVersion() ?? "0.0.0-dev",
110192
+ // The chat is behind the sign-in gate (the turn gate blocks sends until signed in),
110193
+ // so reaching a completed turn implies a session exists.
110194
+ signedIn: () => true,
110195
+ forced: process.env.ORION_FEEDBACK_FORCE === "1"
110196
+ });
109251
110197
  let signedIn = await session.isSignedIn();
109252
110198
  appStore.setState((s) => ({ ...s, signedIn }));
109253
110199
  void session.tier().then((t) => appStore.setState((s) => ({ ...s, accountTier: t })));
@@ -109266,10 +110212,10 @@ async function main() {
109266
110212
  }
109267
110213
  }
109268
110214
  const authToken = async () => await session.currentAccessToken() ?? process.env.ORION_AUTH_TOKEN ?? null;
109269
- const bridge = new import_client_core38.OrionBridge(
110215
+ const bridge = new import_client_core39.OrionBridge(
109270
110216
  () => config.apiUrl,
109271
110217
  authToken,
109272
- import_client_core39.nodeEmitterFactory,
110218
+ import_client_core40.nodeEmitterFactory,
109273
110219
  // Seamless refresh: a 401 coalesces ONE refresh through the AgentSession (single-flight), so a
109274
110220
  // token cycling mid-chat never logs the user out. `refreshAndSyncGate` also re-syncs the cached
109275
110221
  // gate flag so a definitively-revoked session re-gates the chat cleanly (no stale "signed in").
@@ -109277,9 +110223,9 @@ async function main() {
109277
110223
  );
109278
110224
  let brainInstance;
109279
110225
  const brain = () => {
109280
- brainInstance ??= (0, import_client_core39.createHostBrain)({
110226
+ brainInstance ??= (0, import_client_core40.createHostBrain)({
109281
110227
  topology: config.brainTopology,
109282
- resolveBinary: () => (0, import_client_core39.resolveBrainBinary)({
110228
+ resolveBinary: () => (0, import_client_core40.resolveBrainBinary)({
109283
110229
  configPath: config.brainPath,
109284
110230
  env: process.env,
109285
110231
  bundledCandidates: bundledBrainCandidates()
@@ -109290,10 +110236,10 @@ async function main() {
109290
110236
  });
109291
110237
  return brainInstance;
109292
110238
  };
109293
- const turnTransport = (0, import_client_core39.createTurnTransport)({
110239
+ const turnTransport = (0, import_client_core40.createTurnTransport)({
109294
110240
  mode: config.brain,
109295
110241
  bridge,
109296
- makeLocal: () => new import_client_core39.LocalBrainTransport({
110242
+ makeLocal: () => new import_client_core40.LocalBrainTransport({
109297
110243
  // Proactive freshness: the brain holds this bearer for a whole segment and cannot
109298
110244
  // ride the bridge's reactive 401-refresh — so validate-or-refresh before hand-off.
109299
110245
  authToken: async () => await session.currentFreshAccessToken() ?? process.env.ORION_AUTH_TOKEN ?? null,
@@ -109301,14 +110247,14 @@ async function main() {
109301
110247
  connect: () => brain().connect()
109302
110248
  })
109303
110249
  });
109304
- const codebaseIndexFallback = new import_client_core38.WorkspaceIndexStore();
109305
- const ripgrep = new import_client_core39.NodeRipgrepLocator({
110250
+ const codebaseIndexFallback = new import_client_core39.WorkspaceIndexStore();
110251
+ const ripgrep = new import_client_core40.NodeRipgrepLocator({
109306
110252
  // Bundled-first rg: ships as an optionalDependency of this package, so an
109307
110253
  // `npm i -g` user gets fast search with nothing else installed. Resolved
109308
110254
  // from THIS package's node_modules via require.resolve (nested and hoisted
109309
110255
  // layouts both work); absent (install offline / postinstall failed) → the
109310
110256
  // locator falls through to PATH + well-known paths exactly as before.
109311
- bundledCandidates: () => (0, import_client_core39.vscodeRipgrepCandidates)((specifier) => __require.resolve(specifier))
110257
+ bundledCandidates: () => (0, import_client_core40.vscodeRipgrepCandidates)((specifier) => __require.resolve(specifier))
109312
110258
  });
109313
110259
  const indexer = createIndexer(
109314
110260
  bridge,
@@ -109333,28 +110279,28 @@ async function main() {
109333
110279
  // the store's referential stability: unchanged state returns the same object.
109334
110280
  (relPath) => transcriptStore.setState((s) => {
109335
110281
  const clientState = { ...s.clientState };
109336
- if (!(0, import_client_ui_core10.dropSeenPath)(clientState, relPath)) return s;
110282
+ if (!(0, import_client_ui_core19.dropSeenPath)(clientState, relPath)) return s;
109337
110283
  return { ...s, clientState };
109338
110284
  }),
109339
110285
  { rgPath: ripgrep.locate(), mode: config.indexMode }
109340
110286
  );
109341
110287
  void indexer.start().catch(() => void 0);
109342
110288
  initIndexModeService({ appStore, setMode: (m2) => indexer.setMode(m2) });
109343
- const permissionStore = new import_client_core39.PermissionSettingsStore({ workspaceRoot: config.workspaceRoot });
110289
+ const permissionStore = new import_client_core40.PermissionSettingsStore({ workspaceRoot: config.workspaceRoot });
109344
110290
  await permissionStore.load();
109345
- const executor = new import_client_core38.ToolExecutor(
110291
+ const executor = new import_client_core39.ToolExecutor(
109346
110292
  () => config.workspaceRoot,
109347
110293
  // The session's EFFECTIVE mode — the same turbo⇒full_access law the wire rides
109348
110294
  // (`currentRouting`), never the bare store mode: the executor's membership
109349
110295
  // backstop must agree with the gate that already ruled on each call. Loop-run
109350
110296
  // sessions never enable turbo on the bridge, so they keep the configured mode
109351
110297
  // their own wire rides.
109352
- (sessionId2) => (0, import_client_core39.effectiveWirePermissionMode)(
110298
+ (sessionId2) => (0, import_client_core40.effectiveWirePermissionMode)(
109353
110299
  sessionId2 !== void 0 && bridge.isTurboModeEnabledForSession(sessionId2),
109354
110300
  appStore.getState().permissionMode
109355
110301
  ),
109356
110302
  secrets,
109357
- new import_client_core39.NullLspProvider(),
110303
+ new import_client_core40.NullLspProvider(),
109358
110304
  ripgrep,
109359
110305
  nullFrameSinkFactory,
109360
110306
  fallbackBrowserConfig,
@@ -109416,7 +110362,7 @@ async function main() {
109416
110362
  signedIn = false;
109417
110363
  appStore.setState((s) => ({ ...s, signedIn: false }));
109418
110364
  }
109419
- sessionId = resumeId ?? randomUUID2();
110365
+ sessionId = resumeId ?? randomUUID3();
109420
110366
  transcriptStore.setState((s) => bindSession(s, sessionId));
109421
110367
  }
109422
110368
  if (!signedIn) {
@@ -109476,11 +110422,11 @@ async function main() {
109476
110422
  }
109477
110423
  renderLane(transcriptStore, appStore, ev);
109478
110424
  if (ev.event === "usage_recorded") {
109479
- (0, import_client_core38.recordTurnMetrics)({
110425
+ (0, import_client_core39.recordTurnMetrics)({
109480
110426
  app: "tui",
109481
110427
  sessionId,
109482
110428
  workspaceRoot: currentRouting().workspaceRoot,
109483
- turn: (0, import_client_core38.turnMetricsFromUsageRecorded)(ev.data ?? {})
110429
+ turn: (0, import_client_core39.turnMetricsFromUsageRecorded)(ev.data ?? {})
109484
110430
  });
109485
110431
  }
109486
110432
  if (ev.event === "file_modified") {
@@ -109504,8 +110450,8 @@ async function main() {
109504
110450
  sessionSub = bridge.onSessionEvent(sid, onSessionStreamEvent);
109505
110451
  };
109506
110452
  let goalRunner = null;
109507
- const cronController = new import_client_core39.CronController({
109508
- submitTurn: (prompt) => sendTurn(prompt, "\u27F3 scheduled"),
110453
+ const cronController = new import_client_core40.CronController({
110454
+ submitTurn: (prompt) => sendTurn(prompt, "\u27F3 scheduled", void 0, "system"),
109509
110455
  isBusy: () => appStore.getState().status === "streaming",
109510
110456
  persistence: fileCronPersistence(config.workspaceRoot)
109511
110457
  });
@@ -109676,8 +110622,8 @@ async function main() {
109676
110622
  const anywhere = new Set(
109677
110623
  registry.all().filter((c3) => c3.source === "skill").map((c3) => c3.name)
109678
110624
  );
109679
- const ranges = (0, import_client_core39.scanSlashTokenRanges)(v2, anywhere);
109680
- const lead = (0, import_client_core39.matchSlashToken)(v2);
110625
+ const ranges = (0, import_client_core40.scanSlashTokenRanges)(v2, anywhere);
110626
+ const lead = (0, import_client_core40.matchSlashToken)(v2);
109681
110627
  if (lead && !anywhere.has(lead.name) && registry.get(lead.name)) {
109682
110628
  const start2 = v2.indexOf("/");
109683
110629
  ranges.unshift({ start: start2, end: start2 + lead.name.length + 1 });
@@ -109718,7 +110664,7 @@ async function main() {
109718
110664
  if (turn && streaming && !turn.cancelRequested && turn.phase === "stream") {
109719
110665
  turn.cancelRequested = true;
109720
110666
  outcomes.report({ kind: "cancel_context", kept_edits: turn.hadEdits });
109721
- turn.disposeFallback = (0, import_client_core39.armGracefulCancel)({
110667
+ turn.disposeFallback = (0, import_client_core40.armGracefulCancel)({
109722
110668
  controller: turn.abort,
109723
110669
  sendCancel: () => turnTransport.cancelTurn(turn.sessionId)
109724
110670
  });
@@ -109789,7 +110735,7 @@ async function main() {
109789
110735
  boundary.resolveAskUser(requestId, answers, sid);
109790
110736
  };
109791
110737
  const heldAgentReports = [];
109792
- const agentManager = new import_client_core39.AgentManager((0, import_client_core39.brainAwareAgentTransport)(bridge, turnTransport), executor, async () => {
110738
+ const agentManager = new import_client_core40.AgentManager((0, import_client_core40.brainAwareAgentTransport)(bridge, turnTransport), executor, async () => {
109793
110739
  const result = await bridge.rpc("list_personas", {});
109794
110740
  return result.personas ?? [];
109795
110741
  });
@@ -109799,8 +110745,8 @@ async function main() {
109799
110745
  agentManager.attachOutcomeSink((outcome) => {
109800
110746
  oVaultSessions.for(outcome.parentSessionId, currentRouting().workspaceRoot)?.recordSiblingOutcome(outcome);
109801
110747
  });
109802
- void (0, import_client_core39.loadAgentDefs)(config.workspaceRoot).then((defs) => agentManager.prime(defs));
109803
- const workGraphManager = new import_client_core39.WorkGraphManager({ agents: agentManager, tools: executor });
110748
+ void (0, import_client_core40.loadAgentDefs)(config.workspaceRoot).then((defs) => agentManager.prime(defs));
110749
+ const workGraphManager = new import_client_core40.WorkGraphManager({ agents: agentManager, tools: executor });
109804
110750
  workGraphManager.registerTools(executor);
109805
110751
  const workPlanApproval = new WorkPlanApprovalBridge();
109806
110752
  function rejectPendingWorkPlan() {
@@ -109823,7 +110769,7 @@ async function main() {
109823
110769
  workRunTicker = setInterval(() => {
109824
110770
  const record = liveRunRecord;
109825
110771
  if (!record) return stopWorkRunTicker();
109826
- const view = (0, import_client_core39.buildRunGraphView)(record, agentManager.agentsFor(sessionId), Date.now(), tuiFlowBudget());
110772
+ const view = (0, import_client_core40.buildRunGraphView)(record, agentManager.agentsFor(sessionId), Date.now(), tuiFlowBudget());
109827
110773
  appStore.setState(
109828
110774
  (s) => s.workRun ? { ...s, workRun: { ...s.workRun, view } } : s
109829
110775
  );
@@ -109847,11 +110793,11 @@ async function main() {
109847
110793
  const status = appStore.getState().status;
109848
110794
  if (status !== "idle" && status !== "error") return;
109849
110795
  if (heldAgentReports.length === 0) return;
109850
- sendTurn(import_client_core39.SUBAGENT_WAKE_PROMPT);
110796
+ sendTurn(import_client_core40.SUBAGENT_WAKE_PROMPT, void 0, void 0, "system");
109851
110797
  },
109852
110798
  onRunUpdate: (record) => {
109853
110799
  liveRunRecord = record;
109854
- const view = (0, import_client_core39.buildRunGraphView)(record, agentManager.agentsFor(sessionId), Date.now(), tuiFlowBudget());
110800
+ const view = (0, import_client_core40.buildRunGraphView)(record, agentManager.agentsFor(sessionId), Date.now(), tuiFlowBudget());
109855
110801
  if (view.live) {
109856
110802
  startWorkRunTicker();
109857
110803
  appStore.setState((s) => ({
@@ -109892,7 +110838,7 @@ async function main() {
109892
110838
  agentManager.attachParent(sid, {
109893
110839
  routing: () => currentRouting(),
109894
110840
  clientCapabilities: () => [
109895
- ...(0, import_client_core38.platformCapabilities)(),
110841
+ ...(0, import_client_core39.platformCapabilities)(),
109896
110842
  ...appStore.getState().subagentsEnabled ? ["subagents"] : []
109897
110843
  ],
109898
110844
  transcript: () => transcriptStore.getState().messages,
@@ -109901,7 +110847,7 @@ async function main() {
109901
110847
  const status = appStore.getState().status;
109902
110848
  if (status !== "idle" && status !== "error") return;
109903
110849
  if (heldAgentReports.length === 0) return;
109904
- sendTurn(import_client_core39.SUBAGENT_WAKE_PROMPT);
110850
+ sendTurn(import_client_core40.SUBAGENT_WAKE_PROMPT, void 0, void 0, "system");
109905
110851
  },
109906
110852
  onLifecycle: (ev) => onRenderEvent({
109907
110853
  event: "agent_lifecycle",
@@ -109937,7 +110883,7 @@ async function main() {
109937
110883
  timestamp: Date.now(),
109938
110884
  data
109939
110885
  }),
109940
- getOrionResources: () => (0, import_client_core38.buildOrionSnapshot)(config.workspaceRoot, void 0, sid),
110886
+ getOrionResources: () => (0, import_client_core39.buildOrionSnapshot)(config.workspaceRoot, void 0, sid),
109941
110887
  // Full-dose source for review-persona children (lesson dosing) — the same
109942
110888
  // attention payload the parent turn itself ships.
109943
110889
  oVaultAttention: () => {
@@ -109958,6 +110904,7 @@ async function main() {
109958
110904
  await workGraphManager.detachParent(oldSid);
109959
110905
  heldAgentReports.length = 0;
109960
110906
  rejectPendingWorkPlan();
110907
+ feedbackGate.invalidate();
109961
110908
  appStore.setState((s) => ({ ...s, workRun: null }));
109962
110909
  attachAgentParent(newSid);
109963
110910
  attachWorkGraphParent(newSid);
@@ -109975,7 +110922,7 @@ async function main() {
109975
110922
  // the /turbo-toggle vs --fully-automatic gap: the flag already overrides the
109976
110923
  // store mode at launch (launchPermissionMode); the toggle now buys the same
109977
110924
  // backend posture, so no ask is ever born and batch-mates stop deferring.
109978
- permissionMode: (0, import_client_core39.effectiveWirePermissionMode)(
110925
+ permissionMode: (0, import_client_core40.effectiveWirePermissionMode)(
109979
110926
  bridge.isTurboModeEnabledForSession(sessionId),
109980
110927
  a.permissionMode
109981
110928
  ),
@@ -109995,8 +110942,8 @@ async function main() {
109995
110942
  sandboxAvailable: SANDBOX_AVAILABLE
109996
110943
  };
109997
110944
  };
109998
- const oVaultSessions = new import_client_core38.OVaultSessions(() => process.env.ORION_OVAULT_CAPTURE !== "0");
109999
- oVaultSessions.syncRunner = new import_client_core38.OVaultSyncRunner({
110945
+ const oVaultSessions = new import_client_core39.OVaultSessions(() => process.env.ORION_OVAULT_CAPTURE !== "0");
110946
+ oVaultSessions.syncRunner = new import_client_core39.OVaultSyncRunner({
110000
110947
  auth: {
110001
110948
  apiBaseUrl: () => config.accountsApiUrl,
110002
110949
  accessToken: () => session.currentAccessToken(),
@@ -110039,7 +110986,7 @@ async function main() {
110039
110986
  partialText: "",
110040
110987
  settled: false
110041
110988
  };
110042
- if (lastTurnComplete?.sessionId === sid && Date.now() - lastTurnComplete.at < import_client_core39.REPHRASE_WINDOW_MS) {
110989
+ if (lastTurnComplete?.sessionId === sid && Date.now() - lastTurnComplete.at < import_client_core40.REPHRASE_WINDOW_MS) {
110043
110990
  outcomes.report({ kind: "rephrase" });
110044
110991
  }
110045
110992
  currentTurn = turn;
@@ -110059,7 +111006,7 @@ async function main() {
110059
111006
  };
110060
111007
  try {
110061
111008
  const peerAgents = await presence.registry.peersForWire(sid).catch(() => []);
110062
- const outcome = await (0, import_client_core38.driveTurn)(
111009
+ const outcome = await (0, import_client_core39.driveTurn)(
110063
111010
  turnTransport,
110064
111011
  {
110065
111012
  sessionId: sid,
@@ -110080,7 +111027,7 @@ async function main() {
110080
111027
  // `workgraph` rides the same switch as the fan-out family: a work graph IS a
110081
111028
  // fan-out (its phases are sub-agents), so turning sub-agents off must hide both.
110082
111029
  clientCapabilities: [
110083
- ...(0, import_client_core38.platformCapabilities)(),
111030
+ ...(0, import_client_core39.platformCapabilities)(),
110084
111031
  ...appStore.getState().subagentsEnabled ? ["scheduling", "subagents", "workgraph"] : ["scheduling"]
110085
111032
  ],
110086
111033
  extraBody: {
@@ -110094,7 +111041,7 @@ async function main() {
110094
111041
  // Ship the `.orion` snapshot so the backend's begin-turn loaders read
110095
111042
  // config / sub-agent defs / skills / hooks / memory / plugins from the
110096
111043
  // body — no live client-read channel in the stateless segment model.
110097
- getOrionResources: () => (0, import_client_core38.buildOrionSnapshot)(currentRouting().workspaceRoot, void 0, sid),
111044
+ getOrionResources: () => (0, import_client_core39.buildOrionSnapshot)(currentRouting().workspaceRoot, void 0, sid),
110098
111045
  getFileHistoryManifest: () => executor.fileHistoryManifest(sid),
110099
111046
  // Lesson-recall anchors: the TUI has no editor attention, so recently-touched
110100
111047
  // paths from the capture observer are the attention set.
@@ -110104,7 +111051,7 @@ async function main() {
110104
111051
  return { active: null, open: [], touched, related: executor.oVaultRelatedPaths?.(touched) ?? [] };
110105
111052
  }
110106
111053
  },
110107
- (0, import_client_core38.withOVault)(
111054
+ (0, import_client_core39.withOVault)(
110108
111055
  {
110109
111056
  ...boundary.makeHandlers(sid, ac.signal, onEvent),
110110
111057
  // Stops the driver from POSTING the next segment when the user cancelled at a
@@ -110116,7 +111063,7 @@ async function main() {
110116
111063
  onToolResult: (payload) => {
110117
111064
  if (payload.terminal_savings) {
110118
111065
  terminalSavings.push(payload.terminal_savings);
110119
- (0, import_client_core38.recordTurnMetrics)({
111066
+ (0, import_client_core39.recordTurnMetrics)({
110120
111067
  app: "tui",
110121
111068
  sessionId: sid,
110122
111069
  workspaceRoot: currentRouting().workspaceRoot,
@@ -110150,16 +111097,20 @@ async function main() {
110150
111097
  settleOutcome = "completed";
110151
111098
  lastTurnComplete = { sessionId: sid, at: Date.now() };
110152
111099
  const data = outcome.event.data ?? {};
110153
- (0, import_client_core38.recordTurnMetrics)({
111100
+ (0, import_client_core39.recordTurnMetrics)({
110154
111101
  app: "tui",
110155
111102
  sessionId: sid,
110156
111103
  workspaceRoot: currentRouting().workspaceRoot,
110157
- turn: (0, import_client_core38.turnMetricsFromComplete)(data),
111104
+ turn: (0, import_client_core39.turnMetricsFromComplete)(data),
110158
111105
  terminalSavings
110159
111106
  });
110160
111107
  void oVaultSessions.reflectorFor(sid, currentRouting().workspaceRoot, bridge)?.run("turn_complete").finally(
110161
111108
  () => oVaultSessions.syncRunner?.sync(currentRouting().workspaceRoot, "post_reflect")
110162
111109
  );
111110
+ if (start2.origin !== "system" && goalRunner === null) {
111111
+ feedbackGate.noteTurnCompleted(sid);
111112
+ feedbackGate.maybeOffer(sid, activeMetricsTurnId ?? void 0);
111113
+ }
110163
111114
  } else {
110164
111115
  const data = outcome.event.data ?? {};
110165
111116
  settleOutcome = data.error === "cancelled" ? "cancelled" : "error";
@@ -110201,8 +111152,9 @@ async function main() {
110201
111152
  appStore.getState().signedIn,
110202
111153
  (t) => transcriptStore.setState((s) => appendNote(s, t))
110203
111154
  );
110204
- const sendTurn = (text, display, remoteAttachments) => {
111155
+ const sendTurn = (text, display, remoteAttachments, origin = "user") => {
110205
111156
  if (!ensureSignedInToChat()) return;
111157
+ feedbackGate.invalidate();
110206
111158
  const snapshot = transcriptStore.getState();
110207
111159
  const pending = remoteAttachments !== void 0 ? [] : prunePastedImages(text, appStore.getState().pendingAttachments);
110208
111160
  const attachments = remoteAttachments ?? toWireAttachments(pending);
@@ -110227,7 +111179,7 @@ async function main() {
110227
111179
  // the last await ended; still-running children keep their rows.
110228
111180
  subAgents: s.subAgents.filter((a) => a.phase !== "finished")
110229
111181
  }));
110230
- void runTurn({ text, attachments }, snapshot);
111182
+ void runTurn({ text, attachments, origin }, snapshot);
110231
111183
  };
110232
111184
  const invokeSkillTurn = (name2, args2) => {
110233
111185
  if (!ensureSignedInToChat()) return;
@@ -110250,8 +111202,8 @@ async function main() {
110250
111202
  executor.registerHostTool("schedule_task", makeScheduleTaskHandler(cronController));
110251
111203
  const loopService = new LoopService({
110252
111204
  workspaceRoot: config.workspaceRoot,
110253
- schedulePath: loopSchedulePathFor((0, import_client_core39.runsRootFor)("loops", config.workspaceRoot)),
110254
- transport: (0, import_client_core39.brainAwareAgentTransport)(bridge, turnTransport),
111205
+ schedulePath: loopSchedulePathFor((0, import_client_core40.runsRootFor)("loops", config.workspaceRoot)),
111206
+ transport: (0, import_client_core40.brainAwareAgentTransport)(bridge, turnTransport),
110255
111207
  tools: executor,
110256
111208
  // The CONFIGURED mode rides here deliberately, not the turbo-effective one
110257
111209
  // (currentRouting applies the turbo→full_access law): a loop is standing
@@ -110288,7 +111240,7 @@ async function main() {
110288
111240
  }
110289
111241
  }).catch(() => void 0);
110290
111242
  const runGoalTurn = (prompt) => new Promise((resolve5, reject) => {
110291
- sendTurn(prompt, "\u25CE goal");
111243
+ sendTurn(prompt, "\u25CE goal", void 0, "system");
110292
111244
  if (appStore.getState().status !== "streaming") {
110293
111245
  reject(new Error("turn did not start"));
110294
111246
  return;
@@ -110307,12 +111259,12 @@ async function main() {
110307
111259
  });
110308
111260
  });
110309
111261
  const startGoal = (goal) => {
110310
- const runner = new import_client_core39.GoalRunner({ runTurn: runGoalTurn });
111262
+ const runner = new import_client_core40.GoalRunner({ runTurn: runGoalTurn });
110311
111263
  goalRunner = runner;
110312
111264
  transcriptStore.setState((s) => appendNote(s, `Goal started \u2014 working until complete: ${goal}`));
110313
111265
  void runner.run(goal).then((reason) => {
110314
111266
  if (goalRunner === runner) goalRunner = null;
110315
- transcriptStore.setState((s) => appendNote(s, (0, import_client_core39.describeGoalEnd)(reason)));
111267
+ transcriptStore.setState((s) => appendNote(s, (0, import_client_core40.describeGoalEnd)(reason)));
110316
111268
  settleSteerQueue("completed", {
110317
111269
  app: appStore,
110318
111270
  isBusy: () => currentTurn !== null || goalRunner !== null,
@@ -110336,7 +111288,7 @@ async function main() {
110336
111288
  verbs: {
110337
111289
  send: (text, attachments) => {
110338
111290
  if (!ensureSignedInToChat()) return false;
110339
- sendTurn(text, void 0, attachments);
111291
+ sendTurn(text, void 0, attachments, "system");
110340
111292
  return true;
110341
111293
  },
110342
111294
  steer: (text) => onQueue(text),
@@ -110500,25 +111452,25 @@ async function main() {
110500
111452
  defaultApiUrl: config.apiUrl,
110501
111453
  entries,
110502
111454
  add: async (entry) => {
110503
- await (0, import_client_core39.saveCustomProvider)(entry, "user", opts);
110504
- (0, import_client_core39.clearEndpointCatalog)(entry.baseUrl);
110505
- panel(await (0, import_client_core39.loadCustomProviders)(opts));
111455
+ await (0, import_client_core40.saveCustomProvider)(entry, "user", opts);
111456
+ (0, import_client_core40.clearEndpointCatalog)(entry.baseUrl);
111457
+ panel(await (0, import_client_core40.loadCustomProviders)(opts));
110506
111458
  },
110507
111459
  remove: async (name2) => {
110508
111460
  for (const tier of ["user", "project", "local"]) {
110509
- if (await (0, import_client_core39.removeCustomProvider)(name2, tier, opts)) break;
111461
+ if (await (0, import_client_core40.removeCustomProvider)(name2, tier, opts)) break;
110510
111462
  }
110511
111463
  (0, import_client_core8.clearEndpointRouting)();
110512
- (0, import_client_core39.clearEndpointCatalog)();
110513
- panel(await (0, import_client_core39.loadCustomProviders)(opts));
111464
+ (0, import_client_core40.clearEndpointCatalog)();
111465
+ panel(await (0, import_client_core40.loadCustomProviders)(opts));
110514
111466
  },
110515
- probe: (baseUrl, apiKey) => (0, import_client_core39.probeModels)(baseUrl, apiKey),
111467
+ probe: (baseUrl, apiKey) => (0, import_client_core40.probeModels)(baseUrl, apiKey),
110516
111468
  // A saved endpoint's models come from the CACHED catalog — opening one costs no
110517
111469
  // network, so limits stay editable long after the endpoint was added.
110518
111470
  modelsOf: (entry) => (0, import_client_core8.endpointModelViews)(entry),
110519
111471
  updateModels: async (name2, update) => {
110520
111472
  await (0, import_client_core8.updateCustomProviderModels)(name2, update, "user", opts);
110521
- panel(await (0, import_client_core39.loadCustomProviders)(opts));
111473
+ panel(await (0, import_client_core40.loadCustomProviders)(opts));
110522
111474
  },
110523
111475
  use: async (name2, model) => {
110524
111476
  const provider = `custom:${name2}`;
@@ -110536,12 +111488,12 @@ async function main() {
110536
111488
  }
110537
111489
  }
110538
111490
  }));
110539
- void (0, import_client_core39.loadCustomProviders)(opts).then(panel);
111491
+ void (0, import_client_core40.loadCustomProviders)(opts).then(panel);
110540
111492
  }
110541
111493
  };
110542
111494
  const runCommand = async (text) => {
110543
111495
  let parsed = registry.parse(text);
110544
- if (!parsed && (0, import_client_core39.matchSlashToken)(text)) {
111496
+ if (!parsed && (0, import_client_core40.matchSlashToken)(text)) {
110545
111497
  await skillSlash.refresh().catch(() => void 0);
110546
111498
  parsed = registry.parse(text);
110547
111499
  }
@@ -110580,11 +111532,11 @@ async function main() {
110580
111532
  };
110581
111533
  altScreen = enterAltScreen();
110582
111534
  app = await root_default2(
110583
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
111535
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
110584
111536
  Root,
110585
111537
  {
110586
111538
  appStore,
110587
- app: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
111539
+ app: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
110588
111540
  App2,
110589
111541
  {
110590
111542
  appStore,
@@ -110596,6 +111548,17 @@ async function main() {
110596
111548
  onPlanApproval,
110597
111549
  onAskUser,
110598
111550
  onWorkPlanApproval: respondWorkPlan,
111551
+ onFeedbackSubmit: (requestId, score, why) => {
111552
+ const pending = appStore.getState().pendingFeedback;
111553
+ if (!pending || pending.requestId !== requestId) return;
111554
+ feedbackGate.settleSubmit(requestId, score, why, {
111555
+ sessionId: pending.sessionId,
111556
+ turnId: pending.turnId,
111557
+ model: pending.model,
111558
+ provider: pending.provider
111559
+ });
111560
+ },
111561
+ onFeedbackDismiss: (requestId, explicit) => feedbackGate.settleDismiss(requestId, explicit),
110599
111562
  bindings,
110600
111563
  getCompletions,
110601
111564
  slashTokenRanges,
@@ -110609,7 +111572,7 @@ async function main() {
110609
111572
  onScroll
110610
111573
  }
110611
111574
  ),
110612
- signInScreen: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
111575
+ signInScreen: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
110613
111576
  SignInScreen,
110614
111577
  {
110615
111578
  session,