@hachej/boring-agent 0.1.101 → 0.1.104

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/{DebugDrawer-2TO5SE2D.js → DebugDrawer-JNA43SVR.js} +2 -1
  2. package/dist/chunk-2BGLZZ7T.js +10 -0
  3. package/dist/{chunk-46HJK2ES.js → chunk-4XOW57KJ.js} +3 -8
  4. package/dist/{chunk-XCZBICZS.js → chunk-6DRHERVK.js} +8 -6
  5. package/dist/{chunk-XTMY3PWI.js → chunk-BTYOMR7W.js} +118 -16
  6. package/dist/{chunk-T37OVD6L.js → chunk-I7KFNGB4.js} +28 -2
  7. package/dist/{chunk-3OEDBRKY.js → chunk-JNEKOVMJ.js} +1 -1
  8. package/dist/{chunk-VXF5DWS6.js → chunk-K25PK5EC.js} +1 -0
  9. package/dist/chunk-N6THTH7P.js +110 -0
  10. package/dist/core/index.d.ts +5 -5
  11. package/dist/core/index.js +1 -1
  12. package/dist/{createHarness-7C2A5UVH.js → createHarness-POZ4AXCZ.js} +2 -2
  13. package/dist/{errors-Ci0dzmcP.d.ts → errors-DH7C01Pm.d.ts} +2 -2
  14. package/dist/{file-search-DmoDnMan.d.ts → file-search-qcD5zItr.d.ts} +5 -5
  15. package/dist/front/artifacts.d.ts +34 -0
  16. package/dist/front/artifacts.js +21 -0
  17. package/dist/front/index.d.ts +8 -14
  18. package/dist/front/index.js +775 -762
  19. package/dist/front/styles.css +4 -0
  20. package/dist/{harness-s-kEgJkK.d.ts → harness-Dcd08yKr.d.ts} +2 -2
  21. package/dist/{lease-D5-CBoPs.d.ts → lease-DffrPrQn.d.ts} +3 -3
  22. package/dist/{middleware-Cq_cYHjJ.d.ts → middleware-CaAEXpi5.d.ts} +11 -2
  23. package/dist/{piChatEvent-Bzof4IEy.d.ts → piChatEvent-iNSXiFQq.d.ts} +19 -14
  24. package/dist/{piChatSessionService-BU4L5hxM.d.ts → piChatSessionService-DQSQ_kWZ.d.ts} +1 -1
  25. package/dist/{sandbox-KQiEdz4W.d.ts → sandbox-BMhut3kh.d.ts} +6 -1
  26. package/dist/server/agent-host/testing/gatewayConformance.d.ts +6 -6
  27. package/dist/server/agent-host/testing/gatewayConformance.js +3 -3
  28. package/dist/server/index.d.ts +21 -16
  29. package/dist/server/index.js +7 -5
  30. package/dist/server/worker/index.d.ts +3 -2
  31. package/dist/server/worker/index.js +25 -6
  32. package/dist/shared/index.d.ts +113 -39
  33. package/dist/shared/index.js +3 -3
  34. package/dist/{types-OwI_m-2p.d.ts → types-B1xDlBSo.d.ts} +13 -5
  35. package/docs/ERROR_CODES.md +1 -0
  36. package/package.json +16 -12
@@ -1,11 +1,23 @@
1
+ import {
2
+ Artifact,
3
+ ArtifactAction,
4
+ ArtifactActions,
5
+ ArtifactDescription,
6
+ ArtifactHeader,
7
+ ArtifactOpenProvider,
8
+ ArtifactTitle,
9
+ useOpenArtifact
10
+ } from "../chunk-N6THTH7P.js";
1
11
  import {
2
12
  DebugDrawer,
3
13
  agentResourceUrl,
4
- cn,
5
14
  copyTextToClipboard,
6
15
  createRequestId,
7
16
  withStorageScope
8
- } from "../chunk-46HJK2ES.js";
17
+ } from "../chunk-4XOW57KJ.js";
18
+ import {
19
+ cn
20
+ } from "../chunk-2BGLZZ7T.js";
9
21
  import {
10
22
  AGENT_GATEWAY_ERROR_CODES,
11
23
  CommandReceiptSchema,
@@ -19,11 +31,11 @@ import {
19
31
  WORKSPACE_COMMAND_NOTIFY_EVENT,
20
32
  extractToolUiMetadata,
21
33
  sanitizeToolUiMetadata
22
- } from "../chunk-XCZBICZS.js";
34
+ } from "../chunk-6DRHERVK.js";
23
35
  import "../chunk-YGRQ4Q5P.js";
24
36
  import {
25
37
  ErrorCode
26
- } from "../chunk-VXF5DWS6.js";
38
+ } from "../chunk-K25PK5EC.js";
27
39
 
28
40
  // src/front/upload/uploadFile.ts
29
41
  function readAsDataUrl(file) {
@@ -73,19 +85,7 @@ function rawWorkspaceFileUrl(path, opts) {
73
85
  }
74
86
 
75
87
  // src/front/chat/PiChatPanel.tsx
76
- import { lazy, Suspense, useCallback as useCallback18, useEffect as useEffect21, useMemo as useMemo16, useRef as useRef18, useState as useState20 } from "react";
77
-
78
- // src/front/ArtifactOpenContext.tsx
79
- import { createContext, useContext } from "react";
80
- import { jsx } from "react/jsx-runtime";
81
- var ArtifactOpenContext = createContext(null);
82
- function ArtifactOpenProvider({ onOpenArtifact, children }) {
83
- const inheritedOpenArtifact = useContext(ArtifactOpenContext);
84
- return /* @__PURE__ */ jsx(ArtifactOpenContext.Provider, { value: onOpenArtifact ?? inheritedOpenArtifact, children });
85
- }
86
- function useOpenArtifact() {
87
- return useContext(ArtifactOpenContext);
88
- }
88
+ import { lazy, Suspense, useCallback as useCallback18, useEffect as useEffect21, useMemo as useMemo16, useRef as useRef17, useState as useState20 } from "react";
89
89
 
90
90
  // src/front/chatPanelSettings.ts
91
91
  var DEFAULT_THINKING = "medium";
@@ -118,7 +118,7 @@ function encodeModelKey(sel) {
118
118
  // src/front/ChatEmptyState.tsx
119
119
  import { ArrowUpRight, BookOpen, Code2, FileSearch, Wand2 } from "lucide-react";
120
120
  import { Button } from "@hachej/boring-ui-kit";
121
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
121
+ import { jsx, jsxs } from "react/jsx-runtime";
122
122
  var defaultChatSuggestions = [
123
123
  {
124
124
  label: "Summarize the README",
@@ -147,7 +147,7 @@ var defaultChatSuggestions = [
147
147
  ];
148
148
  function ChatSuggestionGrid({ suggestions, onSelect, className }) {
149
149
  if (suggestions.length === 0) return null;
150
- return /* @__PURE__ */ jsx2(
150
+ return /* @__PURE__ */ jsx(
151
151
  "div",
152
152
  {
153
153
  "data-boring-agent-part": "suggestion-grid",
@@ -176,7 +176,7 @@ function ChatSuggestionGrid({ suggestions, onSelect, className }) {
176
176
  },
177
177
  className: "group h-auto justify-start gap-3 rounded-none bg-background px-4 py-3.5 text-left hover:bg-[color:var(--chat-empty-card-hover)] focus-visible:bg-[color:var(--chat-empty-card-hover)]",
178
178
  children: [
179
- Icon && /* @__PURE__ */ jsx2(
179
+ Icon && /* @__PURE__ */ jsx(
180
180
  Icon,
181
181
  {
182
182
  className: "mt-0.5 h-4 w-4 shrink-0 text-muted-foreground transition-colors group-hover:text-[color:var(--chat-empty-accent)]",
@@ -184,10 +184,10 @@ function ChatSuggestionGrid({ suggestions, onSelect, className }) {
184
184
  }
185
185
  ),
186
186
  /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
187
- /* @__PURE__ */ jsx2("span", { className: "text-[13px] font-medium text-foreground", children: suggestion.label }),
188
- suggestion.hint && /* @__PURE__ */ jsx2("span", { className: "text-[12px] text-muted-foreground", children: suggestion.hint })
187
+ /* @__PURE__ */ jsx("span", { className: "text-[13px] font-medium text-foreground", children: suggestion.label }),
188
+ suggestion.hint && /* @__PURE__ */ jsx("span", { className: "text-[12px] text-muted-foreground", children: suggestion.hint })
189
189
  ] }),
190
- /* @__PURE__ */ jsx2(
190
+ /* @__PURE__ */ jsx(
191
191
  ArrowUpRight,
192
192
  {
193
193
  className: cn(
@@ -235,15 +235,15 @@ function ChatEmptyState({
235
235
  ),
236
236
  children: [
237
237
  !hero && eyebrow && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[10.5px] font-medium uppercase tracking-[0.16em] text-[color:var(--chat-empty-eyebrow-color)]", children: [
238
- /* @__PURE__ */ jsx2("span", { className: "inline-block h-px w-4 bg-[color:var(--chat-empty-accent)]", "aria-hidden": "true" }),
238
+ /* @__PURE__ */ jsx("span", { className: "inline-block h-px w-4 bg-[color:var(--chat-empty-accent)]", "aria-hidden": "true" }),
239
239
  eyebrow
240
240
  ] }),
241
- title && /* @__PURE__ */ jsx2("h3", { className: cn(
241
+ title && /* @__PURE__ */ jsx("h3", { className: cn(
242
242
  "text-[24px] font-medium leading-[1.05] tracking-[-0.02em] text-[color:var(--chat-empty-title-color)] @[480px]:text-[34px]",
243
243
  hero ? "m-0" : "mt-3"
244
244
  ), children: title }),
245
- !hero && description && /* @__PURE__ */ jsx2("p", { className: "mt-3 hidden max-w-[440px] text-[14px] leading-relaxed text-[color:var(--chat-empty-description-color)] @[420px]:block", children: description }),
246
- /* @__PURE__ */ jsx2(ChatSuggestionGrid, { suggestions, onSelect, className: hero ? "mt-4" : "mt-8" }),
245
+ !hero && description && /* @__PURE__ */ jsx("p", { className: "mt-3 hidden max-w-[440px] text-[14px] leading-relaxed text-[color:var(--chat-empty-description-color)] @[420px]:block", children: description }),
246
+ /* @__PURE__ */ jsx(ChatSuggestionGrid, { suggestions, onSelect, className: hero ? "mt-4" : "mt-8" }),
247
247
  footer
248
248
  ]
249
249
  }
@@ -345,7 +345,7 @@ var builtinCommands = [
345
345
  import { useState } from "react";
346
346
  import { createPatch } from "diff";
347
347
  import { Button as Button2 } from "@hachej/boring-ui-kit";
348
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
348
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
349
349
  var COLLAPSE_THRESHOLD = 30;
350
350
  function parsePatch(patch) {
351
351
  const lines = patch.split("\n");
@@ -370,7 +370,7 @@ var prefixMap = { "+": "+", "-": "-", " ": " " };
370
370
  function DiffView({ oldString, newString, path, replaceAll, actions }) {
371
371
  const [expanded, setExpanded] = useState(false);
372
372
  if (oldString === newString) {
373
- return /* @__PURE__ */ jsx3("div", { "data-testid": "diff-no-change", className: "py-2 italic opacity-60", children: "No changes" });
373
+ return /* @__PURE__ */ jsx2("div", { "data-testid": "diff-no-change", className: "py-2 italic opacity-60", children: "No changes" });
374
374
  }
375
375
  const patch = createPatch(path, oldString, newString, "", "", { context: 3 });
376
376
  const lines = parsePatch(patch);
@@ -382,10 +382,10 @@ function DiffView({ oldString, newString, path, replaceAll, actions }) {
382
382
  path,
383
383
  replaceAll ? " (replace all)" : ""
384
384
  ] }),
385
- actions ? /* @__PURE__ */ jsx3("span", { className: "flex shrink-0 items-center gap-0.5", children: actions }) : null
385
+ actions ? /* @__PURE__ */ jsx2("span", { className: "flex shrink-0 items-center gap-0.5", children: actions }) : null
386
386
  ] }),
387
- /* @__PURE__ */ jsx3("pre", { className: "m-0 overflow-auto py-2 font-[family-name:var(--boring-agent-font-mono,monospace)] text-[0.8125rem] leading-relaxed", children: visible.map((line, i) => /* @__PURE__ */ jsxs2("div", { className: cn("px-3", lineClass[line.type]), children: [
388
- /* @__PURE__ */ jsx3("span", { className: "inline-block w-[1.5ch] select-none opacity-50", children: prefixMap[line.type] }),
387
+ /* @__PURE__ */ jsx2("pre", { className: "m-0 overflow-auto py-2 font-[family-name:var(--boring-agent-font-mono,monospace)] text-[0.8125rem] leading-relaxed", children: visible.map((line, i) => /* @__PURE__ */ jsxs2("div", { className: cn("px-3", lineClass[line.type]), children: [
388
+ /* @__PURE__ */ jsx2("span", { className: "inline-block w-[1.5ch] select-none opacity-50", children: prefixMap[line.type] }),
389
389
  line.text
390
390
  ] }, i)) }),
391
391
  collapsed && /* @__PURE__ */ jsxs2(Button2, { type: "button", variant: "ghost", size: "sm", onClick: () => setExpanded(true), className: "w-full rounded-none text-xs opacity-60", children: [
@@ -399,7 +399,7 @@ function DiffView({ oldString, newString, path, replaceAll, actions }) {
399
399
  // src/front/barePrimitives/Tool.tsx
400
400
  import { useEffect, useRef, useState as useState2 } from "react";
401
401
  import { Button as Button3 } from "@hachej/boring-ui-kit";
402
- import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
402
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
403
403
  function stateLabel(state) {
404
404
  switch (state) {
405
405
  case "input-streaming":
@@ -420,7 +420,7 @@ function stateLabel(state) {
420
420
  }
421
421
  }
422
422
  function ToolValue({ value }) {
423
- return /* @__PURE__ */ jsx4("pre", { className: "m-0 whitespace-pre-wrap text-[0.8125rem]", children: typeof value === "string" ? value : JSON.stringify(value, null, 2) });
423
+ return /* @__PURE__ */ jsx3("pre", { className: "m-0 whitespace-pre-wrap text-[0.8125rem]", children: typeof value === "string" ? value : JSON.stringify(value, null, 2) });
424
424
  }
425
425
  function Tool({
426
426
  toolName,
@@ -468,17 +468,17 @@ function Tool({
468
468
  className: "h-auto w-full justify-start gap-2 rounded-none bg-[var(--boring-agent-tool-header-bg,#f9fafb)] px-3 py-2 text-left font-[family-name:var(--boring-agent-font-mono,monospace)] text-[0.8125rem]",
469
469
  "aria-expanded": expanded,
470
470
  children: [
471
- /* @__PURE__ */ jsx4("span", { className: cn("transition-transform duration-150", expanded && "rotate-90"), children: "\u25B6" }),
472
- /* @__PURE__ */ jsx4("span", { className: "font-medium", children: toolName }),
473
- /* @__PURE__ */ jsx4("span", { className: "ml-auto text-xs opacity-60", children: isRunning && elapsedSec >= 1 ? `Running\u2026 (${elapsedSec}s)` : stateLabel(state) }),
474
- !isComplete && /* @__PURE__ */ jsx4("span", { className: "size-2 rounded-full bg-[var(--boring-agent-tool-running,#3b82f6)]", "aria-label": "running" })
471
+ /* @__PURE__ */ jsx3("span", { className: cn("transition-transform duration-150", expanded && "rotate-90"), children: "\u25B6" }),
472
+ /* @__PURE__ */ jsx3("span", { className: "font-medium", children: toolName }),
473
+ /* @__PURE__ */ jsx3("span", { className: "ml-auto text-xs opacity-60", children: isRunning && elapsedSec >= 1 ? `Running\u2026 (${elapsedSec}s)` : stateLabel(state) }),
474
+ !isComplete && /* @__PURE__ */ jsx3("span", { className: "size-2 rounded-full bg-[var(--boring-agent-tool-running,#3b82f6)]", "aria-label": "running" })
475
475
  ]
476
476
  }
477
477
  ),
478
- expanded && /* @__PURE__ */ jsx4("div", { className: "border-t border-[var(--boring-agent-tool-border,#e5e7eb)] px-3 py-2", children: children ?? /* @__PURE__ */ jsxs3(Fragment, { children: [
479
- input !== void 0 && /* @__PURE__ */ jsx4("div", { "data-testid": "tool-input", children: renderInput ? renderInput(input) : /* @__PURE__ */ jsx4(ToolValue, { value: input }) }),
480
- output !== void 0 && /* @__PURE__ */ jsx4("div", { "data-testid": "tool-output", className: "mt-2", children: renderOutput ? renderOutput(output) : /* @__PURE__ */ jsx4(ToolValue, { value: output }) }),
481
- errorText && /* @__PURE__ */ jsx4("div", { "data-testid": "tool-error", className: "mt-2 text-[var(--boring-agent-tool-error,#ef4444)]", children: errorText })
478
+ expanded && /* @__PURE__ */ jsx3("div", { className: "border-t border-[var(--boring-agent-tool-border,#e5e7eb)] px-3 py-2", children: children ?? /* @__PURE__ */ jsxs3(Fragment, { children: [
479
+ input !== void 0 && /* @__PURE__ */ jsx3("div", { "data-testid": "tool-input", children: renderInput ? renderInput(input) : /* @__PURE__ */ jsx3(ToolValue, { value: input }) }),
480
+ output !== void 0 && /* @__PURE__ */ jsx3("div", { "data-testid": "tool-output", className: "mt-2", children: renderOutput ? renderOutput(output) : /* @__PURE__ */ jsx3(ToolValue, { value: output }) }),
481
+ errorText && /* @__PURE__ */ jsx3("div", { "data-testid": "tool-error", className: "mt-2 text-[var(--boring-agent-tool-error,#ef4444)]", children: errorText })
482
482
  ] }) })
483
483
  ]
484
484
  }
@@ -486,7 +486,7 @@ function Tool({
486
486
  }
487
487
 
488
488
  // src/front/barePrimitives/Terminal.tsx
489
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
489
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
490
490
  function Terminal({
491
491
  children,
492
492
  stdout,
@@ -503,10 +503,10 @@ function Terminal({
503
503
  className
504
504
  ),
505
505
  children: [
506
- title && /* @__PURE__ */ jsx5("div", { className: "border-b border-[var(--boring-agent-terminal-border,#404040)] bg-[var(--boring-agent-terminal-header-bg,#2d2d2d)] px-3 py-1.5 text-xs opacity-80", children: title }),
507
- /* @__PURE__ */ jsx5("div", { className: "p-3", children: children ?? /* @__PURE__ */ jsxs4(Fragment2, { children: [
508
- stdout && /* @__PURE__ */ jsx5("pre", { "data-stream": "stdout", className: "m-0 whitespace-pre-wrap", children: stdout }),
509
- stderr && /* @__PURE__ */ jsx5(
506
+ title && /* @__PURE__ */ jsx4("div", { className: "border-b border-[var(--boring-agent-terminal-border,#404040)] bg-[var(--boring-agent-terminal-header-bg,#2d2d2d)] px-3 py-1.5 text-xs opacity-80", children: title }),
507
+ /* @__PURE__ */ jsx4("div", { className: "p-3", children: children ?? /* @__PURE__ */ jsxs4(Fragment2, { children: [
508
+ stdout && /* @__PURE__ */ jsx4("pre", { "data-stream": "stdout", className: "m-0 whitespace-pre-wrap", children: stdout }),
509
+ stderr && /* @__PURE__ */ jsx4(
510
510
  "pre",
511
511
  {
512
512
  "data-stream": "stderr",
@@ -540,7 +540,7 @@ function Terminal({
540
540
  // src/front/barePrimitives/CodeBlock.tsx
541
541
  import { useCallback, useState as useState3 } from "react";
542
542
  import { Button as Button4 } from "@hachej/boring-ui-kit";
543
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
543
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
544
544
  function CodeBlock({
545
545
  code: code3,
546
546
  language,
@@ -568,14 +568,14 @@ function CodeBlock({
568
568
  ),
569
569
  children: [
570
570
  (filename || language) && /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between border-b border-[var(--boring-agent-code-border,#404040)] bg-[var(--boring-agent-code-header-bg,#2d2d2d)] px-3 py-1.5 text-xs", children: [
571
- /* @__PURE__ */ jsx6("span", { className: "opacity-70", children: filename ?? language }),
572
- copyable && /* @__PURE__ */ jsx6(Button4, { type: "button", variant: "ghost", size: "xs", onClick: handleCopy, "aria-label": "Copy code", className: "h-6 px-1.5 text-xs text-inherit opacity-60", children: copied ? "Copied" : "Copy" })
571
+ /* @__PURE__ */ jsx5("span", { className: "opacity-70", children: filename ?? language }),
572
+ copyable && /* @__PURE__ */ jsx5(Button4, { type: "button", variant: "ghost", size: "xs", onClick: handleCopy, "aria-label": "Copy code", className: "h-6 px-1.5 text-xs text-inherit opacity-60", children: copied ? "Copied" : "Copy" })
573
573
  ] }),
574
- /* @__PURE__ */ jsx6("pre", { className: "m-0 overflow-auto p-3", children: /* @__PURE__ */ jsx6("code", { "data-language": language, children: showLineNumbers ? lines.map((line, i) => /* @__PURE__ */ jsxs5("span", { className: "block", children: [
575
- /* @__PURE__ */ jsx6("span", { className: "mr-4 inline-block select-none text-right opacity-40", style: { width: lineNumberWidth }, children: i + 1 }),
574
+ /* @__PURE__ */ jsx5("pre", { className: "m-0 overflow-auto p-3", children: /* @__PURE__ */ jsx5("code", { "data-language": language, children: showLineNumbers ? lines.map((line, i) => /* @__PURE__ */ jsxs5("span", { className: "block", children: [
575
+ /* @__PURE__ */ jsx5("span", { className: "mr-4 inline-block select-none text-right opacity-40", style: { width: lineNumberWidth }, children: i + 1 }),
576
576
  line
577
577
  ] }, i)) : code3 }) }),
578
- copyable && !filename && !language && /* @__PURE__ */ jsx6(
578
+ copyable && !filename && !language && /* @__PURE__ */ jsx5(
579
579
  Button4,
580
580
  {
581
581
  type: "button",
@@ -593,7 +593,7 @@ function CodeBlock({
593
593
  }
594
594
 
595
595
  // src/front/bareToolRenderers/renderers.tsx
596
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
596
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
597
597
  var FALLBACK_RENDERER_KEY = "__fallback";
598
598
  function asRecord(v) {
599
599
  return typeof v === "object" && v !== null ? v : {};
@@ -703,14 +703,14 @@ function renderBash(part) {
703
703
  const stdout = typeof output.stdout === "string" ? output.stdout : output.content ? JSON.stringify(output.content) : void 0;
704
704
  const stderr = typeof output.stderr === "string" ? output.stderr : void 0;
705
705
  const exitCode = typeof output.exitCode === "number" ? output.exitCode : void 0;
706
- return /* @__PURE__ */ jsx7(Tool, { toolName: "bash", toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, defaultExpanded: true, children: /* @__PURE__ */ jsx7(Terminal, { title: `$ ${command}`, stdout, stderr, exitCode: exitCode ?? null }) });
706
+ return /* @__PURE__ */ jsx6(Tool, { toolName: "bash", toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, defaultExpanded: true, children: /* @__PURE__ */ jsx6(Terminal, { title: `$ ${command}`, stdout, stderr, exitCode: exitCode ?? null }) });
707
707
  }
708
708
  function renderRead(part) {
709
709
  const input = asRecord(part.input);
710
710
  const output = asRecord(part.output);
711
711
  const path = String(input.path ?? "");
712
712
  const content = typeof output.text === "string" ? output.text : Array.isArray(output.content) ? output.content.map((c) => c.text ?? "").join("") : typeof output.content === "string" ? output.content : void 0;
713
- return /* @__PURE__ */ jsx7(Tool, { toolName: "read", toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, children: content != null ? /* @__PURE__ */ jsx7(CodeBlock, { code: content, language: langFromPath(path), filename: path }) : /* @__PURE__ */ jsxs6("span", { style: { opacity: 0.6 }, children: [
713
+ return /* @__PURE__ */ jsx6(Tool, { toolName: "read", toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, children: content != null ? /* @__PURE__ */ jsx6(CodeBlock, { code: content, language: langFromPath(path), filename: path }) : /* @__PURE__ */ jsxs6("span", { style: { opacity: 0.6 }, children: [
714
714
  "Reading ",
715
715
  path,
716
716
  "\u2026"
@@ -720,11 +720,11 @@ function renderWrite(part) {
720
720
  const input = asRecord(part.input);
721
721
  const path = String(input.path ?? "");
722
722
  const content = typeof input.content === "string" ? input.content : "";
723
- return /* @__PURE__ */ jsx7(Tool, { toolName: "write", toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, defaultExpanded: true, children: /* @__PURE__ */ jsxs6("span", { style: { fontFamily: "var(--boring-agent-font-mono, monospace)", fontSize: "0.8125rem" }, children: [
723
+ return /* @__PURE__ */ jsx6(Tool, { toolName: "write", toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, defaultExpanded: true, children: /* @__PURE__ */ jsxs6("span", { style: { fontFamily: "var(--boring-agent-font-mono, monospace)", fontSize: "0.8125rem" }, children: [
724
724
  "Wrote ",
725
725
  content.length,
726
726
  " bytes to ",
727
- /* @__PURE__ */ jsx7("strong", { children: path })
727
+ /* @__PURE__ */ jsx6("strong", { children: path })
728
728
  ] }) });
729
729
  }
730
730
  function renderEdit(part) {
@@ -733,7 +733,7 @@ function renderEdit(part) {
733
733
  const oldString = typeof input.oldString === "string" ? input.oldString : "";
734
734
  const newString = typeof input.newString === "string" ? input.newString : "";
735
735
  const replaceAll = Boolean(input.replaceAll);
736
- return /* @__PURE__ */ jsx7(Tool, { toolName: "edit", toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, defaultExpanded: true, children: /* @__PURE__ */ jsx7(DiffView, { oldString, newString, path, replaceAll }) });
736
+ return /* @__PURE__ */ jsx6(Tool, { toolName: "edit", toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, defaultExpanded: true, children: /* @__PURE__ */ jsx6(DiffView, { oldString, newString, path, replaceAll }) });
737
737
  }
738
738
  function renderSearchLike(toolName, part) {
739
739
  const input = asRecord(part.input);
@@ -742,17 +742,17 @@ function renderSearchLike(toolName, part) {
742
742
  const path = typeof input.path === "string" ? input.path : "";
743
743
  const pattern = typeof input.pattern === "string" ? input.pattern : "";
744
744
  const title = [toolName, pattern || path].filter(Boolean).join(" ");
745
- return /* @__PURE__ */ jsx7(Tool, { toolName, toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, children: content ? /* @__PURE__ */ jsx7(CodeBlock, { code: content, language: "text", filename: title }) : /* @__PURE__ */ jsx7("span", { style: { opacity: 0.6 }, children: toolName === "ls" ? `Listing ${path || "."}...` : `Searching ${pattern || path || "."}...` }) });
745
+ return /* @__PURE__ */ jsx6(Tool, { toolName, toolCallId: part.toolCallId, state: part.state, errorText: part.errorText, children: content ? /* @__PURE__ */ jsx6(CodeBlock, { code: content, language: "text", filename: title }) : /* @__PURE__ */ jsx6("span", { style: { opacity: 0.6 }, children: toolName === "ls" ? `Listing ${path || "."}...` : `Searching ${pattern || path || "."}...` }) });
746
746
  }
747
747
  function renderGetUiState(part) {
748
- return /* @__PURE__ */ jsx7(
748
+ return /* @__PURE__ */ jsx6(
749
749
  Tool,
750
750
  {
751
751
  toolName: "get_ui_state",
752
752
  toolCallId: part.toolCallId,
753
753
  state: part.state,
754
754
  errorText: part.errorText,
755
- renderOutput: (output) => /* @__PURE__ */ jsx7("pre", { style: { margin: 0, whiteSpace: "pre-wrap", fontSize: "0.8125rem", fontFamily: "var(--boring-agent-font-mono, monospace)" }, children: typeof output === "string" ? output : JSON.stringify(output, null, 2) }),
755
+ renderOutput: (output) => /* @__PURE__ */ jsx6("pre", { style: { margin: 0, whiteSpace: "pre-wrap", fontSize: "0.8125rem", fontFamily: "var(--boring-agent-font-mono, monospace)" }, children: typeof output === "string" ? output : JSON.stringify(output, null, 2) }),
756
756
  input: part.input,
757
757
  output: part.output
758
758
  }
@@ -764,7 +764,7 @@ function renderExecUi(part) {
764
764
  const params = input.params;
765
765
  const paramsText = params !== void 0 && params !== null ? typeof params === "string" ? params : JSON.stringify(params) : "";
766
766
  const summary = kind ? `${kind}${paramsText ? `(${paramsText})` : ""}` : "(empty)";
767
- return /* @__PURE__ */ jsx7(
767
+ return /* @__PURE__ */ jsx6(
768
768
  Tool,
769
769
  {
770
770
  toolName: "exec_ui",
@@ -787,7 +787,7 @@ function renderExecUi(part) {
787
787
  ]
788
788
  }
789
789
  ),
790
- part.errorText && /* @__PURE__ */ jsx7(
790
+ part.errorText && /* @__PURE__ */ jsx6(
791
791
  "span",
792
792
  {
793
793
  "data-testid": "tool-error",
@@ -809,7 +809,7 @@ function fallbackToolName(part) {
809
809
  return part.toolName;
810
810
  }
811
811
  function renderFallback(part) {
812
- const renderJson = (value) => /* @__PURE__ */ jsx7(
812
+ const renderJson = (value) => /* @__PURE__ */ jsx6(
813
813
  "pre",
814
814
  {
815
815
  style: {
@@ -821,7 +821,7 @@ function renderFallback(part) {
821
821
  children: typeof value === "string" ? value : JSON.stringify(value, null, 2)
822
822
  }
823
823
  );
824
- return /* @__PURE__ */ jsx7(
824
+ return /* @__PURE__ */ jsx6(
825
825
  Tool,
826
826
  {
827
827
  toolName: fallbackToolName(part),
@@ -912,17 +912,17 @@ import {
912
912
  } from "@hachej/boring-ui-kit";
913
913
  import { CheckIcon, CopyIcon } from "lucide-react";
914
914
  import {
915
- createContext as createContext2,
915
+ createContext,
916
916
  memo,
917
917
  useCallback as useCallback2,
918
- useContext as useContext2,
918
+ useContext,
919
919
  useEffect as useEffect2,
920
920
  useMemo,
921
921
  useRef as useRef2,
922
922
  useState as useState4
923
923
  } from "react";
924
924
  import { createHighlighter } from "shiki";
925
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
925
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
926
926
  var isItalic = (fontStyle) => fontStyle && fontStyle & 1;
927
927
  var isBold = (fontStyle) => fontStyle && fontStyle & 2;
928
928
  var isUnderline = (fontStyle) => (
@@ -936,7 +936,7 @@ var addKeysToTokens = (lines) => lines.map((line, lineIdx) => ({
936
936
  token
937
937
  }))
938
938
  }));
939
- var TokenSpan = ({ token }) => /* @__PURE__ */ jsx8(
939
+ var TokenSpan = ({ token }) => /* @__PURE__ */ jsx7(
940
940
  "span",
941
941
  {
942
942
  className: "dark:!text-[var(--shiki-dark)]",
@@ -966,8 +966,8 @@ var LINE_NUMBER_CLASSES = cn(
966
966
  var LineSpan = ({
967
967
  keyedLine,
968
968
  showLineNumbers
969
- }) => /* @__PURE__ */ jsx8("span", { className: showLineNumbers ? LINE_NUMBER_CLASSES : "block", children: keyedLine.tokens.length === 0 ? "\n" : keyedLine.tokens.map(({ token, key }) => /* @__PURE__ */ jsx8(TokenSpan, { token }, key)) });
970
- var CodeBlockContext = createContext2({
969
+ }) => /* @__PURE__ */ jsx7("span", { className: showLineNumbers ? LINE_NUMBER_CLASSES : "block", children: keyedLine.tokens.length === 0 ? "\n" : keyedLine.tokens.map(({ token, key }) => /* @__PURE__ */ jsx7(TokenSpan, { token }, key)) });
970
+ var CodeBlockContext = createContext({
971
971
  code: ""
972
972
  });
973
973
  var highlighterCache = /* @__PURE__ */ new Map();
@@ -1059,7 +1059,7 @@ var CodeBlockBody = memo(
1059
1059
  () => addKeysToTokens(tokenized.tokens),
1060
1060
  [tokenized.tokens]
1061
1061
  );
1062
- return /* @__PURE__ */ jsx8(
1062
+ return /* @__PURE__ */ jsx7(
1063
1063
  "pre",
1064
1064
  {
1065
1065
  className: cn(
@@ -1067,14 +1067,14 @@ var CodeBlockBody = memo(
1067
1067
  className
1068
1068
  ),
1069
1069
  style: preStyle,
1070
- children: /* @__PURE__ */ jsx8(
1070
+ children: /* @__PURE__ */ jsx7(
1071
1071
  "code",
1072
1072
  {
1073
1073
  className: cn(
1074
1074
  "font-mono text-sm",
1075
1075
  showLineNumbers && "[counter-increment:line_0] [counter-reset:line]"
1076
1076
  ),
1077
- children: keyedLines.map((keyedLine) => /* @__PURE__ */ jsx8(
1077
+ children: keyedLines.map((keyedLine) => /* @__PURE__ */ jsx7(
1078
1078
  LineSpan,
1079
1079
  {
1080
1080
  keyedLine,
@@ -1095,7 +1095,7 @@ var CodeBlockContainer = ({
1095
1095
  language,
1096
1096
  style,
1097
1097
  ...props
1098
- }) => /* @__PURE__ */ jsx8(
1098
+ }) => /* @__PURE__ */ jsx7(
1099
1099
  "div",
1100
1100
  {
1101
1101
  className: cn(
@@ -1115,7 +1115,7 @@ var CodeBlockHeader = ({
1115
1115
  children,
1116
1116
  className,
1117
1117
  ...props
1118
- }) => /* @__PURE__ */ jsx8(
1118
+ }) => /* @__PURE__ */ jsx7(
1119
1119
  "div",
1120
1120
  {
1121
1121
  className: cn(
@@ -1130,12 +1130,12 @@ var CodeBlockTitle = ({
1130
1130
  children,
1131
1131
  className,
1132
1132
  ...props
1133
- }) => /* @__PURE__ */ jsx8("div", { className: cn("flex items-center gap-2", className), ...props, children });
1133
+ }) => /* @__PURE__ */ jsx7("div", { className: cn("flex items-center gap-2", className), ...props, children });
1134
1134
  var CodeBlockFilename = ({
1135
1135
  children,
1136
1136
  className,
1137
1137
  ...props
1138
- }) => /* @__PURE__ */ jsx8(
1138
+ }) => /* @__PURE__ */ jsx7(
1139
1139
  "span",
1140
1140
  {
1141
1141
  className: cn(
@@ -1175,7 +1175,7 @@ var CodeBlockContent = ({
1175
1175
  };
1176
1176
  }, [code3, language]);
1177
1177
  const tokenized = asyncTokens ?? syncTokens;
1178
- return /* @__PURE__ */ jsx8("div", { className: "relative overflow-auto", children: /* @__PURE__ */ jsx8(CodeBlockBody, { showLineNumbers, tokenized }) });
1178
+ return /* @__PURE__ */ jsx7("div", { className: "relative overflow-auto", children: /* @__PURE__ */ jsx7(CodeBlockBody, { showLineNumbers, tokenized }) });
1179
1179
  };
1180
1180
  var CodeBlock2 = ({
1181
1181
  code: code3,
@@ -1186,9 +1186,9 @@ var CodeBlock2 = ({
1186
1186
  ...props
1187
1187
  }) => {
1188
1188
  const contextValue = useMemo(() => ({ code: code3 }), [code3]);
1189
- return /* @__PURE__ */ jsx8(CodeBlockContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs7(CodeBlockContainer, { className, language, ...props, children: [
1189
+ return /* @__PURE__ */ jsx7(CodeBlockContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs7(CodeBlockContainer, { className, language, ...props, children: [
1190
1190
  children,
1191
- /* @__PURE__ */ jsx8(
1191
+ /* @__PURE__ */ jsx7(
1192
1192
  CodeBlockContent,
1193
1193
  {
1194
1194
  code: code3,
@@ -1208,7 +1208,7 @@ var CodeBlockCopyButton = ({
1208
1208
  }) => {
1209
1209
  const [isCopied, setIsCopied] = useState4(false);
1210
1210
  const timeoutRef = useRef2(0);
1211
- const { code: code3 } = useContext2(CodeBlockContext);
1211
+ const { code: code3 } = useContext(CodeBlockContext);
1212
1212
  const copyToClipboard = useCallback2(async () => {
1213
1213
  if (typeof window === "undefined") {
1214
1214
  onError?.(new Error("Clipboard API not available"));
@@ -1236,7 +1236,7 @@ var CodeBlockCopyButton = ({
1236
1236
  []
1237
1237
  );
1238
1238
  const Icon = isCopied ? CheckIcon : CopyIcon;
1239
- return /* @__PURE__ */ jsx8(
1239
+ return /* @__PURE__ */ jsx7(
1240
1240
  Button5,
1241
1241
  {
1242
1242
  className: cn("shrink-0", className),
@@ -1244,14 +1244,14 @@ var CodeBlockCopyButton = ({
1244
1244
  size: "icon",
1245
1245
  variant: "ghost",
1246
1246
  ...props,
1247
- children: children ?? /* @__PURE__ */ jsx8(Icon, { size: 14 })
1247
+ children: children ?? /* @__PURE__ */ jsx7(Icon, { size: 14 })
1248
1248
  }
1249
1249
  );
1250
1250
  };
1251
1251
 
1252
1252
  // src/front/primitives/tool.tsx
1253
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1254
- var Tool2 = ({ className, ...props }) => /* @__PURE__ */ jsx9(
1253
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1254
+ var Tool2 = ({ className, ...props }) => /* @__PURE__ */ jsx8(
1255
1255
  Collapsible,
1256
1256
  {
1257
1257
  "data-boring-agent-part": "tool-card",
@@ -1279,14 +1279,14 @@ var statusLabels = {
1279
1279
  aborted: "Aborted"
1280
1280
  };
1281
1281
  var statusIcons = {
1282
- "approval-requested": /* @__PURE__ */ jsx9(ClockIcon, { className: "size-4 text-accent" }),
1283
- "approval-responded": /* @__PURE__ */ jsx9(CheckCircleIcon, { className: "size-4 text-accent" }),
1284
- "input-available": /* @__PURE__ */ jsx9(ClockIcon, { className: "size-4 animate-pulse text-muted-foreground" }),
1285
- "input-streaming": /* @__PURE__ */ jsx9(CircleIcon, { className: "size-4 text-muted-foreground" }),
1286
- "output-available": /* @__PURE__ */ jsx9(CheckCircleIcon, { className: "size-4 text-accent" }),
1287
- "output-denied": /* @__PURE__ */ jsx9(XCircleIcon, { className: "size-4 text-destructive" }),
1288
- "output-error": /* @__PURE__ */ jsx9(XCircleIcon, { className: "size-4 text-destructive" }),
1289
- aborted: /* @__PURE__ */ jsx9(XCircleIcon, { className: "size-4 text-muted-foreground" })
1282
+ "approval-requested": /* @__PURE__ */ jsx8(ClockIcon, { className: "size-4 text-accent" }),
1283
+ "approval-responded": /* @__PURE__ */ jsx8(CheckCircleIcon, { className: "size-4 text-accent" }),
1284
+ "input-available": /* @__PURE__ */ jsx8(ClockIcon, { className: "size-4 animate-pulse text-muted-foreground" }),
1285
+ "input-streaming": /* @__PURE__ */ jsx8(CircleIcon, { className: "size-4 text-muted-foreground" }),
1286
+ "output-available": /* @__PURE__ */ jsx8(CheckCircleIcon, { className: "size-4 text-accent" }),
1287
+ "output-denied": /* @__PURE__ */ jsx8(XCircleIcon, { className: "size-4 text-destructive" }),
1288
+ "output-error": /* @__PURE__ */ jsx8(XCircleIcon, { className: "size-4 text-destructive" }),
1289
+ aborted: /* @__PURE__ */ jsx8(XCircleIcon, { className: "size-4 text-muted-foreground" })
1290
1290
  };
1291
1291
  var getStatusBadge = (status, label = statusLabels[status]) => /* @__PURE__ */ jsxs8(Badge, { className: "shrink-0 gap-1.5 rounded-full text-xs", variant: "secondary", children: [
1292
1292
  statusIcons[status],
@@ -1314,11 +1314,11 @@ var ToolHeader = ({
1314
1314
  ...props,
1315
1315
  children: [
1316
1316
  /* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
1317
- icon ?? /* @__PURE__ */ jsx9(WrenchIcon, { className: "size-4 shrink-0 text-muted-foreground" }),
1318
- /* @__PURE__ */ jsx9("span", { "data-boring-agent-part": "tool-title", className: "min-w-0 flex-1 truncate text-sm font-medium", children: title ?? derivedName }),
1317
+ icon ?? /* @__PURE__ */ jsx8(WrenchIcon, { className: "size-4 shrink-0 text-muted-foreground" }),
1318
+ /* @__PURE__ */ jsx8("span", { "data-boring-agent-part": "tool-title", className: "min-w-0 flex-1 truncate text-sm font-medium", children: title ?? derivedName }),
1319
1319
  getStatusBadge(state, statusLabel)
1320
1320
  ] }),
1321
- /* @__PURE__ */ jsx9(
1321
+ /* @__PURE__ */ jsx8(
1322
1322
  ChevronDownIcon,
1323
1323
  {
1324
1324
  "data-boring-agent-part": "tool-chevron",
@@ -1329,7 +1329,7 @@ var ToolHeader = ({
1329
1329
  }
1330
1330
  );
1331
1331
  };
1332
- var ToolContent = ({ className, ...props }) => /* @__PURE__ */ jsx9(
1332
+ var ToolContent = ({ className, ...props }) => /* @__PURE__ */ jsx8(
1333
1333
  CollapsibleContent,
1334
1334
  {
1335
1335
  className: cn(
@@ -1340,8 +1340,8 @@ var ToolContent = ({ className, ...props }) => /* @__PURE__ */ jsx9(
1340
1340
  }
1341
1341
  );
1342
1342
  var ToolInput = ({ className, input, ...props }) => /* @__PURE__ */ jsxs8("div", { className: cn("space-y-2 overflow-hidden", className), ...props, children: [
1343
- /* @__PURE__ */ jsx9("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: "Parameters" }),
1344
- /* @__PURE__ */ jsx9("div", { className: "rounded-md bg-muted/50", children: /* @__PURE__ */ jsx9(CodeBlock2, { code: JSON.stringify(input, null, 2), language: "json" }) })
1343
+ /* @__PURE__ */ jsx8("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: "Parameters" }),
1344
+ /* @__PURE__ */ jsx8("div", { className: "rounded-md bg-muted/50", children: /* @__PURE__ */ jsx8(CodeBlock2, { code: JSON.stringify(input, null, 2), language: "json" }) })
1345
1345
  ] });
1346
1346
  var ToolOutput = ({
1347
1347
  className,
@@ -1355,15 +1355,15 @@ var ToolOutput = ({
1355
1355
  let Output = null;
1356
1356
  if (!errorText) {
1357
1357
  if (typeof output === "object" && !isValidElement(output)) {
1358
- Output = /* @__PURE__ */ jsx9(CodeBlock2, { code: JSON.stringify(output, null, 2), language: "json" });
1358
+ Output = /* @__PURE__ */ jsx8(CodeBlock2, { code: JSON.stringify(output, null, 2), language: "json" });
1359
1359
  } else if (typeof output === "string") {
1360
- Output = /* @__PURE__ */ jsx9(CodeBlock2, { code: output, language: "text" });
1360
+ Output = /* @__PURE__ */ jsx8(CodeBlock2, { code: output, language: "text" });
1361
1361
  } else if (output) {
1362
- Output = /* @__PURE__ */ jsx9("div", { children: output });
1362
+ Output = /* @__PURE__ */ jsx8("div", { children: output });
1363
1363
  }
1364
1364
  }
1365
1365
  return /* @__PURE__ */ jsxs8("div", { "data-boring-agent-part": "tool-result", className: cn("space-y-2", className), ...props, children: [
1366
- /* @__PURE__ */ jsx9("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: errorText ? "Error" : "Result" }),
1366
+ /* @__PURE__ */ jsx8("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: errorText ? "Error" : "Result" }),
1367
1367
  /* @__PURE__ */ jsxs8(
1368
1368
  "div",
1369
1369
  {
@@ -1372,7 +1372,7 @@ var ToolOutput = ({
1372
1372
  errorText ? "overflow-hidden border border-destructive/20 bg-destructive/10 text-destructive" : "overflow-x-auto bg-muted/30 text-foreground"
1373
1373
  ),
1374
1374
  children: [
1375
- errorText ? /* @__PURE__ */ jsx9("pre", { className: "m-0 overflow-x-auto whitespace-pre-wrap break-words p-3 font-mono text-[12px] leading-5 [overflow-wrap:anywhere]", children: errorText }) : null,
1375
+ errorText ? /* @__PURE__ */ jsx8("pre", { className: "m-0 overflow-x-auto whitespace-pre-wrap break-words p-3 font-mono text-[12px] leading-5 [overflow-wrap:anywhere]", children: errorText }) : null,
1376
1376
  Output
1377
1377
  ]
1378
1378
  }
@@ -1384,52 +1384,6 @@ var ToolOutput = ({
1384
1384
  import { CollapsibleTrigger as CollapsibleTrigger2 } from "@hachej/boring-ui-kit";
1385
1385
  import { ChevronDownIcon as ChevronDownIcon2, CopyIcon as CopyIcon2, DownloadIcon, ExternalLinkIcon, FileDiffIcon, FilePlus2Icon, FileTextIcon, SearchIcon, SquareTerminalIcon, ZapIcon } from "lucide-react";
1386
1386
 
1387
- // src/front/primitives/artifact.tsx
1388
- import { Button as Button6 } from "@hachej/boring-ui-kit";
1389
- import {
1390
- Tooltip,
1391
- TooltipContent,
1392
- TooltipProvider,
1393
- TooltipTrigger
1394
- } from "@hachej/boring-ui-kit";
1395
- import { XIcon } from "lucide-react";
1396
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1397
- var ArtifactAction = ({
1398
- tooltip,
1399
- label,
1400
- icon: Icon,
1401
- children,
1402
- className,
1403
- size = "sm",
1404
- variant = "ghost",
1405
- ...props
1406
- }) => {
1407
- const button = /* @__PURE__ */ jsxs9(
1408
- Button6,
1409
- {
1410
- className: cn(
1411
- "size-8 p-0 text-muted-foreground hover:text-foreground",
1412
- className
1413
- ),
1414
- size,
1415
- type: "button",
1416
- variant,
1417
- ...props,
1418
- children: [
1419
- Icon ? /* @__PURE__ */ jsx10(Icon, { className: "size-4" }) : children,
1420
- /* @__PURE__ */ jsx10("span", { className: "sr-only", children: label || tooltip })
1421
- ]
1422
- }
1423
- );
1424
- if (tooltip) {
1425
- return /* @__PURE__ */ jsx10(TooltipProvider, { children: /* @__PURE__ */ jsxs9(Tooltip, { children: [
1426
- /* @__PURE__ */ jsx10(TooltipTrigger, { asChild: true, children: button }),
1427
- /* @__PURE__ */ jsx10(TooltipContent, { children: /* @__PURE__ */ jsx10("p", { children: tooltip }) })
1428
- ] }) });
1429
- }
1430
- return button;
1431
- };
1432
-
1433
1387
  // src/front/runtimeReadinessStatus.ts
1434
1388
  var COPY = {
1435
1389
  "runtime-dependencies": "Runtime dependencies are still installing.",
@@ -1494,7 +1448,7 @@ function getWorkspaceNotReadyStatus(output) {
1494
1448
  }
1495
1449
 
1496
1450
  // src/front/toolRenderers.tsx
1497
- import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1451
+ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1498
1452
  function asRecord2(value) {
1499
1453
  return typeof value === "object" && value !== null ? value : {};
1500
1454
  }
@@ -1518,7 +1472,7 @@ function toHeaderProps(part) {
1518
1472
  function PathLabel({ path, filesystem }) {
1519
1473
  const onOpen = useOpenArtifact();
1520
1474
  if (!onOpen) {
1521
- return /* @__PURE__ */ jsx11("span", { className: "font-mono text-[12.5px] text-foreground/85", children: path });
1475
+ return /* @__PURE__ */ jsx9("span", { className: "font-mono text-[12.5px] text-foreground/85", children: path });
1522
1476
  }
1523
1477
  const open = (e) => {
1524
1478
  e.preventDefault();
@@ -1529,7 +1483,7 @@ function PathLabel({ path, filesystem }) {
1529
1483
  const handleKeyDown = (e) => {
1530
1484
  if (e.key === "Enter" || e.key === " ") open(e);
1531
1485
  };
1532
- return /* @__PURE__ */ jsxs10(
1486
+ return /* @__PURE__ */ jsxs9(
1533
1487
  "span",
1534
1488
  {
1535
1489
  role: "button",
@@ -1545,8 +1499,8 @@ function PathLabel({ path, filesystem }) {
1545
1499
  "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[color:var(--accent)]/40"
1546
1500
  ),
1547
1501
  children: [
1548
- /* @__PURE__ */ jsx11("span", { className: "truncate", children: path }),
1549
- /* @__PURE__ */ jsx11(
1502
+ /* @__PURE__ */ jsx9("span", { className: "truncate", children: path }),
1503
+ /* @__PURE__ */ jsx9(
1550
1504
  ExternalLinkIcon,
1551
1505
  {
1552
1506
  className: "h-3 w-3 shrink-0 opacity-0 transition-opacity group-hover/path:opacity-100",
@@ -1561,9 +1515,9 @@ function PathLabel({ path, filesystem }) {
1561
1515
  function renderWorkspaceNotReady(part) {
1562
1516
  const status = getWorkspaceNotReadyStatus(part.output);
1563
1517
  if (!status) return null;
1564
- return /* @__PURE__ */ jsxs10(Tool2, { children: [
1565
- /* @__PURE__ */ jsx11(ToolHeader, { title: `${part.toolName} \xB7 ${status.message}`, ...toHeaderProps(part) }),
1566
- /* @__PURE__ */ jsx11(ToolContent, { children: /* @__PURE__ */ jsxs10("div", { className: "rounded-md border border-border/60 bg-muted/30 px-3 py-2 text-sm text-muted-foreground", children: [
1518
+ return /* @__PURE__ */ jsxs9(Tool2, { children: [
1519
+ /* @__PURE__ */ jsx9(ToolHeader, { title: `${part.toolName} \xB7 ${status.message}`, ...toHeaderProps(part) }),
1520
+ /* @__PURE__ */ jsx9(ToolContent, { children: /* @__PURE__ */ jsxs9("div", { className: "rounded-md border border-border/60 bg-muted/30 px-3 py-2 text-sm text-muted-foreground", children: [
1567
1521
  status.message,
1568
1522
  " Try again in a moment."
1569
1523
  ] }) })
@@ -1573,9 +1527,9 @@ function renderRuntimeNotReady(part) {
1573
1527
  const status = getRuntimeReadinessStatus(part.output);
1574
1528
  if (!status) return null;
1575
1529
  const suffix = status.code === ErrorCode.enum.RUNTIME_PROVISIONING_FAILED ? "Retry or reload the workspace." : "This is retryable; try again shortly.";
1576
- return /* @__PURE__ */ jsxs10(Tool2, { children: [
1577
- /* @__PURE__ */ jsx11(ToolHeader, { title: `${part.toolName} \xB7 ${status.message} ${suffix}`, ...toHeaderProps(part) }),
1578
- /* @__PURE__ */ jsx11(ToolContent, { children: /* @__PURE__ */ jsxs10("div", { className: "rounded-md border border-border/60 bg-muted/30 px-3 py-2 text-sm text-muted-foreground", children: [
1530
+ return /* @__PURE__ */ jsxs9(Tool2, { children: [
1531
+ /* @__PURE__ */ jsx9(ToolHeader, { title: `${part.toolName} \xB7 ${status.message} ${suffix}`, ...toHeaderProps(part) }),
1532
+ /* @__PURE__ */ jsx9(ToolContent, { children: /* @__PURE__ */ jsxs9("div", { className: "rounded-md border border-border/60 bg-muted/30 px-3 py-2 text-sm text-muted-foreground", children: [
1579
1533
  status.message,
1580
1534
  " ",
1581
1535
  suffix
@@ -1586,10 +1540,10 @@ function renderReadinessBlock(part) {
1586
1540
  return renderWorkspaceNotReady(part) ?? renderRuntimeNotReady(part);
1587
1541
  }
1588
1542
  function pathTitle(prefix, path, filesystem) {
1589
- return /* @__PURE__ */ jsxs10("span", { className: "flex min-w-0 items-center gap-1.5", children: [
1590
- /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground", children: prefix }),
1591
- /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground/40", "aria-hidden": "true", children: "\xB7" }),
1592
- /* @__PURE__ */ jsx11(PathLabel, { path, filesystem })
1543
+ return /* @__PURE__ */ jsxs9("span", { className: "flex min-w-0 items-center gap-1.5", children: [
1544
+ /* @__PURE__ */ jsx9("span", { className: "text-muted-foreground", children: prefix }),
1545
+ /* @__PURE__ */ jsx9("span", { className: "text-muted-foreground/40", "aria-hidden": "true", children: "\xB7" }),
1546
+ /* @__PURE__ */ jsx9(PathLabel, { path, filesystem })
1593
1547
  ] });
1594
1548
  }
1595
1549
  function renderBash2(part) {
@@ -1604,21 +1558,21 @@ function renderBash2(part) {
1604
1558
  const exitCode = typeof output.exitCode === "number" ? output.exitCode : null;
1605
1559
  const title = description || (command.length > 64 ? command.slice(0, 64) + "\u2026" : command) || "bash";
1606
1560
  const errorText = part.errorText || (stderr && (exitCode ?? 0) !== 0 ? stderr : void 0);
1607
- return /* @__PURE__ */ jsxs10(Tool2, { children: [
1608
- /* @__PURE__ */ jsx11(ToolHeader, { icon: /* @__PURE__ */ jsx11(SquareTerminalIcon, { className: "size-4 text-muted-foreground" }), title: `bash \xB7 ${title}`, ...toHeaderProps(part) }),
1609
- /* @__PURE__ */ jsxs10(ToolContent, { children: [
1610
- command && /* @__PURE__ */ jsxs10("section", { className: "space-y-2", children: [
1611
- /* @__PURE__ */ jsx11("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: "Command" }),
1612
- /* @__PURE__ */ jsx11(CodeBlock2, { code: command, language: "bash" })
1561
+ return /* @__PURE__ */ jsxs9(Tool2, { children: [
1562
+ /* @__PURE__ */ jsx9(ToolHeader, { icon: /* @__PURE__ */ jsx9(SquareTerminalIcon, { className: "size-4 text-muted-foreground" }), title: `bash \xB7 ${title}`, ...toHeaderProps(part) }),
1563
+ /* @__PURE__ */ jsxs9(ToolContent, { children: [
1564
+ command && /* @__PURE__ */ jsxs9("section", { className: "space-y-2", children: [
1565
+ /* @__PURE__ */ jsx9("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: "Command" }),
1566
+ /* @__PURE__ */ jsx9(CodeBlock2, { code: command, language: "bash" })
1613
1567
  ] }),
1614
- /* @__PURE__ */ jsx11(
1568
+ /* @__PURE__ */ jsx9(
1615
1569
  ToolOutput,
1616
1570
  {
1617
1571
  output: stdout && !errorText ? stdout : void 0,
1618
1572
  errorText
1619
1573
  }
1620
1574
  ),
1621
- exitCode !== null && exitCode !== 0 && !errorText && /* @__PURE__ */ jsxs10("div", { className: "text-xs text-destructive", children: [
1575
+ exitCode !== null && exitCode !== 0 && !errorText && /* @__PURE__ */ jsxs9("div", { className: "text-xs text-destructive", children: [
1622
1576
  "exit ",
1623
1577
  exitCode
1624
1578
  ] })
@@ -1634,13 +1588,13 @@ function renderRead2(part) {
1634
1588
  const filesystem = typeof input.filesystem === "string" ? input.filesystem : void 0;
1635
1589
  const content = extractTextContent(output);
1636
1590
  const lang = langFromPath(path);
1637
- return /* @__PURE__ */ jsxs10(Tool2, { children: [
1638
- /* @__PURE__ */ jsx11(ToolHeader, { icon: /* @__PURE__ */ jsx11(FileTextIcon, { className: "size-4 text-muted-foreground" }), title: pathTitle("read", path, filesystem), ...toHeaderProps(part) }),
1639
- /* @__PURE__ */ jsxs10(ToolContent, { children: [
1640
- /* @__PURE__ */ jsx11(ToolInput, { input }),
1641
- content && /* @__PURE__ */ jsxs10("section", { className: "space-y-2", children: [
1642
- /* @__PURE__ */ jsx11("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: "Content" }),
1643
- /* @__PURE__ */ jsx11(CodeBlock2, { code: content, language: lang ?? "text" })
1591
+ return /* @__PURE__ */ jsxs9(Tool2, { children: [
1592
+ /* @__PURE__ */ jsx9(ToolHeader, { icon: /* @__PURE__ */ jsx9(FileTextIcon, { className: "size-4 text-muted-foreground" }), title: pathTitle("read", path, filesystem), ...toHeaderProps(part) }),
1593
+ /* @__PURE__ */ jsxs9(ToolContent, { children: [
1594
+ /* @__PURE__ */ jsx9(ToolInput, { input }),
1595
+ content && /* @__PURE__ */ jsxs9("section", { className: "space-y-2", children: [
1596
+ /* @__PURE__ */ jsx9("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: "Content" }),
1597
+ /* @__PURE__ */ jsx9(CodeBlock2, { code: content, language: lang ?? "text" })
1644
1598
  ] })
1645
1599
  ] })
1646
1600
  ] });
@@ -1652,20 +1606,20 @@ function renderWrite2(part) {
1652
1606
  const path = typeof input.path === "string" ? input.path : "";
1653
1607
  const filesystem = typeof input.filesystem === "string" ? input.filesystem : void 0;
1654
1608
  const content = typeof input.content === "string" ? input.content : "";
1655
- return /* @__PURE__ */ jsxs10(Tool2, { defaultOpen: part.state === "output-available", children: [
1656
- /* @__PURE__ */ jsx11(ToolHeader, { className: "p-2", icon: /* @__PURE__ */ jsx11(FilePlus2Icon, { className: "size-4 shrink-0 text-muted-foreground" }), title: pathTitle("write", path, filesystem), ...toHeaderProps(part) }),
1657
- /* @__PURE__ */ jsxs10(ToolContent, { className: "p-1.5", children: [
1658
- /* @__PURE__ */ jsx11("div", { className: "max-h-80 overflow-auto overscroll-contain rounded-sm", children: content ? /* @__PURE__ */ jsx11(
1609
+ return /* @__PURE__ */ jsxs9(Tool2, { defaultOpen: part.state === "output-available", children: [
1610
+ /* @__PURE__ */ jsx9(ToolHeader, { className: "p-2", icon: /* @__PURE__ */ jsx9(FilePlus2Icon, { className: "size-4 shrink-0 text-muted-foreground" }), title: pathTitle("write", path, filesystem), ...toHeaderProps(part) }),
1611
+ /* @__PURE__ */ jsxs9(ToolContent, { className: "p-1.5", children: [
1612
+ /* @__PURE__ */ jsx9("div", { className: "max-h-80 overflow-auto overscroll-contain rounded-sm", children: content ? /* @__PURE__ */ jsx9(
1659
1613
  DiffView,
1660
1614
  {
1661
1615
  oldString: "",
1662
1616
  newString: content,
1663
1617
  path,
1664
- actions: /* @__PURE__ */ jsxs10(Fragment3, { children: [
1665
- /* @__PURE__ */ jsx11(ArtifactAction, { className: "size-6", icon: CopyIcon2, tooltip: "Copy contents", label: "Copy", onClick: () => {
1618
+ actions: /* @__PURE__ */ jsxs9(Fragment3, { children: [
1619
+ /* @__PURE__ */ jsx9(ArtifactAction, { className: "size-6", icon: CopyIcon2, tooltip: "Copy contents", label: "Copy", onClick: () => {
1666
1620
  void copyTextToClipboard(content);
1667
1621
  } }),
1668
- /* @__PURE__ */ jsx11(
1622
+ /* @__PURE__ */ jsx9(
1669
1623
  ArtifactAction,
1670
1624
  {
1671
1625
  className: "size-6",
@@ -1687,8 +1641,8 @@ function renderWrite2(part) {
1687
1641
  )
1688
1642
  ] })
1689
1643
  }
1690
- ) : /* @__PURE__ */ jsx11("p", { className: "px-2 py-1 text-[12px] text-muted-foreground", children: "No file content was included with this tool call." }) }),
1691
- part.errorText || part.state === "output-error" || part.state === "output-denied" ? /* @__PURE__ */ jsx11(ToolOutput, { output: part.output, errorText: part.errorText }) : null
1644
+ ) : /* @__PURE__ */ jsx9("p", { className: "px-2 py-1 text-[12px] text-muted-foreground", children: "No file content was included with this tool call." }) }),
1645
+ part.errorText || part.state === "output-error" || part.state === "output-denied" ? /* @__PURE__ */ jsx9(ToolOutput, { output: part.output, errorText: part.errorText }) : null
1692
1646
  ] })
1693
1647
  ] });
1694
1648
  }
@@ -1707,17 +1661,17 @@ function renderEdit2(part) {
1707
1661
  const legacyOldText = typeof input.oldString === "string" ? input.oldString : typeof input.oldText === "string" ? input.oldText : "";
1708
1662
  const legacyNewText = typeof input.newString === "string" ? input.newString : typeof input.newText === "string" ? input.newText : "";
1709
1663
  const visibleEdits = edits.length > 0 ? edits : legacyOldText || legacyNewText ? [{ oldText: legacyOldText, newText: legacyNewText }] : [];
1710
- return /* @__PURE__ */ jsxs10(Tool2, { defaultOpen: part.state === "output-available", children: [
1711
- /* @__PURE__ */ jsx11(ToolHeader, { className: "p-2", icon: /* @__PURE__ */ jsx11(FileDiffIcon, { className: "size-4 shrink-0 text-muted-foreground" }), title: pathTitle("edit", path, filesystem), ...toHeaderProps(part) }),
1712
- /* @__PURE__ */ jsxs10(ToolContent, { className: "space-y-2 p-2", children: [
1713
- /* @__PURE__ */ jsx11("div", { className: "max-h-80 space-y-2 overflow-auto overscroll-contain rounded-sm", children: visibleEdits.length > 0 ? visibleEdits.map((edit, index) => /* @__PURE__ */ jsxs10("div", { children: [
1714
- visibleEdits.length > 1 ? /* @__PURE__ */ jsxs10("div", { className: "mb-1 px-1 text-[11px] text-muted-foreground", children: [
1664
+ return /* @__PURE__ */ jsxs9(Tool2, { defaultOpen: part.state === "output-available", children: [
1665
+ /* @__PURE__ */ jsx9(ToolHeader, { className: "p-2", icon: /* @__PURE__ */ jsx9(FileDiffIcon, { className: "size-4 shrink-0 text-muted-foreground" }), title: pathTitle("edit", path, filesystem), ...toHeaderProps(part) }),
1666
+ /* @__PURE__ */ jsxs9(ToolContent, { className: "space-y-2 p-2", children: [
1667
+ /* @__PURE__ */ jsx9("div", { className: "max-h-80 space-y-2 overflow-auto overscroll-contain rounded-sm", children: visibleEdits.length > 0 ? visibleEdits.map((edit, index) => /* @__PURE__ */ jsxs9("div", { children: [
1668
+ visibleEdits.length > 1 ? /* @__PURE__ */ jsxs9("div", { className: "mb-1 px-1 text-[11px] text-muted-foreground", children: [
1715
1669
  "Change ",
1716
1670
  index + 1
1717
1671
  ] }) : null,
1718
- /* @__PURE__ */ jsx11(DiffView, { oldString: edit.oldText, newString: edit.newText, path })
1719
- ] }, `${index}:${edit.oldText.length}:${edit.newText.length}`)) : /* @__PURE__ */ jsx11("p", { className: "px-2 py-1 text-[12px] text-muted-foreground", children: "Diff details were not included with this tool call." }) }),
1720
- part.errorText || part.state === "output-error" || part.state === "output-denied" ? /* @__PURE__ */ jsx11(ToolOutput, { output: part.output, errorText: part.errorText }) : null
1672
+ /* @__PURE__ */ jsx9(DiffView, { oldString: edit.oldText, newString: edit.newText, path })
1673
+ ] }, `${index}:${edit.oldText.length}:${edit.newText.length}`)) : /* @__PURE__ */ jsx9("p", { className: "px-2 py-1 text-[12px] text-muted-foreground", children: "Diff details were not included with this tool call." }) }),
1674
+ part.errorText || part.state === "output-error" || part.state === "output-denied" ? /* @__PURE__ */ jsx9(ToolOutput, { output: part.output, errorText: part.errorText }) : null
1721
1675
  ] })
1722
1676
  ] });
1723
1677
  }
@@ -1730,18 +1684,18 @@ function renderSearchLike2(toolName, part) {
1730
1684
  const path = typeof input.path === "string" ? input.path : "";
1731
1685
  const glob = typeof input.glob === "string" ? input.glob : "";
1732
1686
  const summary = [pattern, path, glob].filter(Boolean).join(" \xB7 ");
1733
- return /* @__PURE__ */ jsxs10(Tool2, { children: [
1734
- /* @__PURE__ */ jsx11(
1687
+ return /* @__PURE__ */ jsxs9(Tool2, { children: [
1688
+ /* @__PURE__ */ jsx9(
1735
1689
  ToolHeader,
1736
1690
  {
1737
- icon: /* @__PURE__ */ jsx11(SearchLikeIcon, { className: "size-4 text-muted-foreground" }),
1691
+ icon: /* @__PURE__ */ jsx9(SearchLikeIcon, { className: "size-4 text-muted-foreground" }),
1738
1692
  title: summary ? `${toolName} \xB7 ${summary}` : toolName,
1739
1693
  ...toHeaderProps(part)
1740
1694
  }
1741
1695
  ),
1742
- /* @__PURE__ */ jsxs10(ToolContent, { children: [
1743
- /* @__PURE__ */ jsx11(ToolInput, { input }),
1744
- /* @__PURE__ */ jsx11(ToolOutput, { output: part.output, errorText: part.errorText })
1696
+ /* @__PURE__ */ jsxs9(ToolContent, { children: [
1697
+ /* @__PURE__ */ jsx9(ToolInput, { input }),
1698
+ /* @__PURE__ */ jsx9(ToolOutput, { output: part.output, errorText: part.errorText })
1745
1699
  ] })
1746
1700
  ] });
1747
1701
  }
@@ -1766,8 +1720,8 @@ function renderExecUi2(part) {
1766
1720
  const kind = typeof input.kind === "string" ? input.kind : "(empty)";
1767
1721
  const tokens = extractParamTokens(input.params);
1768
1722
  const headerProps = toHeaderProps(part);
1769
- return /* @__PURE__ */ jsxs10(Tool2, { children: [
1770
- /* @__PURE__ */ jsxs10(
1723
+ return /* @__PURE__ */ jsxs9(Tool2, { children: [
1724
+ /* @__PURE__ */ jsxs9(
1771
1725
  CollapsibleTrigger2,
1772
1726
  {
1773
1727
  className: cn(
@@ -1775,17 +1729,17 @@ function renderExecUi2(part) {
1775
1729
  "hover:bg-muted/40 transition-colors"
1776
1730
  ),
1777
1731
  children: [
1778
- /* @__PURE__ */ jsx11(
1732
+ /* @__PURE__ */ jsx9(
1779
1733
  ZapIcon,
1780
1734
  {
1781
1735
  className: "size-3.5 shrink-0 text-muted-foreground/70",
1782
1736
  "aria-hidden": "true"
1783
1737
  }
1784
1738
  ),
1785
- /* @__PURE__ */ jsx11("span", { className: "font-medium text-sm", children: kind }),
1786
- tokens.length > 0 && /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 items-center gap-1.5 overflow-hidden", children: [
1787
- /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground/40", "aria-hidden": "true", children: "\xB7" }),
1788
- tokens.map((tok, i) => /* @__PURE__ */ jsx11(
1739
+ /* @__PURE__ */ jsx9("span", { className: "font-medium text-sm", children: kind }),
1740
+ tokens.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "flex min-w-0 items-center gap-1.5 overflow-hidden", children: [
1741
+ /* @__PURE__ */ jsx9("span", { className: "text-muted-foreground/40", "aria-hidden": "true", children: "\xB7" }),
1742
+ tokens.map((tok, i) => /* @__PURE__ */ jsx9(
1789
1743
  "span",
1790
1744
  {
1791
1745
  className: cn(
@@ -1798,9 +1752,9 @@ function renderExecUi2(part) {
1798
1752
  i
1799
1753
  ))
1800
1754
  ] }),
1801
- /* @__PURE__ */ jsxs10("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
1755
+ /* @__PURE__ */ jsxs9("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
1802
1756
  getStatusBadge(headerProps.state),
1803
- /* @__PURE__ */ jsx11(
1757
+ /* @__PURE__ */ jsx9(
1804
1758
  ChevronDownIcon2,
1805
1759
  {
1806
1760
  className: "size-4 text-muted-foreground/60 transition-transform group-data-[state=open]/exec-ui:rotate-180",
@@ -1811,9 +1765,9 @@ function renderExecUi2(part) {
1811
1765
  ]
1812
1766
  }
1813
1767
  ),
1814
- /* @__PURE__ */ jsxs10(ToolContent, { children: [
1815
- part.input !== void 0 && part.input !== null && /* @__PURE__ */ jsx11(ToolInput, { input: part.input }),
1816
- /* @__PURE__ */ jsx11(ToolOutput, { output: part.output, errorText: part.errorText })
1768
+ /* @__PURE__ */ jsxs9(ToolContent, { children: [
1769
+ part.input !== void 0 && part.input !== null && /* @__PURE__ */ jsx9(ToolInput, { input: part.input }),
1770
+ /* @__PURE__ */ jsx9(ToolOutput, { output: part.output, errorText: part.errorText })
1817
1771
  ] })
1818
1772
  ] });
1819
1773
  }
@@ -1825,11 +1779,11 @@ function fallbackTitle(part) {
1825
1779
  function renderFallback2(part) {
1826
1780
  const readiness = renderReadinessBlock(part);
1827
1781
  if (readiness) return readiness;
1828
- return /* @__PURE__ */ jsxs10(Tool2, { children: [
1829
- /* @__PURE__ */ jsx11(ToolHeader, { title: fallbackTitle(part), ...toHeaderProps(part) }),
1830
- /* @__PURE__ */ jsxs10(ToolContent, { children: [
1831
- part.input !== void 0 && part.input !== null && /* @__PURE__ */ jsx11(ToolInput, { input: part.input }),
1832
- /* @__PURE__ */ jsx11(ToolOutput, { output: part.output, errorText: part.errorText })
1782
+ return /* @__PURE__ */ jsxs9(Tool2, { children: [
1783
+ /* @__PURE__ */ jsx9(ToolHeader, { title: fallbackTitle(part), ...toHeaderProps(part) }),
1784
+ /* @__PURE__ */ jsxs9(ToolContent, { children: [
1785
+ part.input !== void 0 && part.input !== null && /* @__PURE__ */ jsx9(ToolInput, { input: part.input }),
1786
+ /* @__PURE__ */ jsx9(ToolOutput, { output: part.output, errorText: part.errorText })
1833
1787
  ] })
1834
1788
  ] });
1835
1789
  }
@@ -1993,7 +1947,7 @@ function usePickerKeyboard({
1993
1947
  }
1994
1948
 
1995
1949
  // src/front/primitives/mention-picker.tsx
1996
- import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1950
+ import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1997
1951
  var mentionSearchGlob = toFileSearchGlob;
1998
1952
  function highlight(text, query) {
1999
1953
  if (!query) return null;
@@ -2040,10 +1994,10 @@ function MentionPicker({
2040
1994
  }, [results, onSelect]);
2041
1995
  usePickerKeyboard({ count: results.length, activeIdx, setActiveIdx, listRef, onSelect: handleSelect, onDismiss });
2042
1996
  if (results.length === 0) return null;
2043
- return /* @__PURE__ */ jsx12("div", { className: "mb-1 w-full overflow-hidden rounded-lg border border-border/60 bg-popover shadow-lg", children: /* @__PURE__ */ jsx12("ul", { ref: listRef, className: "max-h-48 overflow-y-auto py-1", role: "listbox", "aria-label": "File suggestions", children: results.map((path, i) => {
1997
+ return /* @__PURE__ */ jsx10("div", { className: "mb-1 w-full overflow-hidden rounded-lg border border-border/60 bg-popover shadow-lg", children: /* @__PURE__ */ jsx10("ul", { ref: listRef, className: "max-h-48 overflow-y-auto py-1", role: "listbox", "aria-label": "File suggestions", children: results.map((path, i) => {
2044
1998
  const name = path.split("/").pop() ?? path;
2045
1999
  const hl = highlight(name, mention.query);
2046
- return /* @__PURE__ */ jsxs11(
2000
+ return /* @__PURE__ */ jsxs10(
2047
2001
  "li",
2048
2002
  {
2049
2003
  role: "option",
@@ -2058,12 +2012,12 @@ function MentionPicker({
2058
2012
  onSelect(path);
2059
2013
  },
2060
2014
  children: [
2061
- /* @__PURE__ */ jsx12("span", { className: "font-medium", children: hl ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
2015
+ /* @__PURE__ */ jsx10("span", { className: "font-medium", children: hl ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
2062
2016
  hl.before,
2063
- /* @__PURE__ */ jsx12("mark", { className: "bg-transparent text-[color:var(--accent)]", children: hl.match }),
2017
+ /* @__PURE__ */ jsx10("mark", { className: "bg-transparent text-[color:var(--accent)]", children: hl.match }),
2064
2018
  hl.after
2065
2019
  ] }) : name }),
2066
- /* @__PURE__ */ jsx12("span", { className: "truncate text-[11px] opacity-50", children: path })
2020
+ /* @__PURE__ */ jsx10("span", { className: "truncate text-[11px] opacity-50", children: path })
2067
2021
  ]
2068
2022
  },
2069
2023
  path
@@ -2172,7 +2126,7 @@ function useComposerPickers({
2172
2126
  }
2173
2127
 
2174
2128
  // src/front/hooks/useChatModelSelection.ts
2175
- import { useCallback as useCallback6, useEffect as useEffect5, useMemo as useMemo2, useRef as useRef6, useState as useState7 } from "react";
2129
+ import { useCallback as useCallback6, useEffect as useEffect5, useMemo as useMemo2, useState as useState7 } from "react";
2176
2130
 
2177
2131
  // src/front/browserFiles.ts
2178
2132
  var convertBlobUrlToDataUrl = async (url) => {
@@ -2596,35 +2550,59 @@ function resolveStorage(storage) {
2596
2550
  }
2597
2551
 
2598
2552
  // src/front/hooks/useChatModelSelection.ts
2553
+ function sameModel(left, right) {
2554
+ return left?.provider === right?.provider && left?.id === right?.id;
2555
+ }
2556
+ function availableModel(models, model) {
2557
+ return Boolean(model && models.some((candidate) => candidate.available && candidate.provider === model.provider && candidate.id === model.id));
2558
+ }
2599
2559
  function useChatModelSelection({
2600
2560
  agentTypeId,
2601
2561
  apiBaseUrl,
2602
2562
  defaultModel,
2563
+ sessionId,
2564
+ sessionHydrated = sessionId === void 0,
2565
+ sessionIsNew = sessionId === void 0,
2566
+ sessionModel,
2603
2567
  fetch: fetchImpl,
2604
2568
  requestHeaders,
2605
2569
  storage,
2606
2570
  storageScope,
2607
2571
  enabled = true
2608
2572
  }) {
2609
- const initialModelState = useMemo2(() => readPiComposerSettings({ storageScope, storage }), []);
2610
- const [model, setModelState] = useState7(
2611
- () => initialModelState.model ?? defaultModel ?? null
2612
- );
2613
- const [userSelectedModel, setUserSelectedModel] = useState7(
2614
- () => initialModelState.userSelectedModel
2615
- );
2616
- const userSelectedModelRef = useRef6(userSelectedModel);
2617
- const loadedSettingsSourceRef = useRef6({ storage, storageScope });
2573
+ const initialSettings = useMemo2(() => readPiComposerSettings({ storageScope, storage }), []);
2574
+ const [selection, setSelection] = useState7(() => ({
2575
+ sessionId,
2576
+ storage,
2577
+ storageScope,
2578
+ localDefault: initialSettings.model ?? defaultModel ?? null
2579
+ }));
2618
2580
  useEffect5(() => {
2619
- userSelectedModelRef.current = userSelectedModel;
2620
- }, [userSelectedModel]);
2581
+ const settings = readPiComposerSettings({ storageScope, storage });
2582
+ setSelection((current) => {
2583
+ const sameSession = current.sessionId === sessionId;
2584
+ const pendingOverride2 = sameSession && current.pendingOverride && sessionModel && !sameModel(current.pendingOverride, sessionModel) ? current.pendingOverride : sessionIsNew && sessionModel && settings.model && !sameModel(settings.model, sessionModel) ? settings.model : void 0;
2585
+ return {
2586
+ sessionId,
2587
+ storage,
2588
+ storageScope,
2589
+ localDefault: settings.model ?? defaultModel ?? null,
2590
+ ...pendingOverride2 ? { pendingOverride: pendingOverride2 } : {}
2591
+ };
2592
+ });
2593
+ }, [defaultModel, sessionId, sessionIsNew, sessionModel?.id, sessionModel?.provider, storage, storageScope]);
2621
2594
  const setModel = useCallback6((next) => {
2622
2595
  const normalized = next === null ? null : parseModelSelection(next);
2623
- userSelectedModelRef.current = normalized !== null;
2624
- setUserSelectedModel(normalized !== null);
2625
- setModelState(normalized);
2596
+ setSelection((current) => {
2597
+ if (sessionModel) {
2598
+ const pendingOverride2 = normalized && !sameModel(normalized, sessionModel) ? normalized : void 0;
2599
+ return { ...current, sessionId, ...pendingOverride2 ? { pendingOverride: pendingOverride2 } : { pendingOverride: void 0 } };
2600
+ }
2601
+ if (sessionId && !sessionIsNew) return current;
2602
+ return { ...current, sessionId, localDefault: normalized, pendingOverride: void 0 };
2603
+ });
2626
2604
  writePiComposerModelSelection(normalized, { storageScope, storage });
2627
- }, [storage, storageScope]);
2605
+ }, [sessionId, sessionIsNew, sessionModel, storage, storageScope]);
2628
2606
  const discoveryKey = useMemo2(
2629
2607
  () => JSON.stringify({
2630
2608
  apiBaseUrl: apiBaseUrl ?? "",
@@ -2637,22 +2615,6 @@ function useChatModelSelection({
2637
2615
  const [availableModels, setAvailableModels] = useState7([]);
2638
2616
  const [loaded, setLoaded] = useState7(!enabled);
2639
2617
  const [loadedDiscoveryKey, setLoadedDiscoveryKey] = useState7(enabled ? null : discoveryKey);
2640
- useEffect5(() => {
2641
- if (loadedSettingsSourceRef.current.storage !== storage || loadedSettingsSourceRef.current.storageScope !== storageScope) return;
2642
- if (!userSelectedModel || !model) return;
2643
- writePiComposerModelSelection(model, { storageScope, storage });
2644
- }, [model, storage, storageScope, userSelectedModel]);
2645
- useEffect5(() => {
2646
- const settings = readPiComposerSettings({ storageScope, storage });
2647
- loadedSettingsSourceRef.current = { storage, storageScope };
2648
- userSelectedModelRef.current = settings.userSelectedModel;
2649
- setUserSelectedModel(settings.userSelectedModel);
2650
- setModelState(settings.model ?? defaultModel ?? null);
2651
- }, [storage, storageScope]);
2652
- useEffect5(() => {
2653
- if (userSelectedModelRef.current || !defaultModel) return;
2654
- setModelState(defaultModel);
2655
- }, [defaultModel]);
2656
2618
  useEffect5(() => {
2657
2619
  if (!enabled) {
2658
2620
  setLoaded(true);
@@ -2664,46 +2626,44 @@ function useChatModelSelection({
2664
2626
  const nextFetch = fetchImpl ?? globalThis.fetch.bind(globalThis);
2665
2627
  nextFetch(agentResourceUrl(apiBaseUrl, `/api/v1/agents/${encodeURIComponent(agentTypeId)}/models`), {
2666
2628
  headers: withStorageScope(requestHeaders, storageScope)
2667
- }).then((res) => res.ok ? res.json() : null).then((payload) => {
2629
+ }).then((response) => response.ok ? response.json() : null).then((payload) => {
2668
2630
  if (aborted) return;
2669
- if (!payload?.models) {
2670
- userSelectedModelRef.current = false;
2671
- setUserSelectedModel(false);
2631
+ const models = payload?.models;
2632
+ if (!models) {
2672
2633
  setAvailableModels([]);
2673
- setModelState(null);
2674
- writePiComposerModelSelection(null, { storageScope, storage });
2634
+ setSelection((current) => ({ ...current, pendingOverride: void 0, localDefault: sessionModel ?? null }));
2635
+ if (!sessionModel) writePiComposerModelSelection(null, { storageScope, storage });
2675
2636
  setLoadedDiscoveryKey(discoveryKey);
2676
2637
  setLoaded(true);
2677
2638
  return;
2678
2639
  }
2679
- setAvailableModels(payload.models);
2640
+ setAvailableModels(models);
2641
+ setSelection((current) => {
2642
+ const selected = current.pendingOverride ?? sessionModel ?? current.localDefault;
2643
+ if (availableModel(models, selected)) return current;
2644
+ if (sessionModel) return { ...current, pendingOverride: void 0 };
2645
+ if (sessionId && !sessionIsNew) return { ...current, pendingOverride: void 0, localDefault: null };
2646
+ const firstAvailable = models.find((candidate) => candidate.available);
2647
+ return {
2648
+ ...current,
2649
+ pendingOverride: void 0,
2650
+ localDefault: payload.defaultModel ?? (firstAvailable ? { provider: firstAvailable.provider, id: firstAvailable.id } : null)
2651
+ };
2652
+ });
2680
2653
  setLoadedDiscoveryKey(discoveryKey);
2681
2654
  setLoaded(true);
2682
- const available = payload.models.filter((m) => m.available);
2683
- setModelState((current) => {
2684
- const currentAvailable = current ? available.some((m) => m.provider === current.provider && m.id === current.id) : false;
2685
- if (currentAvailable) return current;
2686
- userSelectedModelRef.current = false;
2687
- setUserSelectedModel(false);
2688
- writePiComposerModelSelection(null, { storageScope, storage });
2689
- if (payload.defaultModel) return { provider: payload.defaultModel.provider, id: payload.defaultModel.id };
2690
- const firstAvailable = available[0];
2691
- return firstAvailable ? { provider: firstAvailable.provider, id: firstAvailable.id } : null;
2692
- });
2693
2655
  }).catch(() => {
2694
2656
  if (aborted) return;
2695
- userSelectedModelRef.current = false;
2696
- setUserSelectedModel(false);
2697
2657
  setAvailableModels([]);
2698
- setModelState(null);
2699
- writePiComposerModelSelection(null, { storageScope, storage });
2658
+ setSelection((current) => ({ ...current, pendingOverride: void 0, localDefault: sessionModel ?? null }));
2659
+ if (!sessionModel) writePiComposerModelSelection(null, { storageScope, storage });
2700
2660
  setLoadedDiscoveryKey(discoveryKey);
2701
2661
  setLoaded(true);
2702
2662
  });
2703
2663
  return () => {
2704
2664
  aborted = true;
2705
2665
  };
2706
- }, [agentTypeId, apiBaseUrl, discoveryKey, enabled, fetchImpl, requestHeaders, storage, storageScope]);
2666
+ }, [agentTypeId, apiBaseUrl, discoveryKey, enabled, fetchImpl, requestHeaders, sessionId, sessionIsNew, sessionModel, storage, storageScope]);
2707
2667
  useEffect5(() => {
2708
2668
  const onChange = (event) => {
2709
2669
  const next = parseModelSelection(event.detail);
@@ -2713,13 +2673,23 @@ function useChatModelSelection({
2713
2673
  return () => globalThis.removeEventListener?.("boring:model-change", onChange);
2714
2674
  }, [setModel]);
2715
2675
  const currentDiscoveryLoaded = !enabled || loaded && loadedDiscoveryKey === discoveryKey;
2716
- const currentAvailableModels = currentDiscoveryLoaded ? availableModels : [];
2717
- const currentModel = currentDiscoveryLoaded ? model : null;
2718
- return { availableModels: currentAvailableModels, loaded: currentDiscoveryLoaded, model: currentModel, setModel };
2676
+ const selectionBelongsToSession = selection.sessionId === sessionId && selection.storage === storage && selection.storageScope === storageScope;
2677
+ const pendingOverride = selectionBelongsToSession ? selection.pendingOverride : void 0;
2678
+ const isOverride = Boolean(pendingOverride && sessionModel && !sameModel(pendingOverride, sessionModel));
2679
+ const sessionAuthorityReady = !sessionId || sessionHydrated && (sessionModel !== void 0 || sessionIsNew);
2680
+ const model = currentDiscoveryLoaded && sessionAuthorityReady ? pendingOverride ?? sessionModel ?? selection.localDefault : null;
2681
+ return {
2682
+ availableModels: currentDiscoveryLoaded ? availableModels : [],
2683
+ loaded: currentDiscoveryLoaded,
2684
+ model,
2685
+ sessionModel,
2686
+ isOverride,
2687
+ setModel
2688
+ };
2719
2689
  }
2720
2690
 
2721
2691
  // src/front/hooks/useServerCommands.ts
2722
- import { useEffect as useEffect6, useRef as useRef7, useState as useState8 } from "react";
2692
+ import { useEffect as useEffect6, useRef as useRef6, useState as useState8 } from "react";
2723
2693
  function serverCommandErrorMessage(body, fallback) {
2724
2694
  if (typeof body.error === "string") return body.error;
2725
2695
  if (body.error && typeof body.error === "object" && typeof body.error.message === "string") return body.error.message;
@@ -2771,10 +2741,10 @@ function useServerCommands({
2771
2741
  refreshKey = 0
2772
2742
  }) {
2773
2743
  const [stamp, setStamp] = useState8(0);
2774
- const registrationsRef = useRef7({ registry, identity: void 0, names: /* @__PURE__ */ new Set() });
2744
+ const registrationsRef = useRef6({ registry, identity: void 0, names: /* @__PURE__ */ new Set() });
2775
2745
  const canonicalSessionId = sessionId.trim() || void 0;
2776
2746
  const identityKey = canonicalSessionId ? `${agentTypeId}\0${canonicalSessionId}` : void 0;
2777
- const identityKeyRef = useRef7(identityKey);
2747
+ const identityKeyRef = useRef6(identityKey);
2778
2748
  identityKeyRef.current = identityKey;
2779
2749
  useEffect6(() => () => {
2780
2750
  const registrations = registrationsRef.current;
@@ -2880,22 +2850,22 @@ function composerNoticeForRuntimeDependencies(status) {
2880
2850
  }
2881
2851
 
2882
2852
  // src/front/chat/composerContributions.tsx
2883
- import { createContext as createContext3, useContext as useContext3, useMemo as useMemo3 } from "react";
2884
- import { jsx as jsx13 } from "react/jsx-runtime";
2885
- var ComposerContributionContext = createContext3([]);
2853
+ import { createContext as createContext2, useContext as useContext2, useMemo as useMemo3 } from "react";
2854
+ import { jsx as jsx11 } from "react/jsx-runtime";
2855
+ var ComposerContributionContext = createContext2([]);
2886
2856
  function ComposerContributionProvider({
2887
2857
  contribution,
2888
2858
  children
2889
2859
  }) {
2890
- const parent = useContext3(ComposerContributionContext);
2860
+ const parent = useContext2(ComposerContributionContext);
2891
2861
  const contributions = useMemo3(
2892
2862
  () => [contribution, ...parent.filter((entry) => entry.id !== contribution.id)],
2893
2863
  [contribution, parent]
2894
2864
  );
2895
- return /* @__PURE__ */ jsx13(ComposerContributionContext.Provider, { value: contributions, children });
2865
+ return /* @__PURE__ */ jsx11(ComposerContributionContext.Provider, { value: contributions, children });
2896
2866
  }
2897
2867
  function useComposerContributions() {
2898
- return useContext3(ComposerContributionContext);
2868
+ return useContext2(ComposerContributionContext);
2899
2869
  }
2900
2870
 
2901
2871
  // src/front/chat/pi/piChatMessageMetadata.ts
@@ -3806,6 +3776,8 @@ function piChatReducer(state, action) {
3806
3776
  return hydrateFromSnapshot(state, action.snapshot, { allowSeqRewind: action.allowSeqRewind });
3807
3777
  case "cursor-sync":
3808
3778
  return syncCursor(state, action.cursor);
3779
+ case "model-confirmed":
3780
+ return { ...state, currentModel: action.model };
3809
3781
  case "event":
3810
3782
  return applySequencedEvent(state, action.event);
3811
3783
  case "optimistic-user-message":
@@ -3902,6 +3874,7 @@ function hydrateFromSnapshot(state, snapshot, options = {}) {
3902
3874
  ...state,
3903
3875
  sessionId: snapshot.sessionId,
3904
3876
  status: snapshot.status,
3877
+ currentModel: snapshot.currentModel,
3905
3878
  turnId: snapshot.activeTurnId,
3906
3879
  lastSeq: snapshot.seq,
3907
3880
  committedMessages,
@@ -3952,6 +3925,8 @@ function applySequencedEvent(state, event) {
3952
3925
  }
3953
3926
  function reduceEvent(state, event) {
3954
3927
  switch (event.type) {
3928
+ case "model-changed":
3929
+ return { ...state, currentModel: event.currentModel };
3955
3930
  case "agent-start":
3956
3931
  return { ...state, status: "streaming", turnId: event.turnId, error: void 0, streamingPreservedTextPartKeys: void 0 };
3957
3932
  case "agent-end":
@@ -4684,6 +4659,9 @@ var RemotePiSession = class {
4684
4659
  else if (!this.suspended) this.ensureReconnectScheduled();
4685
4660
  try {
4686
4661
  const receipt = await this.postCommand("/prompt", payload, PromptReceiptSchema);
4662
+ if (!this.disposed && payload.model) {
4663
+ this.store.dispatch({ type: "model-confirmed", model: payload.model }, { flush: true });
4664
+ }
4687
4665
  return receipt;
4688
4666
  } catch (error) {
4689
4667
  this.rollbackOptimisticMessage(payload.clientNonce);
@@ -5258,7 +5236,7 @@ function resolveBootStorage(storage) {
5258
5236
  }
5259
5237
 
5260
5238
  // src/front/chat/session/usePiSessions.ts
5261
- import { useCallback as useCallback7, useEffect as useEffect8, useLayoutEffect, useMemo as useMemo4, useRef as useRef8, useState as useState10 } from "react";
5239
+ import { useCallback as useCallback7, useEffect as useEffect8, useLayoutEffect, useMemo as useMemo4, useRef as useRef7, useState as useState10 } from "react";
5262
5240
  var SESSION_PAGE_SIZE = 50;
5263
5241
  var DEFAULT_MAX_RETRIES = 60;
5264
5242
  var DEFAULT_RETRY_BASE_MS = 250;
@@ -5321,22 +5299,22 @@ function usePiSessions(options) {
5321
5299
  const [loadingMore, setLoadingMore] = useState10(false);
5322
5300
  const [hasMore, setHasMore] = useState10(false);
5323
5301
  const [error, setError] = useState10(void 0);
5324
- const mountedRef = useRef8(false);
5325
- const refreshVersionRef = useRef8(0);
5326
- const retryTimerRef = useRef8(void 0);
5327
- const sessionsRef = useRef8([]);
5328
- const activeSessionIdRef = useRef8(activeSessionId);
5329
- const hasMoreRef = useRef8(hasMore);
5330
- const canonicalLoadedCountRef = useRef8(0);
5331
- const nextCursorRef = useRef8(void 0);
5332
- const loadMoreRequestSeqRef = useRef8(0);
5333
- const loadMoreInFlightRef = useRef8(false);
5334
- const pendingCreatedRef = useRef8(/* @__PURE__ */ new Map());
5335
- const pendingDeletedRef = useRef8(/* @__PURE__ */ new Set());
5336
- const pendingCreatedScopeRef = useRef8(requestScopeKey);
5337
- const dataStorageScopeRef = useRef8(storageScope);
5338
- const loadedDataSourceRef = useRef8(dataSourceKey);
5339
- const committedRequestScopeRef = useRef8(requestScopeKey);
5302
+ const mountedRef = useRef7(false);
5303
+ const refreshVersionRef = useRef7(0);
5304
+ const retryTimerRef = useRef7(void 0);
5305
+ const sessionsRef = useRef7([]);
5306
+ const activeSessionIdRef = useRef7(activeSessionId);
5307
+ const hasMoreRef = useRef7(hasMore);
5308
+ const canonicalLoadedCountRef = useRef7(0);
5309
+ const nextCursorRef = useRef7(void 0);
5310
+ const loadMoreRequestSeqRef = useRef7(0);
5311
+ const loadMoreInFlightRef = useRef7(false);
5312
+ const pendingCreatedRef = useRef7(/* @__PURE__ */ new Map());
5313
+ const pendingDeletedRef = useRef7(/* @__PURE__ */ new Set());
5314
+ const pendingCreatedScopeRef = useRef7(requestScopeKey);
5315
+ const dataStorageScopeRef = useRef7(storageScope);
5316
+ const loadedDataSourceRef = useRef7(dataSourceKey);
5317
+ const committedRequestScopeRef = useRef7(requestScopeKey);
5340
5318
  useIsomorphicLayoutEffect(() => {
5341
5319
  committedRequestScopeRef.current = requestScopeKey;
5342
5320
  }, [requestScopeKey]);
@@ -5344,7 +5322,7 @@ function usePiSessions(options) {
5344
5322
  (scope) => mountedRef.current && committedRequestScopeRef.current === scope,
5345
5323
  []
5346
5324
  );
5347
- const remoteSessionOptionsRef = useRef8(options.remoteSessionOptions);
5325
+ const remoteSessionOptionsRef = useRef7(options.remoteSessionOptions);
5348
5326
  remoteSessionOptionsRef.current = options.remoteSessionOptions;
5349
5327
  const remoteSessionOptionsKey = useMemo4(
5350
5328
  () => remoteSessionOptionsIdentity(options.remoteSessionOptions),
@@ -5845,7 +5823,7 @@ function clearRetryTimer(ref) {
5845
5823
  import { useMemo as useMemo5 } from "react";
5846
5824
  import { ChevronLeftIcon, PlusIcon, Trash2Icon } from "lucide-react";
5847
5825
  import { IconButton } from "@hachej/boring-ui-kit";
5848
- import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
5826
+ import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
5849
5827
  var DAY_MS = 24 * 60 * 60 * 1e3;
5850
5828
  function SessionList({
5851
5829
  sessions,
@@ -5861,7 +5839,7 @@ function SessionList({
5861
5839
  className
5862
5840
  }) {
5863
5841
  const groups = useMemo5(() => groupSessions(sessions), [sessions]);
5864
- return /* @__PURE__ */ jsxs12(
5842
+ return /* @__PURE__ */ jsxs11(
5865
5843
  "div",
5866
5844
  {
5867
5845
  "data-boring-agent-part": "session-list",
@@ -5870,27 +5848,27 @@ function SessionList({
5870
5848
  "aria-label": "Session history",
5871
5849
  "aria-busy": loading ? "true" : void 0,
5872
5850
  children: [
5873
- /* @__PURE__ */ jsxs12("div", { className: "flex h-11 items-center justify-between border-b border-border/60 px-3.5", children: [
5874
- /* @__PURE__ */ jsx14("span", { className: "text-[12px] font-medium tracking-tight text-foreground/70", children: "Sessions" }),
5875
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-0.5", children: [
5876
- onCreate ? /* @__PURE__ */ jsx14(IconButton, { type: "button", variant: "ghost", size: "icon-xs", onClick: onCreate, "aria-label": "New session", title: "New chat", children: /* @__PURE__ */ jsx14(PlusIcon, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }) }) : null,
5877
- onClose ? /* @__PURE__ */ jsx14(IconButton, { type: "button", variant: "ghost", size: "icon-xs", onClick: onClose, "aria-label": "Close sessions", title: "Close sessions", children: /* @__PURE__ */ jsx14(ChevronLeftIcon, { className: "h-4 w-4", strokeWidth: 1.75 }) }) : null
5851
+ /* @__PURE__ */ jsxs11("div", { className: "flex h-11 items-center justify-between border-b border-border/60 px-3.5", children: [
5852
+ /* @__PURE__ */ jsx12("span", { className: "text-[12px] font-medium tracking-tight text-foreground/70", children: "Sessions" }),
5853
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-0.5", children: [
5854
+ onCreate ? /* @__PURE__ */ jsx12(IconButton, { type: "button", variant: "ghost", size: "icon-xs", onClick: onCreate, "aria-label": "New session", title: "New chat", children: /* @__PURE__ */ jsx12(PlusIcon, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }) }) : null,
5855
+ onClose ? /* @__PURE__ */ jsx12(IconButton, { type: "button", variant: "ghost", size: "icon-xs", onClick: onClose, "aria-label": "Close sessions", title: "Close sessions", children: /* @__PURE__ */ jsx12(ChevronLeftIcon, { className: "h-4 w-4", strokeWidth: 1.75 }) }) : null
5878
5856
  ] })
5879
5857
  ] }),
5880
- /* @__PURE__ */ jsxs12("div", { className: "flex-1 overflow-y-auto py-2.5", children: [
5881
- sessions.length === 0 ? /* @__PURE__ */ jsxs12("div", { "data-boring-agent-part": "session-list-empty", className: "px-3 py-8 text-center text-[13px] text-muted-foreground", children: [
5858
+ /* @__PURE__ */ jsxs11("div", { className: "flex-1 overflow-y-auto py-2.5", children: [
5859
+ sessions.length === 0 ? /* @__PURE__ */ jsxs11("div", { "data-boring-agent-part": "session-list-empty", className: "px-3 py-8 text-center text-[13px] text-muted-foreground", children: [
5882
5860
  loading ? "Loading sessions\u2026" : "No sessions yet.",
5883
- !loading ? /* @__PURE__ */ jsxs12(Fragment5, { children: [
5884
- /* @__PURE__ */ jsx14("br", {}),
5861
+ !loading ? /* @__PURE__ */ jsxs11(Fragment5, { children: [
5862
+ /* @__PURE__ */ jsx12("br", {}),
5885
5863
  "Start a new chat to begin."
5886
5864
  ] }) : null
5887
5865
  ] }) : null,
5888
- groups.map((group, index) => /* @__PURE__ */ jsxs12("section", { className: cn(index > 0 && "mt-4"), children: [
5889
- /* @__PURE__ */ jsxs12("div", { className: "flex items-baseline justify-between gap-2 px-3.5 pb-2 pt-2 text-[11px] font-medium tracking-tight text-muted-foreground/75", children: [
5890
- /* @__PURE__ */ jsx14("span", { children: group.label }),
5891
- /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", className: "text-[10.5px] tabular-nums text-muted-foreground/40", children: group.items.length })
5866
+ groups.map((group, index) => /* @__PURE__ */ jsxs11("section", { className: cn(index > 0 && "mt-4"), children: [
5867
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-baseline justify-between gap-2 px-3.5 pb-2 pt-2 text-[11px] font-medium tracking-tight text-muted-foreground/75", children: [
5868
+ /* @__PURE__ */ jsx12("span", { children: group.label }),
5869
+ /* @__PURE__ */ jsx12("span", { "aria-hidden": "true", className: "text-[10.5px] tabular-nums text-muted-foreground/40", children: group.items.length })
5892
5870
  ] }),
5893
- /* @__PURE__ */ jsx14("ul", { role: "list", className: "flex flex-col", children: group.items.map((session) => /* @__PURE__ */ jsx14(
5871
+ /* @__PURE__ */ jsx12("ul", { role: "list", className: "flex flex-col", children: group.items.map((session) => /* @__PURE__ */ jsx12(
5894
5872
  SessionRow,
5895
5873
  {
5896
5874
  session,
@@ -5901,7 +5879,7 @@ function SessionList({
5901
5879
  session.id
5902
5880
  )) })
5903
5881
  ] }, group.key)),
5904
- hasMore && onLoadMore ? /* @__PURE__ */ jsx14("div", { className: "px-3 py-3", children: /* @__PURE__ */ jsx14(
5882
+ hasMore && onLoadMore ? /* @__PURE__ */ jsx12("div", { className: "px-3 py-3", children: /* @__PURE__ */ jsx12(
5905
5883
  "button",
5906
5884
  {
5907
5885
  type: "button",
@@ -5919,7 +5897,7 @@ function SessionList({
5919
5897
  var SessionBrowser = SessionList;
5920
5898
  function SessionRow({ session, active, onSwitch, onDelete }) {
5921
5899
  const time = relativeTime(session.updatedAt);
5922
- return /* @__PURE__ */ jsxs12(
5900
+ return /* @__PURE__ */ jsxs11(
5923
5901
  "li",
5924
5902
  {
5925
5903
  role: "listitem",
@@ -5932,11 +5910,11 @@ function SessionRow({ session, active, onSwitch, onDelete }) {
5932
5910
  ),
5933
5911
  onClick: () => onSwitch?.(session.id),
5934
5912
  children: [
5935
- /* @__PURE__ */ jsxs12("span", { className: "min-w-0 flex-1 truncate leading-5", title: session.title, children: [
5936
- /* @__PURE__ */ jsx14("span", { className: cn(active ? "font-medium text-foreground" : "text-foreground/90"), children: session.title || "Untitled" }),
5937
- time ? /* @__PURE__ */ jsx14("span", { className: cn("ml-1.5 tabular-nums text-[11px]", active ? "text-[color:var(--accent)]" : "text-muted-foreground/60"), children: time }) : null
5913
+ /* @__PURE__ */ jsxs11("span", { className: "min-w-0 flex-1 truncate leading-5", title: session.title, children: [
5914
+ /* @__PURE__ */ jsx12("span", { className: cn(active ? "font-medium text-foreground" : "text-foreground/90"), children: session.title || "Untitled" }),
5915
+ time ? /* @__PURE__ */ jsx12("span", { className: cn("ml-1.5 tabular-nums text-[11px]", active ? "text-[color:var(--accent)]" : "text-muted-foreground/60"), children: time }) : null
5938
5916
  ] }),
5939
- onDelete ? /* @__PURE__ */ jsx14(
5917
+ onDelete ? /* @__PURE__ */ jsx12(
5940
5918
  IconButton,
5941
5919
  {
5942
5920
  type: "button",
@@ -5948,7 +5926,7 @@ function SessionRow({ session, active, onSwitch, onDelete }) {
5948
5926
  onDelete(session.id);
5949
5927
  },
5950
5928
  "aria-label": `Delete ${session.title || "session"}`,
5951
- children: /* @__PURE__ */ jsx14(Trash2Icon, { className: "h-3 w-3" })
5929
+ children: /* @__PURE__ */ jsx12(Trash2Icon, { className: "h-3 w-3" })
5952
5930
  }
5953
5931
  ) : null
5954
5932
  ]
@@ -6195,15 +6173,15 @@ function searchPiSessions(sessions, query, options = {}) {
6195
6173
 
6196
6174
  // src/front/chat/components/PiConversationSurface.tsx
6197
6175
  import { Skeleton } from "@hachej/boring-ui-kit";
6198
- import { useCallback as useCallback14, useEffect as useEffect14, useLayoutEffect as useLayoutEffect2, useRef as useRef11, useState as useState15 } from "react";
6176
+ import { useCallback as useCallback14, useEffect as useEffect14, useLayoutEffect as useLayoutEffect2, useRef as useRef10, useState as useState15 } from "react";
6199
6177
  import { useStickToBottomContext as useStickToBottomContext2 } from "use-stick-to-bottom";
6200
6178
 
6201
6179
  // src/front/primitives/conversation.tsx
6202
- import { Button as Button7 } from "@hachej/boring-ui-kit";
6180
+ import { Button as Button6 } from "@hachej/boring-ui-kit";
6203
6181
  import { ArrowDownIcon, DownloadIcon as DownloadIcon2 } from "lucide-react";
6204
6182
  import { useCallback as useCallback8, useEffect as useEffect9 } from "react";
6205
6183
  import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
6206
- import { Fragment as Fragment6, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
6184
+ import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
6207
6185
  var ConversationScrollController = ({
6208
6186
  onScrollToBottomReady
6209
6187
  }) => {
@@ -6220,7 +6198,7 @@ var Conversation = ({
6220
6198
  children,
6221
6199
  onScrollToBottomReady,
6222
6200
  ...props
6223
- }) => /* @__PURE__ */ jsxs13(
6201
+ }) => /* @__PURE__ */ jsxs12(
6224
6202
  StickToBottom,
6225
6203
  {
6226
6204
  className: cn("relative flex-1 overflow-y-hidden", className),
@@ -6229,7 +6207,7 @@ var Conversation = ({
6229
6207
  role: "log",
6230
6208
  ...props,
6231
6209
  children: [
6232
- /* @__PURE__ */ jsx15(ConversationScrollController, { onScrollToBottomReady }),
6210
+ /* @__PURE__ */ jsx13(ConversationScrollController, { onScrollToBottomReady }),
6233
6211
  children
6234
6212
  ]
6235
6213
  }
@@ -6237,7 +6215,7 @@ var Conversation = ({
6237
6215
  var ConversationContent = ({
6238
6216
  className,
6239
6217
  ...props
6240
- }) => /* @__PURE__ */ jsx15(
6218
+ }) => /* @__PURE__ */ jsx13(
6241
6219
  StickToBottom.Content,
6242
6220
  {
6243
6221
  className: cn("flex flex-col gap-8 p-4", className),
@@ -6252,8 +6230,8 @@ var ConversationScrollButton = ({
6252
6230
  const handleScrollToBottom = useCallback8(() => {
6253
6231
  scrollToBottom();
6254
6232
  }, [scrollToBottom]);
6255
- return !isAtBottom && /* @__PURE__ */ jsx15(
6256
- Button7,
6233
+ return !isAtBottom && /* @__PURE__ */ jsx13(
6234
+ Button6,
6257
6235
  {
6258
6236
  className: cn(
6259
6237
  "boring-agent-scroll-latest absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full dark:bg-background dark:hover:bg-muted",
@@ -6265,13 +6243,13 @@ var ConversationScrollButton = ({
6265
6243
  variant: "outline",
6266
6244
  "aria-label": "Scroll to latest message",
6267
6245
  ...props,
6268
- children: /* @__PURE__ */ jsx15(ArrowDownIcon, { className: "size-4" })
6246
+ children: /* @__PURE__ */ jsx13(ArrowDownIcon, { className: "size-4" })
6269
6247
  }
6270
6248
  );
6271
6249
  };
6272
6250
 
6273
6251
  // src/front/chat/components/ChatNotices.tsx
6274
- import { AlertCircleIcon, ExternalLinkIcon as ExternalLinkIcon2, ListRestartIcon, Loader2, XIcon as XIcon3 } from "lucide-react";
6252
+ import { AlertCircleIcon, ExternalLinkIcon as ExternalLinkIcon2, ListRestartIcon, Loader2, XIcon as XIcon2 } from "lucide-react";
6275
6253
  import { IconButton as IconButton2 } from "@hachej/boring-ui-kit";
6276
6254
 
6277
6255
  // src/front/chat/components/noticeStyles.ts
@@ -6299,8 +6277,8 @@ function noticeTextClass(className) {
6299
6277
 
6300
6278
  // src/front/chat/components/RuntimeNotices.tsx
6301
6279
  import { memo as memo2 } from "react";
6302
- import { AlertTriangleIcon, InfoIcon, Loader2Icon, PlugZapIcon, RefreshCwIcon, XIcon as XIcon2 } from "lucide-react";
6303
- import { Button as Button8 } from "@hachej/boring-ui-kit";
6280
+ import { AlertTriangleIcon, InfoIcon, Loader2Icon, PlugZapIcon, RefreshCwIcon, XIcon } from "lucide-react";
6281
+ import { Button as Button7 } from "@hachej/boring-ui-kit";
6304
6282
 
6305
6283
  // src/front/chat/components/terminalChatErrors.ts
6306
6284
  var TERMINAL_CHAT_ERROR_IDS = /* @__PURE__ */ new Set(["chat-error", "session-navigation-error"]);
@@ -6320,16 +6298,16 @@ function filterCompetingNoiseNotices(notices, historyEmpty) {
6320
6298
  }
6321
6299
 
6322
6300
  // src/front/chat/components/RuntimeNotices.tsx
6323
- import { Fragment as Fragment7, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
6301
+ import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
6324
6302
  var RuntimeNotices = memo2(({ notices, onDismiss, onAction, renderAction, historyEmpty, className, ...props }) => {
6325
6303
  if (notices.length === 0) return null;
6326
- return /* @__PURE__ */ jsx16(
6304
+ return /* @__PURE__ */ jsx14(
6327
6305
  "div",
6328
6306
  {
6329
6307
  "data-boring-agent-part": "runtime-notices",
6330
6308
  className: cn("flex flex-col gap-2 px-4 py-2", className),
6331
6309
  ...props,
6332
- children: notices.map((notice) => /* @__PURE__ */ jsx16(
6310
+ children: notices.map((notice) => /* @__PURE__ */ jsx14(
6333
6311
  RuntimeNoticeRow,
6334
6312
  {
6335
6313
  notice,
@@ -6350,9 +6328,9 @@ function RuntimeNoticeRow({ notice, onDismiss, onAction, renderAction, historyEm
6350
6328
  const actionLabel = notice.actionLabel ?? defaultActionLabel(kind);
6351
6329
  const hostAction = renderAction?.(notice);
6352
6330
  const isTerminalError = isTerminalChatErrorNotice(notice.id, historyEmpty);
6353
- const explicitAction = actionLabel && onAction ? /* @__PURE__ */ jsx16(Button8, { type: "button", variant: "ghost", size: "sm", onClick: () => onAction(notice.id), children: actionLabel }) : null;
6354
- const primaryAction = hostAction ?? explicitAction ?? (isTerminalError ? /* @__PURE__ */ jsx16(Button8, { type: "button", variant: "outline", size: "sm", className: "shrink-0", onClick: () => window.location.reload(), children: "Reload workspace" }) : null);
6355
- return /* @__PURE__ */ jsxs14(
6331
+ const explicitAction = actionLabel && onAction ? /* @__PURE__ */ jsx14(Button7, { type: "button", variant: "ghost", size: "sm", onClick: () => onAction(notice.id), children: actionLabel }) : null;
6332
+ const primaryAction = hostAction ?? explicitAction ?? (isTerminalError ? /* @__PURE__ */ jsx14(Button7, { type: "button", variant: "outline", size: "sm", className: "shrink-0", onClick: () => window.location.reload(), children: "Reload workspace" }) : null);
6333
+ return /* @__PURE__ */ jsxs13(
6356
6334
  "div",
6357
6335
  {
6358
6336
  role: notice.level === "error" ? "alert" : "status",
@@ -6366,18 +6344,18 @@ function RuntimeNoticeRow({ notice, onDismiss, onAction, renderAction, historyEm
6366
6344
  "flex items-start gap-2.5 motion-reduce:transition-none"
6367
6345
  ),
6368
6346
  children: [
6369
- /* @__PURE__ */ jsx16(Icon, { className: cn(noticeIconClass(notice.level), kind === "retry" && "animate-spin motion-reduce:animate-none"), "aria-hidden": "true" }),
6370
- /* @__PURE__ */ jsx16("div", { className: "min-w-0 flex-1", children: isTerminalError ? /* @__PURE__ */ jsxs14(Fragment7, { children: [
6371
- /* @__PURE__ */ jsx16("p", { className: "text-sm font-semibold text-foreground", children: "Chat history unavailable" }),
6372
- /* @__PURE__ */ jsx16("p", { className: noticeTextClass("mt-0.5"), children: "The saved conversation could not be loaded. Reload the workspace to try again." }),
6373
- /* @__PURE__ */ jsxs14("details", { className: "mt-2 text-xs text-muted-foreground", children: [
6374
- /* @__PURE__ */ jsx16("summary", { className: "cursor-pointer select-none", children: "Error details" }),
6375
- /* @__PURE__ */ jsx16("p", { className: "mt-1 break-words", children: notice.text })
6347
+ /* @__PURE__ */ jsx14(Icon, { className: cn(noticeIconClass(notice.level), kind === "retry" && "animate-spin motion-reduce:animate-none"), "aria-hidden": "true" }),
6348
+ /* @__PURE__ */ jsx14("div", { className: "min-w-0 flex-1", children: isTerminalError ? /* @__PURE__ */ jsxs13(Fragment7, { children: [
6349
+ /* @__PURE__ */ jsx14("p", { className: "text-sm font-semibold text-foreground", children: "Chat history unavailable" }),
6350
+ /* @__PURE__ */ jsx14("p", { className: noticeTextClass("mt-0.5"), children: "The saved conversation could not be loaded. Reload the workspace to try again." }),
6351
+ /* @__PURE__ */ jsxs13("details", { className: "mt-2 text-xs text-muted-foreground", children: [
6352
+ /* @__PURE__ */ jsx14("summary", { className: "cursor-pointer select-none", children: "Error details" }),
6353
+ /* @__PURE__ */ jsx14("p", { className: "mt-1 break-words", children: notice.text })
6376
6354
  ] })
6377
- ] }) : /* @__PURE__ */ jsx16("p", { className: noticeTextClass(), children: notice.text }) }),
6355
+ ] }) : /* @__PURE__ */ jsx14("p", { className: noticeTextClass(), children: notice.text }) }),
6378
6356
  primaryAction,
6379
- notice.dismissible && onDismiss ? /* @__PURE__ */ jsx16(
6380
- Button8,
6357
+ notice.dismissible && onDismiss ? /* @__PURE__ */ jsx14(
6358
+ Button7,
6381
6359
  {
6382
6360
  type: "button",
6383
6361
  variant: "ghost",
@@ -6385,7 +6363,7 @@ function RuntimeNoticeRow({ notice, onDismiss, onAction, renderAction, historyEm
6385
6363
  "aria-label": "Dismiss notice",
6386
6364
  onClick: () => onDismiss(notice.id),
6387
6365
  className: "-mr-1 -mt-1 shrink-0 text-muted-foreground/70 hover:bg-muted hover:text-foreground",
6388
- children: /* @__PURE__ */ jsx16(XIcon2, { className: "size-3" })
6366
+ children: /* @__PURE__ */ jsx14(XIcon, { className: "size-3" })
6389
6367
  }
6390
6368
  ) : null
6391
6369
  ]
@@ -6414,7 +6392,7 @@ function defaultActionLabel(kind) {
6414
6392
  }
6415
6393
 
6416
6394
  // src/front/chat/components/ChatNotices.tsx
6417
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
6395
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
6418
6396
  function RuntimeNoticeMessages({
6419
6397
  notices,
6420
6398
  onDismiss,
@@ -6425,7 +6403,7 @@ function RuntimeNoticeMessages({
6425
6403
  (notice) => notice.level === "error" || notice.level === "warning" || notice.id === "connection-reconnecting" || notice.id === "auto-retry" || notice.id === "large-state-warning" || notice.id.startsWith("command:") || notice.id.startsWith("composer-warning:")
6426
6404
  );
6427
6405
  if (visible.length === 0) return null;
6428
- return /* @__PURE__ */ jsx17(
6406
+ return /* @__PURE__ */ jsx15(
6429
6407
  RuntimeNotices,
6430
6408
  {
6431
6409
  notices: visible,
@@ -6438,42 +6416,42 @@ function RuntimeNoticeMessages({
6438
6416
  }
6439
6417
  function ComposerRuntimeNotice({ notice }) {
6440
6418
  const level = notice.code === ErrorCode.enum.AGENT_RUNTIME_NOT_READY ? "info" : "error";
6441
- return /* @__PURE__ */ jsx17(
6419
+ return /* @__PURE__ */ jsx15(
6442
6420
  "div",
6443
6421
  {
6444
6422
  "data-testid": "chat-composer-runtime-notice",
6445
6423
  role: "status",
6446
6424
  "aria-live": "polite",
6447
6425
  className: noticeSurfaceClass(level, "mx-auto mb-2 w-full max-w-3xl text-xs"),
6448
- children: /* @__PURE__ */ jsxs15("div", { className: "flex items-start gap-2", children: [
6449
- notice.code === ErrorCode.enum.AGENT_RUNTIME_NOT_READY ? /* @__PURE__ */ jsx17(Loader2, { "aria-hidden": "true", className: "mt-0.5 size-3.5 shrink-0 animate-spin text-muted-foreground" }) : /* @__PURE__ */ jsx17(AlertCircleIcon, { "aria-hidden": "true", className: "mt-0.5 size-3.5 shrink-0 text-destructive" }),
6450
- /* @__PURE__ */ jsxs15("div", { className: "min-w-0", children: [
6451
- /* @__PURE__ */ jsx17("div", { className: "font-medium", children: notice.title }),
6452
- notice.detail ? /* @__PURE__ */ jsx17(NoticeText, { className: "mt-0.5 text-muted-foreground", children: notice.detail }) : null
6426
+ children: /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-2", children: [
6427
+ notice.code === ErrorCode.enum.AGENT_RUNTIME_NOT_READY ? /* @__PURE__ */ jsx15(Loader2, { "aria-hidden": "true", className: "mt-0.5 size-3.5 shrink-0 animate-spin text-muted-foreground" }) : /* @__PURE__ */ jsx15(AlertCircleIcon, { "aria-hidden": "true", className: "mt-0.5 size-3.5 shrink-0 text-destructive" }),
6428
+ /* @__PURE__ */ jsxs14("div", { className: "min-w-0", children: [
6429
+ /* @__PURE__ */ jsx15("div", { className: "font-medium", children: notice.title }),
6430
+ notice.detail ? /* @__PURE__ */ jsx15(NoticeText, { className: "mt-0.5 text-muted-foreground", children: notice.detail }) : null
6453
6431
  ] })
6454
6432
  ] })
6455
6433
  }
6456
6434
  );
6457
6435
  }
6458
6436
  function NoticeText({ className, children }) {
6459
- return /* @__PURE__ */ jsx17("div", { className: noticeTextClass(className), children });
6437
+ return /* @__PURE__ */ jsx15("div", { className: noticeTextClass(className), children });
6460
6438
  }
6461
6439
  function ComposerBlockerNotice({
6462
6440
  blocker,
6463
6441
  label,
6464
6442
  onAction
6465
6443
  }) {
6466
- return /* @__PURE__ */ jsxs15(
6444
+ return /* @__PURE__ */ jsxs14(
6467
6445
  "div",
6468
6446
  {
6469
6447
  role: "status",
6470
6448
  "aria-live": "polite",
6471
6449
  className: noticeSurfaceClass("info", "relative z-20 mx-auto mb-2 w-full max-w-3xl text-xs"),
6472
6450
  children: [
6473
- /* @__PURE__ */ jsx17("span", { children: label }),
6451
+ /* @__PURE__ */ jsx15("span", { children: label }),
6474
6452
  blocker?.actions?.map((action) => {
6475
6453
  const icon = composerBlockerActionIcon(action.id);
6476
- return icon ? /* @__PURE__ */ jsx17(
6454
+ return icon ? /* @__PURE__ */ jsx15(
6477
6455
  IconButton2,
6478
6456
  {
6479
6457
  type: "button",
@@ -6486,7 +6464,7 @@ function ComposerBlockerNotice({
6486
6464
  children: icon
6487
6465
  },
6488
6466
  action.id
6489
- ) : /* @__PURE__ */ jsx17(
6467
+ ) : /* @__PURE__ */ jsx15(
6490
6468
  "button",
6491
6469
  {
6492
6470
  type: "button",
@@ -6502,12 +6480,12 @@ function ComposerBlockerNotice({
6502
6480
  );
6503
6481
  }
6504
6482
  function composerBlockerActionIcon(actionId) {
6505
- if (actionId === "open") return /* @__PURE__ */ jsx17(ExternalLinkIcon2, { className: "size-3.5", "aria-hidden": "true" });
6506
- if (actionId === "cancel") return /* @__PURE__ */ jsx17(XIcon3, { className: "size-3.5", "aria-hidden": "true" });
6483
+ if (actionId === "open") return /* @__PURE__ */ jsx15(ExternalLinkIcon2, { className: "size-3.5", "aria-hidden": "true" });
6484
+ if (actionId === "cancel") return /* @__PURE__ */ jsx15(XIcon2, { className: "size-3.5", "aria-hidden": "true" });
6507
6485
  return null;
6508
6486
  }
6509
6487
  function QueuedComposerNotice({ followUps, onEdit }) {
6510
- return /* @__PURE__ */ jsxs15(
6488
+ return /* @__PURE__ */ jsxs14(
6511
6489
  "div",
6512
6490
  {
6513
6491
  "data-boring-agent-part": "composer-queue-preview",
@@ -6516,15 +6494,15 @@ function QueuedComposerNotice({ followUps, onEdit }) {
6516
6494
  "border border-dashed border-[color:var(--border)] bg-[color:oklch(from_var(--muted)_l_c_h/0.45)] px-3 py-2 text-xs text-[color:var(--foreground)]"
6517
6495
  ),
6518
6496
  children: [
6519
- /* @__PURE__ */ jsxs15("div", { className: "min-w-0 text-[color:var(--muted-foreground)]", children: [
6520
- /* @__PURE__ */ jsxs15("div", { className: "font-medium text-[color:var(--foreground)]", children: [
6497
+ /* @__PURE__ */ jsxs14("div", { className: "min-w-0 text-[color:var(--muted-foreground)]", children: [
6498
+ /* @__PURE__ */ jsxs14("div", { className: "font-medium text-[color:var(--foreground)]", children: [
6521
6499
  followUps.length,
6522
6500
  " queued follow-up",
6523
6501
  followUps.length === 1 ? "" : "s"
6524
6502
  ] }),
6525
- /* @__PURE__ */ jsx17("div", { className: "truncate text-[color:var(--muted-foreground)]", "data-boring-agent-part": "composer-queue-preview-text", children: followUps.map((followUp) => followUp.displayText).join(" - ") })
6503
+ /* @__PURE__ */ jsx15("div", { className: "truncate text-[color:var(--muted-foreground)]", "data-boring-agent-part": "composer-queue-preview-text", children: followUps.map((followUp) => followUp.displayText).join(" - ") })
6526
6504
  ] }),
6527
- /* @__PURE__ */ jsx17(
6505
+ /* @__PURE__ */ jsx15(
6528
6506
  IconButton2,
6529
6507
  {
6530
6508
  type: "button",
@@ -6534,7 +6512,7 @@ function QueuedComposerNotice({ followUps, onEdit }) {
6534
6512
  className: "shrink-0 text-[color:var(--muted-foreground)] hover:bg-[color:var(--muted)] hover:text-[color:var(--foreground)]",
6535
6513
  "aria-label": "Edit queued follow-ups",
6536
6514
  title: "Edit queued follow-ups",
6537
- children: /* @__PURE__ */ jsx17(ListRestartIcon, { className: "size-3.5", "aria-hidden": "true" })
6515
+ children: /* @__PURE__ */ jsx15(ListRestartIcon, { className: "size-3.5", "aria-hidden": "true" })
6538
6516
  }
6539
6517
  )
6540
6518
  ]
@@ -6543,12 +6521,12 @@ function QueuedComposerNotice({ followUps, onEdit }) {
6543
6521
  }
6544
6522
 
6545
6523
  // src/front/chat/components/PiTimelineMessage.tsx
6546
- import { useCallback as useCallback13, useEffect as useEffect13, useMemo as useMemo12, useRef as useRef10, useState as useState14 } from "react";
6524
+ import { useCallback as useCallback13, useEffect as useEffect13, useMemo as useMemo12, useRef as useRef9, useState as useState14 } from "react";
6547
6525
  import { CheckIcon as CheckIcon2, CopyIcon as CopyIcon3 } from "lucide-react";
6548
- import { Button as Button11 } from "@hachej/boring-ui-kit";
6526
+ import { Button as Button10 } from "@hachej/boring-ui-kit";
6549
6527
 
6550
6528
  // src/front/primitives/attachments.tsx
6551
- import { Button as Button9, HoverCard, HoverCardContent, HoverCardTrigger } from "@hachej/boring-ui-kit";
6529
+ import { Button as Button8, HoverCard, HoverCardContent, HoverCardTrigger } from "@hachej/boring-ui-kit";
6552
6530
  import {
6553
6531
  FileTextIcon as FileTextIcon2,
6554
6532
  GlobeIcon,
@@ -6556,10 +6534,10 @@ import {
6556
6534
  Music2Icon,
6557
6535
  PaperclipIcon,
6558
6536
  VideoIcon,
6559
- XIcon as XIcon4
6537
+ XIcon as XIcon3
6560
6538
  } from "lucide-react";
6561
- import { createContext as createContext4, useCallback as useCallback9, useContext as useContext4, useMemo as useMemo6 } from "react";
6562
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
6539
+ import { createContext as createContext3, useCallback as useCallback9, useContext as useContext3, useMemo as useMemo6 } from "react";
6540
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
6563
6541
  var mediaCategoryIcons = {
6564
6542
  audio: Music2Icon,
6565
6543
  document: FileTextIcon2,
@@ -6594,7 +6572,7 @@ var getAttachmentLabel = (data) => {
6594
6572
  const category = getMediaCategory(data);
6595
6573
  return data.filename || (category === "image" ? "Image" : "Attachment");
6596
6574
  };
6597
- var renderAttachmentImage = (url, filename, isGrid) => isGrid ? /* @__PURE__ */ jsx18(
6575
+ var renderAttachmentImage = (url, filename, isGrid) => isGrid ? /* @__PURE__ */ jsx16(
6598
6576
  "img",
6599
6577
  {
6600
6578
  alt: filename || "Image",
@@ -6603,7 +6581,7 @@ var renderAttachmentImage = (url, filename, isGrid) => isGrid ? /* @__PURE__ */
6603
6581
  src: url,
6604
6582
  width: 96
6605
6583
  }
6606
- ) : /* @__PURE__ */ jsx18(
6584
+ ) : /* @__PURE__ */ jsx16(
6607
6585
  "img",
6608
6586
  {
6609
6587
  alt: filename || "Image",
@@ -6613,11 +6591,11 @@ var renderAttachmentImage = (url, filename, isGrid) => isGrid ? /* @__PURE__ */
6613
6591
  width: 20
6614
6592
  }
6615
6593
  );
6616
- var AttachmentsContext = createContext4(null);
6617
- var AttachmentContext = createContext4(null);
6618
- var useAttachmentsContext = () => useContext4(AttachmentsContext) ?? { variant: "grid" };
6594
+ var AttachmentsContext = createContext3(null);
6595
+ var AttachmentContext = createContext3(null);
6596
+ var useAttachmentsContext = () => useContext3(AttachmentsContext) ?? { variant: "grid" };
6619
6597
  var useAttachmentContext = () => {
6620
- const ctx = useContext4(AttachmentContext);
6598
+ const ctx = useContext3(AttachmentContext);
6621
6599
  if (!ctx) {
6622
6600
  throw new Error("Attachment components must be used within <Attachment>");
6623
6601
  }
@@ -6630,7 +6608,7 @@ var Attachments = ({
6630
6608
  ...props
6631
6609
  }) => {
6632
6610
  const contextValue = useMemo6(() => ({ variant }), [variant]);
6633
- return /* @__PURE__ */ jsx18(AttachmentsContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx18(
6611
+ return /* @__PURE__ */ jsx16(AttachmentsContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx16(
6634
6612
  "div",
6635
6613
  {
6636
6614
  className: cn(
@@ -6657,7 +6635,7 @@ var Attachment = ({
6657
6635
  () => ({ data, mediaCategory, onRemove, variant }),
6658
6636
  [data, mediaCategory, onRemove, variant]
6659
6637
  );
6660
- return /* @__PURE__ */ jsx18(AttachmentContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx18(
6638
+ return /* @__PURE__ */ jsx16(AttachmentContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx16(
6661
6639
  "div",
6662
6640
  {
6663
6641
  className: cn(
@@ -6687,18 +6665,18 @@ var AttachmentPreview = ({
6687
6665
  }) => {
6688
6666
  const { data, mediaCategory, variant } = useAttachmentContext();
6689
6667
  const iconSize = variant === "inline" ? "size-3" : "size-4";
6690
- const renderIcon = (Icon) => /* @__PURE__ */ jsx18(Icon, { className: cn(iconSize, "text-muted-foreground") });
6668
+ const renderIcon = (Icon) => /* @__PURE__ */ jsx16(Icon, { className: cn(iconSize, "text-muted-foreground") });
6691
6669
  const renderContent = () => {
6692
6670
  if (mediaCategory === "image" && data.type === "file" && data.url) {
6693
6671
  return renderAttachmentImage(data.url, data.filename, variant === "grid");
6694
6672
  }
6695
6673
  if (mediaCategory === "video" && data.type === "file" && data.url) {
6696
- return /* @__PURE__ */ jsx18("video", { className: "size-full object-cover", muted: true, src: data.url });
6674
+ return /* @__PURE__ */ jsx16("video", { className: "size-full object-cover", muted: true, src: data.url });
6697
6675
  }
6698
6676
  const Icon = mediaCategoryIcons[mediaCategory];
6699
6677
  return fallbackIcon ?? renderIcon(Icon);
6700
6678
  };
6701
- return /* @__PURE__ */ jsx18(
6679
+ return /* @__PURE__ */ jsx16(
6702
6680
  "div",
6703
6681
  {
6704
6682
  className: cn(
@@ -6723,9 +6701,9 @@ var AttachmentInfo = ({
6723
6701
  if (variant === "grid") {
6724
6702
  return null;
6725
6703
  }
6726
- return /* @__PURE__ */ jsxs16("div", { className: cn("min-w-0 flex-1", className), ...props, children: [
6727
- /* @__PURE__ */ jsx18("span", { className: "block truncate", children: label }),
6728
- showMediaType && data.mediaType && /* @__PURE__ */ jsx18("span", { className: "block truncate text-muted-foreground text-xs", children: data.mediaType })
6704
+ return /* @__PURE__ */ jsxs15("div", { className: cn("min-w-0 flex-1", className), ...props, children: [
6705
+ /* @__PURE__ */ jsx16("span", { className: "block truncate", children: label }),
6706
+ showMediaType && data.mediaType && /* @__PURE__ */ jsx16("span", { className: "block truncate text-muted-foreground text-xs", children: data.mediaType })
6729
6707
  ] });
6730
6708
  };
6731
6709
  var AttachmentRemove = ({
@@ -6745,8 +6723,8 @@ var AttachmentRemove = ({
6745
6723
  if (!onRemove) {
6746
6724
  return null;
6747
6725
  }
6748
- return /* @__PURE__ */ jsxs16(
6749
- Button9,
6726
+ return /* @__PURE__ */ jsxs15(
6727
+ Button8,
6750
6728
  {
6751
6729
  "aria-label": label,
6752
6730
  className: cn(
@@ -6770,20 +6748,20 @@ var AttachmentRemove = ({
6770
6748
  variant: "ghost",
6771
6749
  ...props,
6772
6750
  children: [
6773
- children ?? /* @__PURE__ */ jsx18(XIcon4, {}),
6774
- /* @__PURE__ */ jsx18("span", { className: "sr-only", children: label })
6751
+ children ?? /* @__PURE__ */ jsx16(XIcon3, {}),
6752
+ /* @__PURE__ */ jsx16("span", { className: "sr-only", children: label })
6775
6753
  ]
6776
6754
  }
6777
6755
  );
6778
6756
  };
6779
6757
 
6780
6758
  // src/front/primitives/message.tsx
6781
- import { Button as Button10, ButtonGroup, ButtonGroupText } from "@hachej/boring-ui-kit";
6759
+ import { Button as Button9, ButtonGroup, ButtonGroupText } from "@hachej/boring-ui-kit";
6782
6760
  import {
6783
- Tooltip as Tooltip2,
6784
- TooltipContent as TooltipContent2,
6785
- TooltipProvider as TooltipProvider2,
6786
- TooltipTrigger as TooltipTrigger2
6761
+ Tooltip,
6762
+ TooltipContent,
6763
+ TooltipProvider,
6764
+ TooltipTrigger
6787
6765
  } from "@hachej/boring-ui-kit";
6788
6766
 
6789
6767
  // src/front/primitives/markdownStyles.ts
@@ -6796,17 +6774,17 @@ import { math } from "@streamdown/math";
6796
6774
  import { mermaid } from "@streamdown/mermaid";
6797
6775
  import { ChevronLeftIcon as ChevronLeftIcon2, ChevronRightIcon } from "lucide-react";
6798
6776
  import {
6799
- createContext as createContext5,
6777
+ createContext as createContext4,
6800
6778
  memo as memo3,
6801
6779
  useCallback as useCallback10,
6802
- useContext as useContext5,
6780
+ useContext as useContext4,
6803
6781
  useEffect as useEffect10,
6804
6782
  useMemo as useMemo7,
6805
6783
  useState as useState11
6806
6784
  } from "react";
6807
6785
  import { Streamdown } from "streamdown";
6808
- import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
6809
- var Message = ({ className, from, ...props }) => /* @__PURE__ */ jsx19(
6786
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
6787
+ var Message = ({ className, from, ...props }) => /* @__PURE__ */ jsx17(
6810
6788
  "div",
6811
6789
  {
6812
6790
  "data-boring-agent-message-role": from,
@@ -6822,7 +6800,7 @@ var MessageContent = ({
6822
6800
  children,
6823
6801
  className,
6824
6802
  ...props
6825
- }) => /* @__PURE__ */ jsx19(
6803
+ }) => /* @__PURE__ */ jsx17(
6826
6804
  "div",
6827
6805
  {
6828
6806
  className: cn(
@@ -6839,7 +6817,7 @@ var MessageActions = ({
6839
6817
  className,
6840
6818
  children,
6841
6819
  ...props
6842
- }) => /* @__PURE__ */ jsx19("div", { className: cn("flex items-center gap-1", className), ...props, children });
6820
+ }) => /* @__PURE__ */ jsx17("div", { className: cn("flex items-center gap-1", className), ...props, children });
6843
6821
  var MessageAction = ({
6844
6822
  tooltip,
6845
6823
  children,
@@ -6848,19 +6826,19 @@ var MessageAction = ({
6848
6826
  size = "icon-sm",
6849
6827
  ...props
6850
6828
  }) => {
6851
- const button = /* @__PURE__ */ jsxs17(Button10, { size, type: "button", variant, ...props, children: [
6829
+ const button = /* @__PURE__ */ jsxs16(Button9, { size, type: "button", variant, ...props, children: [
6852
6830
  children,
6853
- /* @__PURE__ */ jsx19("span", { className: "sr-only", children: label || tooltip })
6831
+ /* @__PURE__ */ jsx17("span", { className: "sr-only", children: label || tooltip })
6854
6832
  ] });
6855
6833
  if (tooltip) {
6856
- return /* @__PURE__ */ jsx19(TooltipProvider2, { children: /* @__PURE__ */ jsxs17(Tooltip2, { children: [
6857
- /* @__PURE__ */ jsx19(TooltipTrigger2, { asChild: true, children: button }),
6858
- /* @__PURE__ */ jsx19(TooltipContent2, { children: /* @__PURE__ */ jsx19("p", { children: tooltip }) })
6834
+ return /* @__PURE__ */ jsx17(TooltipProvider, { children: /* @__PURE__ */ jsxs16(Tooltip, { children: [
6835
+ /* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: button }),
6836
+ /* @__PURE__ */ jsx17(TooltipContent, { children: /* @__PURE__ */ jsx17("p", { children: tooltip }) })
6859
6837
  ] }) });
6860
6838
  }
6861
6839
  return button;
6862
6840
  };
6863
- var MessageBranchContext = createContext5(
6841
+ var MessageBranchContext = createContext4(
6864
6842
  null
6865
6843
  );
6866
6844
  var streamdownPlugins = { cjk, code, math, mermaid };
@@ -6896,9 +6874,9 @@ function extractCodeBlockText(children) {
6896
6874
  var MarkdownPre = ({ children, filename }) => {
6897
6875
  const code3 = extractCodeBlockText(children).replace(/\n$/, "");
6898
6876
  const language = extractCodeBlockLanguage(children);
6899
- return /* @__PURE__ */ jsx19(CodeBlock2, { code: code3, language: language ?? "text", className: "my-3", children: /* @__PURE__ */ jsxs17(CodeBlockHeader, { children: [
6900
- /* @__PURE__ */ jsx19(CodeBlockTitle, { children: /* @__PURE__ */ jsx19(CodeBlockFilename, { children: filename ?? language ?? "text" }) }),
6901
- /* @__PURE__ */ jsx19(CodeBlockCopyButton, {})
6877
+ return /* @__PURE__ */ jsx17(CodeBlock2, { code: code3, language: language ?? "text", className: "my-3", children: /* @__PURE__ */ jsxs16(CodeBlockHeader, { children: [
6878
+ /* @__PURE__ */ jsx17(CodeBlockTitle, { children: /* @__PURE__ */ jsx17(CodeBlockFilename, { children: filename ?? language ?? "text" }) }),
6879
+ /* @__PURE__ */ jsx17(CodeBlockCopyButton, {})
6902
6880
  ] }) });
6903
6881
  };
6904
6882
  var MarkdownCode = ({
@@ -6908,9 +6886,9 @@ var MarkdownCode = ({
6908
6886
  ...props
6909
6887
  }) => {
6910
6888
  if (inline === false) {
6911
- return /* @__PURE__ */ jsx19("code", { className, ...props, children });
6889
+ return /* @__PURE__ */ jsx17("code", { className, ...props, children });
6912
6890
  }
6913
- return /* @__PURE__ */ jsx19(
6891
+ return /* @__PURE__ */ jsx17(
6914
6892
  "code",
6915
6893
  {
6916
6894
  className: cn(
@@ -6927,7 +6905,7 @@ var markdownComponents = {
6927
6905
  code: MarkdownCode
6928
6906
  };
6929
6907
  var MessageResponse = memo3(
6930
- ({ className, shikiTheme, components, codeFilename, ...props }) => /* @__PURE__ */ jsx19(
6908
+ ({ className, shikiTheme, components, codeFilename, ...props }) => /* @__PURE__ */ jsx17(
6931
6909
  Streamdown,
6932
6910
  {
6933
6911
  className: cn(
@@ -6939,7 +6917,7 @@ var MessageResponse = memo3(
6939
6917
  components: {
6940
6918
  ...markdownComponents,
6941
6919
  ...components ?? {},
6942
- ...codeFilename ? { pre: (props2) => /* @__PURE__ */ jsx19(MarkdownPre, { ...props2, filename: codeFilename }) } : {}
6920
+ ...codeFilename ? { pre: (props2) => /* @__PURE__ */ jsx17(MarkdownPre, { ...props2, filename: codeFilename }) } : {}
6943
6921
  },
6944
6922
  ...props
6945
6923
  }
@@ -6961,13 +6939,13 @@ import { math as math2 } from "@streamdown/math";
6961
6939
  import { mermaid as mermaid2 } from "@streamdown/mermaid";
6962
6940
  import { BrainIcon, ChevronDownIcon as ChevronDownIcon3 } from "lucide-react";
6963
6941
  import {
6964
- createContext as createContext6,
6942
+ createContext as createContext5,
6965
6943
  memo as memo5,
6966
6944
  useCallback as useCallback11,
6967
- useContext as useContext6,
6945
+ useContext as useContext5,
6968
6946
  useEffect as useEffect11,
6969
6947
  useMemo as useMemo9,
6970
- useRef as useRef9,
6948
+ useRef as useRef8,
6971
6949
  useState as useState12
6972
6950
  } from "react";
6973
6951
  import { Streamdown as Streamdown2 } from "streamdown";
@@ -6975,7 +6953,7 @@ import { Streamdown as Streamdown2 } from "streamdown";
6975
6953
  // src/front/primitives/shimmer.tsx
6976
6954
  import { motion } from "motion/react";
6977
6955
  import { memo as memo4, useMemo as useMemo8 } from "react";
6978
- import { jsx as jsx20 } from "react/jsx-runtime";
6956
+ import { jsx as jsx18 } from "react/jsx-runtime";
6979
6957
  var motionComponentCache = /* @__PURE__ */ new Map();
6980
6958
  var getMotionComponent = (element) => {
6981
6959
  let component = motionComponentCache.get(element);
@@ -6999,7 +6977,7 @@ var ShimmerComponent = ({
6999
6977
  () => (children?.length ?? 0) * spread,
7000
6978
  [children, spread]
7001
6979
  );
7002
- return /* @__PURE__ */ jsx20(
6980
+ return /* @__PURE__ */ jsx18(
7003
6981
  MotionComponent,
7004
6982
  {
7005
6983
  animate: { backgroundPosition: "0% center" },
@@ -7025,10 +7003,10 @@ var ShimmerComponent = ({
7025
7003
  var Shimmer = memo4(ShimmerComponent);
7026
7004
 
7027
7005
  // src/front/primitives/reasoning.tsx
7028
- import { Fragment as Fragment8, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
7029
- var ReasoningContext = createContext6(null);
7006
+ import { Fragment as Fragment8, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
7007
+ var ReasoningContext = createContext5(null);
7030
7008
  var useReasoning = () => {
7031
- const context = useContext6(ReasoningContext);
7009
+ const context = useContext5(ReasoningContext);
7032
7010
  if (!context) {
7033
7011
  throw new Error("Reasoning components must be used within Reasoning");
7034
7012
  }
@@ -7059,9 +7037,9 @@ var Reasoning = memo5(
7059
7037
  defaultProp: void 0,
7060
7038
  prop: durationProp
7061
7039
  });
7062
- const hasEverStreamedRef = useRef9(isStreaming);
7040
+ const hasEverStreamedRef = useRef8(isStreaming);
7063
7041
  const [hasAutoClosed, setHasAutoClosed] = useState12(false);
7064
- const startTimeRef = useRef9(null);
7042
+ const startTimeRef = useRef8(null);
7065
7043
  useEffect11(() => {
7066
7044
  if (isStreaming) {
7067
7045
  hasEverStreamedRef.current = true;
@@ -7097,7 +7075,7 @@ var Reasoning = memo5(
7097
7075
  () => ({ duration, isOpen, isStreaming, setIsOpen }),
7098
7076
  [duration, isOpen, isStreaming, setIsOpen]
7099
7077
  );
7100
- return /* @__PURE__ */ jsx21(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx21(
7078
+ return /* @__PURE__ */ jsx19(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx19(
7101
7079
  Collapsible2,
7102
7080
  {
7103
7081
  className: cn("not-prose mb-2", className),
@@ -7111,12 +7089,12 @@ var Reasoning = memo5(
7111
7089
  );
7112
7090
  var defaultGetThinkingMessage = (isStreaming, duration) => {
7113
7091
  if (isStreaming || duration === 0) {
7114
- return /* @__PURE__ */ jsx21(Shimmer, { duration: 1, children: "thinking" });
7092
+ return /* @__PURE__ */ jsx19(Shimmer, { duration: 1, children: "thinking" });
7115
7093
  }
7116
7094
  if (duration === void 0) {
7117
- return /* @__PURE__ */ jsx21("span", { children: "thoughts" });
7095
+ return /* @__PURE__ */ jsx19("span", { children: "thoughts" });
7118
7096
  }
7119
- return /* @__PURE__ */ jsxs18("span", { children: [
7097
+ return /* @__PURE__ */ jsxs17("span", { children: [
7120
7098
  "thoughts \xB7 ",
7121
7099
  duration,
7122
7100
  "s"
@@ -7130,7 +7108,7 @@ var ReasoningTrigger = memo5(
7130
7108
  ...props
7131
7109
  }) => {
7132
7110
  const { isStreaming, isOpen, duration } = useReasoning();
7133
- return /* @__PURE__ */ jsx21(
7111
+ return /* @__PURE__ */ jsx19(
7134
7112
  CollapsibleTrigger3,
7135
7113
  {
7136
7114
  className: cn(
@@ -7138,10 +7116,10 @@ var ReasoningTrigger = memo5(
7138
7116
  className
7139
7117
  ),
7140
7118
  ...props,
7141
- children: children ?? /* @__PURE__ */ jsxs18(Fragment8, { children: [
7142
- /* @__PURE__ */ jsx21(BrainIcon, { className: "size-3" }),
7119
+ children: children ?? /* @__PURE__ */ jsxs17(Fragment8, { children: [
7120
+ /* @__PURE__ */ jsx19(BrainIcon, { className: "size-3" }),
7143
7121
  getThinkingMessage(isStreaming, duration),
7144
- /* @__PURE__ */ jsx21(
7122
+ /* @__PURE__ */ jsx19(
7145
7123
  ChevronDownIcon3,
7146
7124
  {
7147
7125
  className: cn(
@@ -7157,7 +7135,7 @@ var ReasoningTrigger = memo5(
7157
7135
  );
7158
7136
  var streamdownPlugins2 = { cjk: cjk2, code: code2, math: math2, mermaid: mermaid2 };
7159
7137
  var ReasoningContent = memo5(
7160
- ({ className, children, ...props }) => /* @__PURE__ */ jsx21(
7138
+ ({ className, children, ...props }) => /* @__PURE__ */ jsx19(
7161
7139
  CollapsibleContent2,
7162
7140
  {
7163
7141
  className: cn(
@@ -7166,7 +7144,7 @@ var ReasoningContent = memo5(
7166
7144
  className
7167
7145
  ),
7168
7146
  ...props,
7169
- children: /* @__PURE__ */ jsx21(Streamdown2, { plugins: streamdownPlugins2, children })
7147
+ children: /* @__PURE__ */ jsx19(Streamdown2, { plugins: streamdownPlugins2, children })
7170
7148
  }
7171
7149
  )
7172
7150
  );
@@ -7215,7 +7193,7 @@ var TOOL_GROUP_VISUAL_PRESENTATION = {
7215
7193
  };
7216
7194
 
7217
7195
  // src/front/primitives/tool-call-group.tsx
7218
- import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
7196
+ import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
7219
7197
  function isInputRunningState(state) {
7220
7198
  return state === "input-streaming" || state === "input-available";
7221
7199
  }
@@ -7304,7 +7282,7 @@ var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
7304
7282
  const { renderer } = resolveToolRendererForPart(part, mergedToolRenderers);
7305
7283
  return renderer.presentation === "inline" ? [key] : [];
7306
7284
  }));
7307
- return /* @__PURE__ */ jsxs19(
7285
+ return /* @__PURE__ */ jsxs18(
7308
7286
  Collapsible3,
7309
7287
  {
7310
7288
  open: isOpen,
@@ -7315,9 +7293,9 @@ var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
7315
7293
  toolParts.map(({ part, key }) => {
7316
7294
  if (!inlineToolKeys.has(key)) return null;
7317
7295
  const { renderer, part: resolvedPart, resolution } = resolveToolRendererForPart(part, mergedToolRenderers);
7318
- return /* @__PURE__ */ jsx22("div", { "data-boring-agent-part": "inline-tool-renderer", "data-tool-call-id": resolvedPart.toolCallId, "data-tool-renderer-key": resolution.key, children: renderer(resolvedPart) }, key);
7296
+ return /* @__PURE__ */ jsx20("div", { "data-boring-agent-part": "inline-tool-renderer", "data-tool-call-id": resolvedPart.toolCallId, "data-tool-renderer-key": resolution.key, children: renderer(resolvedPart) }, key);
7319
7297
  }),
7320
- /* @__PURE__ */ jsxs19(
7298
+ /* @__PURE__ */ jsxs18(
7321
7299
  CollapsibleTrigger4,
7322
7300
  {
7323
7301
  "aria-label": `Tool calls: ${title}`,
@@ -7329,7 +7307,7 @@ var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
7329
7307
  TOOL_GROUP_VISUAL_PRESENTATION[visualState].triggerClassName
7330
7308
  ),
7331
7309
  children: [
7332
- /* @__PURE__ */ jsx22("span", { className: "flex size-4 shrink-0 items-center justify-center", "aria-hidden": "true", children: /* @__PURE__ */ jsx22(
7310
+ /* @__PURE__ */ jsx20("span", { className: "flex size-4 shrink-0 items-center justify-center", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(
7333
7311
  "span",
7334
7312
  {
7335
7313
  "data-boring-agent-part": "tool-group-state-dot",
@@ -7339,10 +7317,10 @@ var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
7339
7317
  )
7340
7318
  }
7341
7319
  ) }),
7342
- /* @__PURE__ */ jsx22("span", { "data-boring-agent-part": "tool-group-title", children: workspaceNotReady ? workspaceNotReady.message : title }),
7343
- elapsedLabel ? /* @__PURE__ */ jsx22("span", { className: "ml-1 shrink-0 tabular-nums text-[12px] text-muted-foreground/70", children: elapsedLabel }) : null,
7344
- /* @__PURE__ */ jsx22("span", { className: "ml-1 shrink-0 tabular-nums text-[12px] text-muted-foreground/70", children: toolParts.length }),
7345
- /* @__PURE__ */ jsx22(
7320
+ /* @__PURE__ */ jsx20("span", { "data-boring-agent-part": "tool-group-title", children: workspaceNotReady ? workspaceNotReady.message : title }),
7321
+ elapsedLabel ? /* @__PURE__ */ jsx20("span", { className: "ml-1 shrink-0 tabular-nums text-[12px] text-muted-foreground/70", children: elapsedLabel }) : null,
7322
+ /* @__PURE__ */ jsx20("span", { className: "ml-1 shrink-0 tabular-nums text-[12px] text-muted-foreground/70", children: toolParts.length }),
7323
+ /* @__PURE__ */ jsx20(
7346
7324
  ChevronDownIcon4,
7347
7325
  {
7348
7326
  className: cn(
@@ -7354,19 +7332,19 @@ var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
7354
7332
  ]
7355
7333
  }
7356
7334
  ),
7357
- /* @__PURE__ */ jsx22(CollapsibleContent3, { className: "overflow-hidden data-[state=closed]:animate-[boring-collapse-close_200ms_ease] data-[state=open]:animate-[boring-collapse-open_200ms_ease]", children: /* @__PURE__ */ jsxs19(
7335
+ /* @__PURE__ */ jsx20(CollapsibleContent3, { className: "overflow-hidden data-[state=closed]:animate-[boring-collapse-close_200ms_ease] data-[state=open]:animate-[boring-collapse-open_200ms_ease]", children: /* @__PURE__ */ jsxs18(
7358
7336
  "div",
7359
7337
  {
7360
7338
  "data-boring-agent-part": "tool-group-details",
7361
7339
  className: "relative mt-1.5 w-full max-w-2xl pl-[18px]",
7362
7340
  children: [
7363
- /* @__PURE__ */ jsx22("div", { className: "absolute left-[5px] top-0 bottom-2 w-px bg-border/35" }),
7364
- /* @__PURE__ */ jsx22("div", { className: "flex min-w-0 flex-col gap-1.5 [&_[data-boring-agent-part=tool-card]]:!my-0", children: toolParts.map(({ part, key }) => {
7341
+ /* @__PURE__ */ jsx20("div", { className: "absolute left-[5px] top-0 bottom-2 w-px bg-border/35" }),
7342
+ /* @__PURE__ */ jsx20("div", { className: "flex min-w-0 flex-col gap-1.5 [&_[data-boring-agent-part=tool-card]]:!my-0", children: toolParts.map(({ part, key }) => {
7365
7343
  const { renderer, part: resolvedPart, resolution } = resolveToolRendererForPart(
7366
7344
  part,
7367
7345
  inlineToolKeys.has(key) ? {} : mergedToolRenderers
7368
7346
  );
7369
- return /* @__PURE__ */ jsx22(
7347
+ return /* @__PURE__ */ jsx20(
7370
7348
  "div",
7371
7349
  {
7372
7350
  className: "min-w-0",
@@ -7388,22 +7366,22 @@ var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
7388
7366
  ToolCallGroup.displayName = "ToolCallGroup";
7389
7367
 
7390
7368
  // src/front/chat/messageContributions.tsx
7391
- import { createContext as createContext7, createElement, useContext as useContext7, useMemo as useMemo11 } from "react";
7392
- import { jsx as jsx23 } from "react/jsx-runtime";
7393
- var ChatMessageContributionContext = createContext7([]);
7369
+ import { createContext as createContext6, createElement, useContext as useContext6, useMemo as useMemo11 } from "react";
7370
+ import { jsx as jsx21 } from "react/jsx-runtime";
7371
+ var ChatMessageContributionContext = createContext6([]);
7394
7372
  function ChatMessageContributionProvider({
7395
7373
  contribution,
7396
7374
  children
7397
7375
  }) {
7398
- const parent = useContext7(ChatMessageContributionContext);
7376
+ const parent = useContext6(ChatMessageContributionContext);
7399
7377
  const contributions = useMemo11(
7400
7378
  () => [contribution, ...parent.filter((entry) => entry.id !== contribution.id)],
7401
7379
  [contribution, parent]
7402
7380
  );
7403
- return /* @__PURE__ */ jsx23(ChatMessageContributionContext.Provider, { value: contributions, children });
7381
+ return /* @__PURE__ */ jsx21(ChatMessageContributionContext.Provider, { value: contributions, children });
7404
7382
  }
7405
7383
  function useCustomChatMessage(message) {
7406
- const contributions = useContext7(ChatMessageContributionContext);
7384
+ const contributions = useContext6(ChatMessageContributionContext);
7407
7385
  const contribution = contributions.find((entry) => entry.matches(message));
7408
7386
  return contribution ? createElement(contribution.Component, { message }) : void 0;
7409
7387
  }
@@ -7417,7 +7395,7 @@ function ChatMessageContributionBoundary({
7417
7395
 
7418
7396
  // src/front/chat/components/MessageMentions.tsx
7419
7397
  import { Children, cloneElement, isValidElement as isValidElement2 } from "react";
7420
- import { Fragment as Fragment9, jsx as jsx24 } from "react/jsx-runtime";
7398
+ import { Fragment as Fragment9, jsx as jsx22 } from "react/jsx-runtime";
7421
7399
  var TERMINAL_BOUNDARY = String.raw`(?=$|\s|[.,;!?)}\]"'”’]+(?=$|\s))`;
7422
7400
  var PREFIX_BOUNDARY = String.raw`(^|[\s(\[{"'“‘])`;
7423
7401
  function escapeRegExp2(value) {
@@ -7526,7 +7504,7 @@ function MessageMentions({
7526
7504
  }).map((segment, segmentIndex) => {
7527
7505
  if (!segment.mention) return segment.text;
7528
7506
  const actionLabel = mentionActionLabel(segment.mention);
7529
- return /* @__PURE__ */ jsx24(
7507
+ return /* @__PURE__ */ jsx22(
7530
7508
  "button",
7531
7509
  {
7532
7510
  type: "button",
@@ -7552,7 +7530,7 @@ function MessageMentions({
7552
7530
  return cloneElement(
7553
7531
  element,
7554
7532
  void 0,
7555
- /* @__PURE__ */ jsx24(
7533
+ /* @__PURE__ */ jsx22(
7556
7534
  MessageMentions,
7557
7535
  {
7558
7536
  catalog,
@@ -7570,19 +7548,19 @@ function MessageMentions({
7570
7548
  return nodes.map(decorate);
7571
7549
  }
7572
7550
  function createMessageMentionMarkdownComponents(catalog, onActivate) {
7573
- const decorate = (children) => /* @__PURE__ */ jsx24(MessageMentions, { catalog, onActivate, children });
7551
+ const decorate = (children) => /* @__PURE__ */ jsx22(MessageMentions, { catalog, onActivate, children });
7574
7552
  const paragraph = ({ node: _node, children, ...props }) => {
7575
7553
  const content = Children.toArray(children).filter((child) => child !== null && child !== "");
7576
7554
  if (content.length === 1 && isValidElement2(content[0])) {
7577
7555
  const child = content[0];
7578
- if (child.props.node?.tagName === "img") return /* @__PURE__ */ jsx24(Fragment9, { children });
7579
- if (child.props.node?.tagName === "code" && "data-block" in child.props) return /* @__PURE__ */ jsx24(Fragment9, { children });
7556
+ if (child.props.node?.tagName === "img") return /* @__PURE__ */ jsx22(Fragment9, { children });
7557
+ if (child.props.node?.tagName === "code" && "data-block" in child.props) return /* @__PURE__ */ jsx22(Fragment9, { children });
7580
7558
  }
7581
- return /* @__PURE__ */ jsx24("p", { ...props, children: decorate(children) });
7559
+ return /* @__PURE__ */ jsx22("p", { ...props, children: decorate(children) });
7582
7560
  };
7583
- const tableHeader = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24("th", { ...props, "data-streamdown": "table-header-cell", className: cn("whitespace-nowrap px-4 py-2 text-left font-semibold text-sm", className), children: decorate(children) });
7584
- const tableCell = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24("td", { ...props, "data-streamdown": "table-cell", className: cn("px-4 py-2 text-sm", className), children: decorate(children) });
7585
- const listItem = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24("li", { ...props, "data-streamdown": "list-item", className: cn("py-1 [&>p]:inline", className), children: decorate(children) });
7561
+ const tableHeader = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx22("th", { ...props, "data-streamdown": "table-header-cell", className: cn("whitespace-nowrap px-4 py-2 text-left font-semibold text-sm", className), children: decorate(children) });
7562
+ const tableCell = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx22("td", { ...props, "data-streamdown": "table-cell", className: cn("px-4 py-2 text-sm", className), children: decorate(children) });
7563
+ const listItem = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx22("li", { ...props, "data-streamdown": "list-item", className: cn("py-1 [&>p]:inline", className), children: decorate(children) });
7586
7564
  const headingClasses = {
7587
7565
  h1: "text-3xl",
7588
7566
  h2: "text-2xl",
@@ -7591,8 +7569,8 @@ function createMessageMentionMarkdownComponents(catalog, onActivate) {
7591
7569
  h5: "text-base",
7592
7570
  h6: "text-sm"
7593
7571
  };
7594
- const heading = (Tag) => ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24(Tag, { ...props, "data-streamdown": `heading-${Tag.slice(1)}`, className: cn("mt-6 mb-2 font-semibold", headingClasses[Tag], className), children: decorate(children) });
7595
- const inlineCode = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24(
7572
+ const heading = (Tag) => ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx22(Tag, { ...props, "data-streamdown": `heading-${Tag.slice(1)}`, className: cn("mt-6 mb-2 font-semibold", headingClasses[Tag], className), children: decorate(children) });
7573
+ const inlineCode = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx22(
7596
7574
  "code",
7597
7575
  {
7598
7576
  ...props,
@@ -7616,7 +7594,7 @@ function createMessageMentionMarkdownComponents(catalog, onActivate) {
7616
7594
  }
7617
7595
 
7618
7596
  // src/front/chat/components/PiTimelineMessage.tsx
7619
- import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
7597
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
7620
7598
  var EMPTY_MENTION_CATALOG = { commands: [], skills: [], files: false };
7621
7599
  var COLLAPSIBLE_TOOL_NAMES = /* @__PURE__ */ new Set([
7622
7600
  "read",
@@ -7632,7 +7610,7 @@ function isCollapsibleTool(part) {
7632
7610
  return part.type === "tool-call" && COLLAPSIBLE_TOOL_NAMES.has(part.toolName);
7633
7611
  }
7634
7612
  function PiTimelineMessage(props) {
7635
- return /* @__PURE__ */ jsx25(ChatMessageContributionBoundary, { message: props.message, children: /* @__PURE__ */ jsx25(DefaultPiTimelineMessage, { ...props }) });
7613
+ return /* @__PURE__ */ jsx23(ChatMessageContributionBoundary, { message: props.message, children: /* @__PURE__ */ jsx23(DefaultPiTimelineMessage, { ...props }) });
7636
7614
  }
7637
7615
  function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts, toolRenderers, mentionCatalog = EMPTY_MENTION_CATALOG, onMentionActivate }) {
7638
7616
  const role = message.role;
@@ -7652,7 +7630,7 @@ function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts,
7652
7630
  ...effectiveMentionCatalog.skills.map((skill) => `skill:${skill.name}:${skill.commandName}`),
7653
7631
  effectiveMentionCatalog.files ? "files:enabled" : "files:disabled"
7654
7632
  ].join("|");
7655
- const mentionActivateRef = useRef10(onMentionActivate);
7633
+ const mentionActivateRef = useRef9(onMentionActivate);
7656
7634
  mentionActivateRef.current = onMentionActivate;
7657
7635
  const activateCurrentMention = useCallback13((mention) => {
7658
7636
  if (mention.kind === "file") {
@@ -7669,7 +7647,7 @@ function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts,
7669
7647
  [activateCurrentMention, effectiveMentionCatalog, mentionSignature, mentionsEnabled]
7670
7648
  );
7671
7649
  const shouldReserveStreamingActions = messageIsStreaming;
7672
- return /* @__PURE__ */ jsxs20(
7650
+ return /* @__PURE__ */ jsxs19(
7673
7651
  Message,
7674
7652
  {
7675
7653
  from: role,
@@ -7678,8 +7656,8 @@ function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts,
7678
7656
  "data-boring-agent-message-role": role,
7679
7657
  "data-boring-agent-message-status": message.status,
7680
7658
  children: [
7681
- /* @__PURE__ */ jsxs20(MessageContent, { children: [
7682
- fileParts.length > 0 ? /* @__PURE__ */ jsx25(
7659
+ /* @__PURE__ */ jsxs19(MessageContent, { children: [
7660
+ fileParts.length > 0 ? /* @__PURE__ */ jsx23(
7683
7661
  Attachments,
7684
7662
  {
7685
7663
  variant: role === "user" ? "inline" : "list",
@@ -7704,7 +7682,7 @@ function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts,
7704
7682
  event.preventDefault();
7705
7683
  openAttachment();
7706
7684
  };
7707
- return /* @__PURE__ */ jsxs20(
7685
+ return /* @__PURE__ */ jsxs19(
7708
7686
  Attachment,
7709
7687
  {
7710
7688
  data: toAttachmentData(file, `file-${message.id}-${index}`),
@@ -7718,8 +7696,8 @@ function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts,
7718
7696
  onKeyDown: openAttachmentFromKeyboard
7719
7697
  } : void 0,
7720
7698
  children: [
7721
- /* @__PURE__ */ jsx25(AttachmentPreview, { className: role === "user" ? "!size-5 shrink-0 rounded-[var(--radius-sm)]" : "size-10 shrink-0 rounded-[var(--radius-md)]" }),
7722
- /* @__PURE__ */ jsx25(AttachmentInfo, { className: role === "user" ? "min-w-0 max-w-[220px] flex-1 text-[12px]" : "min-w-0 flex-1" })
7699
+ /* @__PURE__ */ jsx23(AttachmentPreview, { className: role === "user" ? "!size-5 shrink-0 rounded-[var(--radius-sm)]" : "size-10 shrink-0 rounded-[var(--radius-md)]" }),
7700
+ /* @__PURE__ */ jsx23(AttachmentInfo, { className: role === "user" ? "min-w-0 max-w-[220px] flex-1 text-[12px]" : "min-w-0 flex-1" })
7723
7701
  ]
7724
7702
  },
7725
7703
  `file-${message.id}-${index}`
@@ -7729,7 +7707,7 @@ function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts,
7729
7707
  ) : null,
7730
7708
  finalParts.map((item, index) => {
7731
7709
  if (item.kind === "reasoning") {
7732
- return /* @__PURE__ */ jsx25(
7710
+ return /* @__PURE__ */ jsx23(
7733
7711
  TimelineReasoningPart,
7734
7712
  {
7735
7713
  item,
@@ -7739,15 +7717,15 @@ function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts,
7739
7717
  );
7740
7718
  }
7741
7719
  if (item.kind === "tool-group") {
7742
- return /* @__PURE__ */ jsx25("div", { "data-boring-agent-part": "message-tools", children: /* @__PURE__ */ jsx25(ToolCallGroup, { tools: item.tools, mergedToolRenderers: toolRenderers }) }, item.key);
7720
+ return /* @__PURE__ */ jsx23("div", { "data-boring-agent-part": "message-tools", children: /* @__PURE__ */ jsx23(ToolCallGroup, { tools: item.tools, mergedToolRenderers: toolRenderers }) }, item.key);
7743
7721
  }
7744
7722
  if (item.kind === "tool-plain") {
7745
- return /* @__PURE__ */ jsx25("div", { "data-boring-agent-part": "message-tools", children: /* @__PURE__ */ jsx25(PlainToolCard, { part: item.part, renderers: toolRenderers }) }, item.key);
7723
+ return /* @__PURE__ */ jsx23("div", { "data-boring-agent-part": "message-tools", children: /* @__PURE__ */ jsx23(PlainToolCard, { part: item.part, renderers: toolRenderers }) }, item.key);
7746
7724
  }
7747
7725
  if (item.part.type === "text") {
7748
7726
  const text = textForMessageDisplay(item.part.text, role);
7749
7727
  if (!text) return null;
7750
- return /* @__PURE__ */ jsx25("div", { "data-boring-agent-part": "message-text", children: /* @__PURE__ */ jsx25(
7728
+ return /* @__PURE__ */ jsx23("div", { "data-boring-agent-part": "message-text", children: /* @__PURE__ */ jsx23(
7751
7729
  MessageResponse,
7752
7730
  {
7753
7731
  components: mentionMarkdownComponents,
@@ -7759,12 +7737,12 @@ function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts,
7759
7737
  ) }, item.key);
7760
7738
  }
7761
7739
  if (item.part.type === "notice") {
7762
- return /* @__PURE__ */ jsx25(NoticeBubble, { level: item.part.level, text: item.part.text }, item.key);
7740
+ return /* @__PURE__ */ jsx23(NoticeBubble, { level: item.part.level, text: item.part.text }, item.key);
7763
7741
  }
7764
7742
  return null;
7765
7743
  })
7766
7744
  ] }),
7767
- isAssistant && (textParts.length > 0 || shouldReserveStreamingActions) ? /* @__PURE__ */ jsx25(
7745
+ isAssistant && (textParts.length > 0 || shouldReserveStreamingActions) ? /* @__PURE__ */ jsx23(
7768
7746
  MessageActionsBar,
7769
7747
  {
7770
7748
  text: textParts.map((part) => part.text).join("\n\n"),
@@ -7789,7 +7767,7 @@ function TimelineReasoningPart({ item, showThoughts }) {
7789
7767
  event.preventDefault();
7790
7768
  setManualOpen((open) => !(open ?? showThoughts));
7791
7769
  }, [showThoughts]);
7792
- return /* @__PURE__ */ jsxs20(
7770
+ return /* @__PURE__ */ jsxs19(
7793
7771
  Reasoning,
7794
7772
  {
7795
7773
  "data-boring-agent-part": "message-reasoning",
@@ -7799,15 +7777,15 @@ function TimelineReasoningPart({ item, showThoughts }) {
7799
7777
  onOpenChange: handleOpenChange,
7800
7778
  autoClose: false,
7801
7779
  children: [
7802
- /* @__PURE__ */ jsx25(
7780
+ /* @__PURE__ */ jsx23(
7803
7781
  ReasoningTrigger,
7804
7782
  {
7805
7783
  className: "mb-1 w-fit rounded-[var(--radius-sm)] px-0 py-0 !text-xs !font-normal !text-muted-foreground/75 hover:bg-transparent hover:!text-muted-foreground/75 [&_svg]:!text-muted-foreground/75",
7806
- getThinkingMessage: () => /* @__PURE__ */ jsx25("span", { children: "Reasoning" }),
7784
+ getThinkingMessage: () => /* @__PURE__ */ jsx23("span", { children: "Reasoning" }),
7807
7785
  onClick: toggleManualOpen
7808
7786
  }
7809
7787
  ),
7810
- /* @__PURE__ */ jsx25(ReasoningContent, { children: item.text })
7788
+ /* @__PURE__ */ jsx23(ReasoningContent, { children: item.text })
7811
7789
  ]
7812
7790
  }
7813
7791
  );
@@ -7816,7 +7794,7 @@ function PlainToolCard({ part, renderers }) {
7816
7794
  const toolPart = toToolPart(part);
7817
7795
  if (!toolPart) return null;
7818
7796
  const { renderer, part: resolved, resolution } = resolveToolRendererForPart(toolPart, renderers);
7819
- return /* @__PURE__ */ jsx25(
7797
+ return /* @__PURE__ */ jsx23(
7820
7798
  "div",
7821
7799
  {
7822
7800
  "data-tool-call-id": resolved.toolCallId,
@@ -7874,13 +7852,13 @@ function codeFilenameForPart(parts, index) {
7874
7852
  return typeof path === "string" && path.trim() ? path : void 0;
7875
7853
  }
7876
7854
  function NoticeBubble({ level, text }) {
7877
- return /* @__PURE__ */ jsx25(
7855
+ return /* @__PURE__ */ jsx23(
7878
7856
  "div",
7879
7857
  {
7880
7858
  "data-boring-agent-part": "message-notice",
7881
7859
  "data-notice-level": level,
7882
7860
  className: noticeSurfaceClass(level, "text-xs"),
7883
- children: /* @__PURE__ */ jsx25("div", { className: noticeTextClass(), children: text })
7861
+ children: /* @__PURE__ */ jsx23("div", { className: noticeTextClass(), children: text })
7884
7862
  }
7885
7863
  );
7886
7864
  }
@@ -7959,7 +7937,7 @@ function MessageActionsBar({
7959
7937
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--accent)]/40"
7960
7938
  );
7961
7939
  const hiddenActionProps = visible ? {} : { tabIndex: -1 };
7962
- return /* @__PURE__ */ jsx25(
7940
+ return /* @__PURE__ */ jsx23(
7963
7941
  "div",
7964
7942
  {
7965
7943
  "aria-hidden": !visible,
@@ -7967,8 +7945,8 @@ function MessageActionsBar({
7967
7945
  "flex min-h-8 items-center gap-1 -mt-1 text-xs text-muted-foreground transition-opacity duration-200",
7968
7946
  visible ? "opacity-100" : "pointer-events-none opacity-0"
7969
7947
  ),
7970
- children: /* @__PURE__ */ jsx25(
7971
- Button11,
7948
+ children: /* @__PURE__ */ jsx23(
7949
+ Button10,
7972
7950
  {
7973
7951
  type: "button",
7974
7952
  variant: "ghost",
@@ -7978,7 +7956,7 @@ function MessageActionsBar({
7978
7956
  "aria-label": copied ? "Copied" : "Copy message",
7979
7957
  title: copied ? "Copied" : "Copy",
7980
7958
  ...hiddenActionProps,
7981
- children: copied ? /* @__PURE__ */ jsx25(CheckIcon2, { className: "h-3.5 w-3.5 text-[color:var(--accent)]" }) : /* @__PURE__ */ jsx25(CopyIcon3, { className: "h-3.5 w-3.5" })
7959
+ children: copied ? /* @__PURE__ */ jsx23(CheckIcon2, { className: "h-3.5 w-3.5 text-[color:var(--accent)]" }) : /* @__PURE__ */ jsx23(CopyIcon3, { className: "h-3.5 w-3.5" })
7982
7960
  }
7983
7961
  )
7984
7962
  }
@@ -7999,7 +7977,7 @@ function partKey(messageId, part, index) {
7999
7977
  }
8000
7978
 
8001
7979
  // src/front/chat/components/PiConversationSurface.tsx
8002
- import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
7980
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
8003
7981
  var TRANSCRIPT_WINDOW = 60;
8004
7982
  var TRANSCRIPT_WINDOW_STEP = 40;
8005
7983
  var LOAD_OLDER_THRESHOLD_PX = 320;
@@ -8037,7 +8015,7 @@ function PiConversationSurface({
8037
8015
  const loadOlder = useCallback14(() => {
8038
8016
  setVisibleCount((count) => count + TRANSCRIPT_WINDOW_STEP);
8039
8017
  }, []);
8040
- return /* @__PURE__ */ jsxs21(
8018
+ return /* @__PURE__ */ jsxs20(
8041
8019
  Conversation,
8042
8020
  {
8043
8021
  className: emptyHero ? cn("flex-none", runtimeNotices.length > 0 ? "max-h-[45vh]" : "max-h-[20vh]") : "flex-1",
@@ -8045,13 +8023,13 @@ function PiConversationSurface({
8045
8023
  "aria-live": "polite",
8046
8024
  onScrollToBottomReady,
8047
8025
  children: [
8048
- /* @__PURE__ */ jsxs21(ConversationContent, { className: cn(
8026
+ /* @__PURE__ */ jsxs20(ConversationContent, { className: cn(
8049
8027
  "mx-auto flex w-full flex-col gap-6",
8050
8028
  chrome ? "max-w-3xl px-6 py-8" : "max-w-[680px] px-4 py-4",
8051
8029
  emptyHero && "py-4 text-center"
8052
8030
  ), children: [
8053
- messages.length === 0 && emptyStateHydrating && !terminalError ? /* @__PURE__ */ jsx26(ConversationHistoryLoadingState, {}) : null,
8054
- messages.length === 0 && !emptyStateHydrating && !terminalError ? /* @__PURE__ */ jsx26(
8031
+ messages.length === 0 && emptyStateHydrating && !terminalError ? /* @__PURE__ */ jsx24(ConversationHistoryLoadingState, {}) : null,
8032
+ messages.length === 0 && !emptyStateHydrating && !terminalError ? /* @__PURE__ */ jsx24(
8055
8033
  ChatEmptyState,
8056
8034
  {
8057
8035
  eyebrow: emptyState?.eyebrow,
@@ -8069,8 +8047,8 @@ function PiConversationSurface({
8069
8047
  }
8070
8048
  }
8071
8049
  ) : null,
8072
- hasOlder ? /* @__PURE__ */ jsx26(TranscriptHistoryLoader, { olderCount, onLoadOlder: loadOlder }) : null,
8073
- visibleItems.map(({ message, key }, index) => /* @__PURE__ */ jsx26(
8050
+ hasOlder ? /* @__PURE__ */ jsx24(TranscriptHistoryLoader, { olderCount, onLoadOlder: loadOlder }) : null,
8051
+ visibleItems.map(({ message, key }, index) => /* @__PURE__ */ jsx24(
8074
8052
  PiTimelineMessage,
8075
8053
  {
8076
8054
  message,
@@ -8083,16 +8061,16 @@ function PiConversationSurface({
8083
8061
  },
8084
8062
  key
8085
8063
  )),
8086
- /* @__PURE__ */ jsx26(RuntimeNoticeMessages, { notices: runtimeNotices, onDismiss: onDismissNotice, renderAction: renderNoticeAction, historyEmpty })
8064
+ /* @__PURE__ */ jsx24(RuntimeNoticeMessages, { notices: runtimeNotices, onDismiss: onDismissNotice, renderAction: renderNoticeAction, historyEmpty })
8087
8065
  ] }),
8088
- /* @__PURE__ */ jsx26(ConversationScrollButton, {})
8066
+ /* @__PURE__ */ jsx24(ConversationScrollButton, {})
8089
8067
  ]
8090
8068
  }
8091
8069
  );
8092
8070
  }
8093
8071
  function ConversationHistoryLoadingState() {
8094
8072
  const skeletonClassName = "motion-reduce:animate-none";
8095
- return /* @__PURE__ */ jsxs21(
8073
+ return /* @__PURE__ */ jsxs20(
8096
8074
  "div",
8097
8075
  {
8098
8076
  role: "status",
@@ -8101,21 +8079,21 @@ function ConversationHistoryLoadingState() {
8101
8079
  "data-boring-agent-part": "chat-history-loading",
8102
8080
  className: "flex flex-col gap-7 py-4",
8103
8081
  children: [
8104
- /* @__PURE__ */ jsxs21("div", { "aria-hidden": "true", className: "flex items-start gap-3", children: [
8105
- /* @__PURE__ */ jsx26(Skeleton, { className: cn("mt-0.5 size-7 shrink-0 rounded-lg", skeletonClassName) }),
8106
- /* @__PURE__ */ jsxs21("div", { className: "flex min-w-0 flex-1 flex-col gap-2.5", children: [
8107
- /* @__PURE__ */ jsx26(Skeleton, { className: cn("h-3 w-24 rounded-sm", skeletonClassName) }),
8108
- /* @__PURE__ */ jsx26(Skeleton, { className: cn("h-3 w-full rounded-sm", skeletonClassName) }),
8109
- /* @__PURE__ */ jsx26(Skeleton, { className: cn("h-3 w-4/5 rounded-sm", skeletonClassName) })
8082
+ /* @__PURE__ */ jsxs20("div", { "aria-hidden": "true", className: "flex items-start gap-3", children: [
8083
+ /* @__PURE__ */ jsx24(Skeleton, { className: cn("mt-0.5 size-7 shrink-0 rounded-lg", skeletonClassName) }),
8084
+ /* @__PURE__ */ jsxs20("div", { className: "flex min-w-0 flex-1 flex-col gap-2.5", children: [
8085
+ /* @__PURE__ */ jsx24(Skeleton, { className: cn("h-3 w-24 rounded-sm", skeletonClassName) }),
8086
+ /* @__PURE__ */ jsx24(Skeleton, { className: cn("h-3 w-full rounded-sm", skeletonClassName) }),
8087
+ /* @__PURE__ */ jsx24(Skeleton, { className: cn("h-3 w-4/5 rounded-sm", skeletonClassName) })
8110
8088
  ] })
8111
8089
  ] }),
8112
- /* @__PURE__ */ jsx26("div", { "aria-hidden": "true", className: "flex justify-end", children: /* @__PURE__ */ jsx26(Skeleton, { className: cn("h-11 w-[min(72%,30rem)] rounded-xl", skeletonClassName) }) }),
8113
- /* @__PURE__ */ jsxs21("div", { "aria-hidden": "true", className: "flex items-start gap-3", children: [
8114
- /* @__PURE__ */ jsx26(Skeleton, { className: cn("mt-0.5 size-7 shrink-0 rounded-lg", skeletonClassName) }),
8115
- /* @__PURE__ */ jsxs21("div", { className: "flex min-w-0 flex-1 flex-col gap-3", children: [
8116
- /* @__PURE__ */ jsx26(Skeleton, { className: cn("h-3 w-20 rounded-sm", skeletonClassName) }),
8117
- /* @__PURE__ */ jsx26(Skeleton, { className: cn("h-20 w-full rounded-lg", skeletonClassName) }),
8118
- /* @__PURE__ */ jsx26(Skeleton, { className: cn("h-3 w-3/5 rounded-sm", skeletonClassName) })
8090
+ /* @__PURE__ */ jsx24("div", { "aria-hidden": "true", className: "flex justify-end", children: /* @__PURE__ */ jsx24(Skeleton, { className: cn("h-11 w-[min(72%,30rem)] rounded-xl", skeletonClassName) }) }),
8091
+ /* @__PURE__ */ jsxs20("div", { "aria-hidden": "true", className: "flex items-start gap-3", children: [
8092
+ /* @__PURE__ */ jsx24(Skeleton, { className: cn("mt-0.5 size-7 shrink-0 rounded-lg", skeletonClassName) }),
8093
+ /* @__PURE__ */ jsxs20("div", { className: "flex min-w-0 flex-1 flex-col gap-3", children: [
8094
+ /* @__PURE__ */ jsx24(Skeleton, { className: cn("h-3 w-20 rounded-sm", skeletonClassName) }),
8095
+ /* @__PURE__ */ jsx24(Skeleton, { className: cn("h-20 w-full rounded-lg", skeletonClassName) }),
8096
+ /* @__PURE__ */ jsx24(Skeleton, { className: cn("h-3 w-3/5 rounded-sm", skeletonClassName) })
8119
8097
  ] })
8120
8098
  ] })
8121
8099
  ]
@@ -8124,8 +8102,8 @@ function ConversationHistoryLoadingState() {
8124
8102
  }
8125
8103
  function TranscriptHistoryLoader({ olderCount, onLoadOlder }) {
8126
8104
  const { scrollRef } = useStickToBottomContext2();
8127
- const pendingAnchor = useRef11(null);
8128
- const armed = useRef11(true);
8105
+ const pendingAnchor = useRef10(null);
8106
+ const armed = useRef10(true);
8129
8107
  useEffect14(() => {
8130
8108
  const el = scrollRef.current;
8131
8109
  if (!el) return;
@@ -8149,7 +8127,7 @@ function TranscriptHistoryLoader({ olderCount, onLoadOlder }) {
8149
8127
  }
8150
8128
  if (el.scrollTop > LOAD_OLDER_THRESHOLD_PX) armed.current = true;
8151
8129
  });
8152
- return /* @__PURE__ */ jsx26("div", { className: "flex justify-center", "data-boring-agent-part": "transcript-load-older", children: /* @__PURE__ */ jsxs21(
8130
+ return /* @__PURE__ */ jsx24("div", { className: "flex justify-center", "data-boring-agent-part": "transcript-load-older", children: /* @__PURE__ */ jsxs20(
8153
8131
  "button",
8154
8132
  {
8155
8133
  type: "button",
@@ -8190,10 +8168,10 @@ import { useCallback as useCallback16, useLayoutEffect as useLayoutEffect3 } fro
8190
8168
  import { motion as motion2, useReducedMotion } from "motion/react";
8191
8169
 
8192
8170
  // src/front/composer/PluginUpdateStatus.tsx
8193
- import { useEffect as useEffect15, useRef as useRef12 } from "react";
8171
+ import { useEffect as useEffect15, useRef as useRef11 } from "react";
8194
8172
 
8195
8173
  // src/front/composer/ComposerStatusBanner.tsx
8196
- import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
8174
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
8197
8175
  function ComposerStatusBanner({
8198
8176
  tone,
8199
8177
  dataAttribute,
@@ -8210,7 +8188,7 @@ function ComposerStatusBanner({
8210
8188
  }) {
8211
8189
  const toneAttr = { [dataAttribute]: tone };
8212
8190
  if (tone === "running") {
8213
- return /* @__PURE__ */ jsxs22(
8191
+ return /* @__PURE__ */ jsxs21(
8214
8192
  "div",
8215
8193
  {
8216
8194
  ...toneAttr,
@@ -8222,14 +8200,14 @@ function ComposerStatusBanner({
8222
8200
  maxWidthClassName
8223
8201
  ),
8224
8202
  children: [
8225
- /* @__PURE__ */ jsx27("span", { className: "inline-block h-2 w-2 animate-pulse rounded-full bg-accent", "aria-hidden": "true" }),
8226
- /* @__PURE__ */ jsx27("span", { children: runningContent })
8203
+ /* @__PURE__ */ jsx25("span", { className: "inline-block h-2 w-2 animate-pulse rounded-full bg-accent", "aria-hidden": "true" }),
8204
+ /* @__PURE__ */ jsx25("span", { children: runningContent })
8227
8205
  ]
8228
8206
  }
8229
8207
  );
8230
8208
  }
8231
8209
  if (tone === "success") {
8232
- return /* @__PURE__ */ jsxs22(
8210
+ return /* @__PURE__ */ jsxs21(
8233
8211
  "div",
8234
8212
  {
8235
8213
  ...toneAttr,
@@ -8241,13 +8219,13 @@ function ComposerStatusBanner({
8241
8219
  maxWidthClassName
8242
8220
  ),
8243
8221
  children: [
8244
- /* @__PURE__ */ jsxs22("div", { className: "flex items-start gap-2", children: [
8245
- /* @__PURE__ */ jsx27("span", { className: "mt-0.5 text-[oklch(0.45_0.13_148)]", "aria-hidden": "true", children: "\u2713" }),
8246
- /* @__PURE__ */ jsxs22("span", { className: "min-w-0 flex-1", children: [
8247
- /* @__PURE__ */ jsx27("span", { className: "block font-medium leading-5", children: title }),
8248
- detail ? /* @__PURE__ */ jsx27("span", { className: "block leading-4 text-muted-foreground", children: detail }) : null
8222
+ /* @__PURE__ */ jsxs21("div", { className: "flex items-start gap-2", children: [
8223
+ /* @__PURE__ */ jsx25("span", { className: "mt-0.5 text-[oklch(0.45_0.13_148)]", "aria-hidden": "true", children: "\u2713" }),
8224
+ /* @__PURE__ */ jsxs21("span", { className: "min-w-0 flex-1", children: [
8225
+ /* @__PURE__ */ jsx25("span", { className: "block font-medium leading-5", children: title }),
8226
+ detail ? /* @__PURE__ */ jsx25("span", { className: "block leading-4 text-muted-foreground", children: detail }) : null
8249
8227
  ] }),
8250
- onDismiss ? /* @__PURE__ */ jsx27(
8228
+ onDismiss ? /* @__PURE__ */ jsx25(
8251
8229
  "button",
8252
8230
  {
8253
8231
  type: "button",
@@ -8263,7 +8241,7 @@ function ComposerStatusBanner({
8263
8241
  }
8264
8242
  );
8265
8243
  }
8266
- return /* @__PURE__ */ jsxs22(
8244
+ return /* @__PURE__ */ jsxs21(
8267
8245
  "div",
8268
8246
  {
8269
8247
  ...toneAttr,
@@ -8275,10 +8253,10 @@ function ComposerStatusBanner({
8275
8253
  maxWidthClassName
8276
8254
  ),
8277
8255
  children: [
8278
- /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
8279
- /* @__PURE__ */ jsx27("span", { className: "text-destructive", "aria-hidden": "true", children: "\u26A0" }),
8280
- /* @__PURE__ */ jsx27("span", { className: "flex-1 font-medium", children: title }),
8281
- onRetry ? /* @__PURE__ */ jsx27(
8256
+ /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-2", children: [
8257
+ /* @__PURE__ */ jsx25("span", { className: "text-destructive", "aria-hidden": "true", children: "\u26A0" }),
8258
+ /* @__PURE__ */ jsx25("span", { className: "flex-1 font-medium", children: title }),
8259
+ onRetry ? /* @__PURE__ */ jsx25(
8282
8260
  "button",
8283
8261
  {
8284
8262
  type: "button",
@@ -8287,7 +8265,7 @@ function ComposerStatusBanner({
8287
8265
  children: retryLabel
8288
8266
  }
8289
8267
  ) : null,
8290
- onDismiss ? /* @__PURE__ */ jsx27(
8268
+ onDismiss ? /* @__PURE__ */ jsx25(
8291
8269
  "button",
8292
8270
  {
8293
8271
  type: "button",
@@ -8298,14 +8276,14 @@ function ComposerStatusBanner({
8298
8276
  }
8299
8277
  ) : null
8300
8278
  ] }),
8301
- message ? /* @__PURE__ */ jsx27("pre", { className: "mt-2 whitespace-pre-wrap break-words text-[11px] text-destructive/90", children: message }) : null
8279
+ message ? /* @__PURE__ */ jsx25("pre", { className: "mt-2 whitespace-pre-wrap break-words text-[11px] text-destructive/90", children: message }) : null
8302
8280
  ]
8303
8281
  }
8304
8282
  );
8305
8283
  }
8306
8284
 
8307
8285
  // src/front/composer/PluginUpdateStatus.tsx
8308
- import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
8286
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
8309
8287
  function PluginUpdateStatus({
8310
8288
  state,
8311
8289
  onDismiss,
@@ -8313,7 +8291,7 @@ function PluginUpdateStatus({
8313
8291
  successAutoDismissMs = 1400,
8314
8292
  maxWidthClassName = "max-w-3xl"
8315
8293
  }) {
8316
- const onDismissRef = useRef12(onDismiss);
8294
+ const onDismissRef = useRef11(onDismiss);
8317
8295
  useEffect15(() => {
8318
8296
  onDismissRef.current = onDismiss;
8319
8297
  }, [onDismiss]);
@@ -8327,7 +8305,7 @@ function PluginUpdateStatus({
8327
8305
  }, [state?.kind, successDismissKey, successAutoDismissMs]);
8328
8306
  if (!state) return null;
8329
8307
  if (state.kind === "running") {
8330
- return /* @__PURE__ */ jsx28(
8308
+ return /* @__PURE__ */ jsx26(
8331
8309
  ComposerStatusBanner,
8332
8310
  {
8333
8311
  tone: "running",
@@ -8344,7 +8322,7 @@ function PluginUpdateStatus({
8344
8322
  const hasWarningsOrDiagnostics = warnings.length > 0 || diagnostics.length > 0;
8345
8323
  const title = state.reloaded ? hasWarningsOrDiagnostics ? "Reload finished with warnings" : "Reload complete" : "Reload queued";
8346
8324
  const detail = state.reloaded ? hasWarningsOrDiagnostics ? "Some extension changes need attention." : frontEvents.length > 0 ? `${frontEvents.length} extension module${frontEvents.length === 1 ? "" : "s"} refreshed. Changes are live.` : "Changes are live." : void 0;
8347
- return /* @__PURE__ */ jsxs23(
8325
+ return /* @__PURE__ */ jsxs22(
8348
8326
  ComposerStatusBanner,
8349
8327
  {
8350
8328
  tone: "success",
@@ -8355,7 +8333,7 @@ function PluginUpdateStatus({
8355
8333
  onDismiss,
8356
8334
  dismissAriaLabel: "Dismiss plugin update status",
8357
8335
  children: [
8358
- diagnostics.length > 0 ? /* @__PURE__ */ jsxs23(
8336
+ diagnostics.length > 0 ? /* @__PURE__ */ jsxs22(
8359
8337
  "div",
8360
8338
  {
8361
8339
  "data-boring-plugin-update-diagnostics": "",
@@ -8364,24 +8342,24 @@ function PluginUpdateStatus({
8364
8342
  "px-2 py-1.5 text-[11px] text-foreground"
8365
8343
  ),
8366
8344
  children: [
8367
- /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-1.5 font-medium text-[oklch(0.48_0.15_60)]", children: [
8368
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u26A0" }),
8369
- /* @__PURE__ */ jsxs23("span", { children: [
8345
+ /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1.5 font-medium text-[oklch(0.48_0.15_60)]", children: [
8346
+ /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", children: "\u26A0" }),
8347
+ /* @__PURE__ */ jsxs22("span", { children: [
8370
8348
  "Reload diagnostics for ",
8371
8349
  diagnostics.length,
8372
8350
  " extension",
8373
8351
  diagnostics.length === 1 ? "" : "s"
8374
8352
  ] })
8375
8353
  ] }),
8376
- /* @__PURE__ */ jsx28("ul", { className: "mt-1 ml-4 list-disc text-foreground/85", children: diagnostics.map((diagnostic, index) => /* @__PURE__ */ jsxs23("li", { children: [
8377
- /* @__PURE__ */ jsx28("code", { className: "font-mono text-[10.5px]", children: diagnostic.pluginId ?? diagnostic.source ?? "plugin" }),
8354
+ /* @__PURE__ */ jsx26("ul", { className: "mt-1 ml-4 list-disc text-foreground/85", children: diagnostics.map((diagnostic, index) => /* @__PURE__ */ jsxs22("li", { children: [
8355
+ /* @__PURE__ */ jsx26("code", { className: "font-mono text-[10.5px]", children: diagnostic.pluginId ?? diagnostic.source ?? "plugin" }),
8378
8356
  " \u2014 ",
8379
8357
  diagnostic.message ?? "reload diagnostic"
8380
8358
  ] }, `${diagnostic.pluginId ?? diagnostic.source ?? "plugin"}-${index}`)) })
8381
8359
  ]
8382
8360
  }
8383
8361
  ) : null,
8384
- warnings.length > 0 ? /* @__PURE__ */ jsxs23(
8362
+ warnings.length > 0 ? /* @__PURE__ */ jsxs22(
8385
8363
  "div",
8386
8364
  {
8387
8365
  "data-boring-plugin-update-restart-warning": "",
@@ -8390,21 +8368,21 @@ function PluginUpdateStatus({
8390
8368
  "px-2 py-1.5 text-[11px] text-foreground"
8391
8369
  ),
8392
8370
  children: [
8393
- /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-1.5 font-medium text-[oklch(0.48_0.15_60)]", children: [
8394
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u26A0" }),
8395
- /* @__PURE__ */ jsxs23("span", { children: [
8371
+ /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1.5 font-medium text-[oklch(0.48_0.15_60)]", children: [
8372
+ /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", children: "\u26A0" }),
8373
+ /* @__PURE__ */ jsxs22("span", { children: [
8396
8374
  "Restart needed for ",
8397
8375
  warnings.length,
8398
8376
  " extension",
8399
8377
  warnings.length === 1 ? "" : "s"
8400
8378
  ] })
8401
8379
  ] }),
8402
- /* @__PURE__ */ jsx28("ul", { className: "mt-1 ml-4 list-disc text-foreground/85", children: warnings.map((w) => /* @__PURE__ */ jsxs23("li", { children: [
8403
- /* @__PURE__ */ jsx28("code", { className: "font-mono text-[10.5px]", children: w.id }),
8380
+ /* @__PURE__ */ jsx26("ul", { className: "mt-1 ml-4 list-disc text-foreground/85", children: warnings.map((w) => /* @__PURE__ */ jsxs22("li", { children: [
8381
+ /* @__PURE__ */ jsx26("code", { className: "font-mono text-[10.5px]", children: w.id }),
8404
8382
  " \u2014 ",
8405
8383
  w.surfaces.join(" + ")
8406
8384
  ] }, w.id)) }),
8407
- /* @__PURE__ */ jsx28("p", { className: "mt-1 text-foreground/70", children: "The interface reloaded successfully, but routes and tools were wired at boot. Restart the workspace process to pick up the new code." })
8385
+ /* @__PURE__ */ jsx26("p", { className: "mt-1 text-foreground/70", children: "The interface reloaded successfully, but routes and tools were wired at boot. Restart the workspace process to pick up the new code." })
8408
8386
  ]
8409
8387
  }
8410
8388
  ) : null
@@ -8412,7 +8390,7 @@ function PluginUpdateStatus({
8412
8390
  }
8413
8391
  );
8414
8392
  }
8415
- return /* @__PURE__ */ jsx28(
8393
+ return /* @__PURE__ */ jsx26(
8416
8394
  ComposerStatusBanner,
8417
8395
  {
8418
8396
  tone: "error",
@@ -8429,15 +8407,15 @@ function PluginUpdateStatus({
8429
8407
  }
8430
8408
 
8431
8409
  // src/front/composer/CommandRunStatus.tsx
8432
- import { useEffect as useEffect16, useRef as useRef13 } from "react";
8433
- import { Fragment as Fragment10, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
8410
+ import { useEffect as useEffect16, useRef as useRef12 } from "react";
8411
+ import { Fragment as Fragment10, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
8434
8412
  function CommandRunStatus({
8435
8413
  state,
8436
8414
  onDismiss,
8437
8415
  successAutoDismissMs = 1400,
8438
8416
  maxWidthClassName = "max-w-3xl"
8439
8417
  }) {
8440
- const onDismissRef = useRef13(onDismiss);
8418
+ const onDismissRef = useRef12(onDismiss);
8441
8419
  useEffect16(() => {
8442
8420
  onDismissRef.current = onDismiss;
8443
8421
  }, [onDismiss]);
@@ -8449,15 +8427,15 @@ function CommandRunStatus({
8449
8427
  }, [state?.kind, successKey, successAutoDismissMs]);
8450
8428
  if (!state) return null;
8451
8429
  if (state.kind === "running") {
8452
- return /* @__PURE__ */ jsx29(
8430
+ return /* @__PURE__ */ jsx27(
8453
8431
  ComposerStatusBanner,
8454
8432
  {
8455
8433
  tone: "running",
8456
8434
  dataAttribute: "data-boring-command-run",
8457
8435
  maxWidthClassName,
8458
- runningContent: state.command ? /* @__PURE__ */ jsxs24(Fragment10, { children: [
8436
+ runningContent: state.command ? /* @__PURE__ */ jsxs23(Fragment10, { children: [
8459
8437
  " Running ",
8460
- /* @__PURE__ */ jsxs24("code", { className: "font-mono", children: [
8438
+ /* @__PURE__ */ jsxs23("code", { className: "font-mono", children: [
8461
8439
  "/",
8462
8440
  state.command
8463
8441
  ] }),
@@ -8467,15 +8445,15 @@ function CommandRunStatus({
8467
8445
  );
8468
8446
  }
8469
8447
  if (state.kind === "success") {
8470
- return /* @__PURE__ */ jsx29(
8448
+ return /* @__PURE__ */ jsx27(
8471
8449
  ComposerStatusBanner,
8472
8450
  {
8473
8451
  tone: "success",
8474
8452
  dataAttribute: "data-boring-command-run",
8475
8453
  maxWidthClassName,
8476
- title: state.command ? /* @__PURE__ */ jsxs24(Fragment10, { children: [
8454
+ title: state.command ? /* @__PURE__ */ jsxs23(Fragment10, { children: [
8477
8455
  " Ran ",
8478
- /* @__PURE__ */ jsxs24("code", { className: "font-mono", children: [
8456
+ /* @__PURE__ */ jsxs23("code", { className: "font-mono", children: [
8479
8457
  "/",
8480
8458
  state.command
8481
8459
  ] }),
@@ -8487,15 +8465,15 @@ function CommandRunStatus({
8487
8465
  }
8488
8466
  );
8489
8467
  }
8490
- return /* @__PURE__ */ jsx29(
8468
+ return /* @__PURE__ */ jsx27(
8491
8469
  ComposerStatusBanner,
8492
8470
  {
8493
8471
  tone: "error",
8494
8472
  dataAttribute: "data-boring-command-run",
8495
8473
  maxWidthClassName,
8496
- title: state.command ? /* @__PURE__ */ jsxs24(Fragment10, { children: [
8474
+ title: state.command ? /* @__PURE__ */ jsxs23(Fragment10, { children: [
8497
8475
  " ",
8498
- /* @__PURE__ */ jsxs24("code", { className: "font-mono", children: [
8476
+ /* @__PURE__ */ jsxs23("code", { className: "font-mono", children: [
8499
8477
  "/",
8500
8478
  state.command
8501
8479
  ] }),
@@ -8509,7 +8487,7 @@ function CommandRunStatus({
8509
8487
  }
8510
8488
 
8511
8489
  // src/front/chatPanelComposerControls.tsx
8512
- import { forwardRef, useEffect as useEffect17, useRef as useRef14, useState as useState16 } from "react";
8490
+ import { forwardRef, useEffect as useEffect17, useRef as useRef13, useState as useState16 } from "react";
8513
8491
  import { CheckIcon as CheckIcon3, ChevronDownIcon as ChevronDownIcon5 } from "lucide-react";
8514
8492
  import {
8515
8493
  Command,
@@ -8543,7 +8521,7 @@ function displayProviderLabel(provider) {
8543
8521
  }
8544
8522
 
8545
8523
  // src/front/chatPanelComposerControls.tsx
8546
- import { Fragment as Fragment11, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
8524
+ import { Fragment as Fragment11, jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
8547
8525
  var composerActionClass = cn(
8548
8526
  "inline-flex h-8 items-center justify-center gap-1.5 rounded-[var(--radius-md)] border-0 bg-transparent",
8549
8527
  "text-muted-foreground shadow-none transition-colors motion-reduce:transition-none",
@@ -8611,7 +8589,7 @@ function useDismissOnOutsidePointer(ref, onClose) {
8611
8589
  }
8612
8590
  function ThinkingLevelGlyph({ level }) {
8613
8591
  const lit = level === "off" ? 0 : level === "low" ? 1 : level === "medium" ? 2 : 3;
8614
- return /* @__PURE__ */ jsx30(
8592
+ return /* @__PURE__ */ jsx28(
8615
8593
  "svg",
8616
8594
  {
8617
8595
  "aria-hidden": "true",
@@ -8620,7 +8598,7 @@ function ThinkingLevelGlyph({ level }) {
8620
8598
  viewBox: "0 0 14 14",
8621
8599
  fill: "none",
8622
8600
  className: "shrink-0",
8623
- children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx30(
8601
+ children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx28(
8624
8602
  "rect",
8625
8603
  {
8626
8604
  x: 2 + i * 4,
@@ -8657,6 +8635,8 @@ function groupModelOptions(options) {
8657
8635
  var ModelSelectTrigger = forwardRef(function ModelSelectTrigger2({
8658
8636
  value,
8659
8637
  options,
8638
+ sessionModel,
8639
+ isOverride = false,
8660
8640
  disabled,
8661
8641
  trigger = "button",
8662
8642
  open = false,
@@ -8666,17 +8646,21 @@ var ModelSelectTrigger = forwardRef(function ModelSelectTrigger2({
8666
8646
  ...props
8667
8647
  }, ref) {
8668
8648
  const triggerLabel = modelTriggerLabel(value, options, emptyLabel);
8649
+ const sessionTriggerLabel = sessionModel ? modelTriggerLabel(sessionModel, options) : void 0;
8669
8650
  const triggerDisplay = value ? `${triggerLabel} (${displayProviderLabel(value.provider)})` : triggerLabel;
8670
- return /* @__PURE__ */ jsx30(
8651
+ const sessionDisplay = sessionModel && sessionTriggerLabel ? `${sessionTriggerLabel} (${displayProviderLabel(sessionModel.provider)})` : triggerDisplay;
8652
+ const accessibleDisplay = isOverride && value ? `Current model: ${sessionDisplay}. Next-message override: ${triggerDisplay}` : `Current model: ${sessionDisplay}`;
8653
+ return /* @__PURE__ */ jsx28(
8671
8654
  "button",
8672
8655
  {
8673
8656
  ref,
8674
8657
  type: "button",
8675
8658
  "data-boring-agent-part": "model-select",
8676
8659
  "data-boring-state": disabled ? "disabled" : void 0,
8660
+ "data-boring-model-override": isOverride ? "true" : void 0,
8677
8661
  disabled,
8678
- "aria-label": trigger === "slash" ? `Open model picker. Current model: ${triggerDisplay}` : "Model",
8679
- title: trigger === "slash" ? `Open model picker. Current model: ${triggerDisplay}` : void 0,
8662
+ "aria-label": trigger === "slash" ? `Open model picker. ${accessibleDisplay}` : "Model",
8663
+ title: trigger === "slash" ? accessibleDisplay : void 0,
8680
8664
  onClick,
8681
8665
  className: cn(
8682
8666
  trigger === "slash" ? "h-8 max-w-[min(68vw,420px)] cursor-pointer overflow-hidden text-ellipsis whitespace-nowrap rounded-[var(--radius-md)] px-2 text-xs transition-colors hover:bg-muted/60 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-popover disabled:pointer-events-none disabled:opacity-50 motion-reduce:transition-none" : selectorTriggerClass,
@@ -8685,16 +8669,25 @@ var ModelSelectTrigger = forwardRef(function ModelSelectTrigger2({
8685
8669
  className
8686
8670
  ),
8687
8671
  ...props,
8688
- children: trigger === "slash" ? /* @__PURE__ */ jsxs25(Fragment11, { children: [
8689
- /* @__PURE__ */ jsx30("span", { className: "text-muted-foreground", children: "Model \xB7 " }),
8690
- /* @__PURE__ */ jsx30("span", { className: "min-w-0 truncate text-foreground", children: triggerLabel }),
8691
- value ? /* @__PURE__ */ jsxs25("span", { className: "shrink-0 text-muted-foreground", children: [
8672
+ children: trigger === "slash" ? /* @__PURE__ */ jsxs24(Fragment11, { children: [
8673
+ /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Model \xB7 " }),
8674
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate text-foreground", children: sessionTriggerLabel ?? triggerLabel }),
8675
+ sessionModel ? /* @__PURE__ */ jsxs24("span", { className: "shrink-0 text-muted-foreground", children: [
8676
+ " \xB7 ",
8677
+ displayProviderLabel(sessionModel.provider)
8678
+ ] }) : value ? /* @__PURE__ */ jsxs24("span", { className: "shrink-0 text-muted-foreground", children: [
8679
+ " \xB7 ",
8680
+ displayProviderLabel(value.provider)
8681
+ ] }) : null,
8682
+ isOverride && value ? /* @__PURE__ */ jsxs24("span", { className: "shrink-0 text-amber-600 dark:text-amber-400", children: [
8683
+ " \xB7 Next override: ",
8684
+ triggerLabel,
8692
8685
  " \xB7 ",
8693
8686
  displayProviderLabel(value.provider)
8694
8687
  ] }) : null
8695
- ] }) : /* @__PURE__ */ jsxs25(Fragment11, { children: [
8696
- /* @__PURE__ */ jsx30("span", { className: "min-w-0 truncate", children: triggerDisplay }),
8697
- /* @__PURE__ */ jsx30(ChevronDownIcon5, { className: "h-3 w-3 shrink-0 text-muted-foreground/50", "aria-hidden": "true" })
8688
+ ] }) : /* @__PURE__ */ jsxs24(Fragment11, { children: [
8689
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: triggerDisplay }),
8690
+ /* @__PURE__ */ jsx28(ChevronDownIcon5, { className: "h-3 w-3 shrink-0 text-muted-foreground/50", "aria-hidden": "true" })
8698
8691
  ] })
8699
8692
  }
8700
8693
  );
@@ -8715,8 +8708,8 @@ function ModelPickerMenu({
8715
8708
  const keyboardOptions = hideDefaultOption ? groupedOptions : [null, ...groupedOptions];
8716
8709
  const selectedIndex = currentKey ? Math.max(0, keyboardOptions.findIndex((option) => option && encodeModelKey(option) === currentKey)) : 0;
8717
8710
  const [activeIndex, setActiveIndex] = useState16(selectedIndex);
8718
- const activeIndexRef = useRef14(selectedIndex);
8719
- const menuRef = useRef14(null);
8711
+ const activeIndexRef = useRef13(selectedIndex);
8712
+ const menuRef = useRef13(null);
8720
8713
  useDismissOnOutsidePointer(menuRef, onClose);
8721
8714
  const setKeyboardActiveIndex = (next) => {
8722
8715
  const resolved = typeof next === "function" ? next(activeIndexRef.current) : next;
@@ -8751,8 +8744,8 @@ function ModelPickerMenu({
8751
8744
  }, [activeIndex, disabled, keyboardOptions, onChange, onClose]);
8752
8745
  const optionIndexOffset = hideDefaultOption ? 0 : 1;
8753
8746
  const optionIndexes = new Map(groupedOptions.map((option, index) => [encodeModelKey(option), index + optionIndexOffset]));
8754
- return /* @__PURE__ */ jsx30("div", { ref: menuRef, "data-boring-agent": "", "data-boring-agent-part": "model-picker-menu", className: cn(composerPickerMenuClass, className), children: /* @__PURE__ */ jsxs25(Command, { className: "bg-transparent text-[color:var(--popover-foreground)]", children: [
8755
- menuOptions.length > 8 && /* @__PURE__ */ jsx30("div", { className: "border-b border-border/60 px-2", children: /* @__PURE__ */ jsx30(
8747
+ return /* @__PURE__ */ jsx28("div", { ref: menuRef, "data-boring-agent": "", "data-boring-agent-part": "model-picker-menu", className: cn(composerPickerMenuClass, className), children: /* @__PURE__ */ jsxs24(Command, { className: "bg-transparent text-[color:var(--popover-foreground)]", children: [
8748
+ menuOptions.length > 8 && /* @__PURE__ */ jsx28("div", { className: "border-b border-border/60 px-2", children: /* @__PURE__ */ jsx28(
8756
8749
  CommandInput,
8757
8750
  {
8758
8751
  placeholder: "Search models\u2026",
@@ -8760,9 +8753,9 @@ function ModelPickerMenu({
8760
8753
  className: "h-8 w-full border-0 bg-transparent text-sm outline-none focus:ring-0"
8761
8754
  }
8762
8755
  ) }),
8763
- /* @__PURE__ */ jsxs25(CommandList, { className: "max-h-[300px] p-0.5", children: [
8764
- /* @__PURE__ */ jsx30(CommandEmpty, { className: "py-4 text-center text-sm text-muted-foreground", children: "No models found" }),
8765
- !hideDefaultOption ? /* @__PURE__ */ jsx30(CommandGroup, { children: /* @__PURE__ */ jsxs25(
8756
+ /* @__PURE__ */ jsxs24(CommandList, { className: "max-h-[300px] p-0.5", children: [
8757
+ /* @__PURE__ */ jsx28(CommandEmpty, { className: "py-4 text-center text-sm text-muted-foreground", children: "No models found" }),
8758
+ !hideDefaultOption ? /* @__PURE__ */ jsx28(CommandGroup, { children: /* @__PURE__ */ jsxs24(
8766
8759
  CommandItem,
8767
8760
  {
8768
8761
  value: "Default model automatic auto",
@@ -8773,7 +8766,7 @@ function ModelPickerMenu({
8773
8766
  },
8774
8767
  className: selectorItemClass(!value || activeIndex === 0),
8775
8768
  children: [
8776
- /* @__PURE__ */ jsx30(
8769
+ /* @__PURE__ */ jsx28(
8777
8770
  CheckIcon3,
8778
8771
  {
8779
8772
  className: cn(
@@ -8782,12 +8775,12 @@ function ModelPickerMenu({
8782
8775
  )
8783
8776
  }
8784
8777
  ),
8785
- /* @__PURE__ */ jsx30("span", { className: "truncate", children: "Default model" }),
8786
- /* @__PURE__ */ jsx30("span", { className: "ml-auto shrink-0 text-xs text-muted-foreground", children: "Auto" })
8778
+ /* @__PURE__ */ jsx28("span", { className: "truncate", children: "Default model" }),
8779
+ /* @__PURE__ */ jsx28("span", { className: "ml-auto shrink-0 text-xs text-muted-foreground", children: "Auto" })
8787
8780
  ]
8788
8781
  }
8789
8782
  ) }) : null,
8790
- [...groups.entries()].map(([provider, list]) => /* @__PURE__ */ jsx30(
8783
+ [...groups.entries()].map(([provider, list]) => /* @__PURE__ */ jsx28(
8791
8784
  CommandGroup,
8792
8785
  {
8793
8786
  heading: displayProviderLabel(provider),
@@ -8796,7 +8789,7 @@ function ModelPickerMenu({
8796
8789
  const key = encodeModelKey(m);
8797
8790
  const label = m.label || displayModelLabel(m.id);
8798
8791
  const itemIndex = optionIndexes.get(key) ?? 0;
8799
- return /* @__PURE__ */ jsxs25(
8792
+ return /* @__PURE__ */ jsxs24(
8800
8793
  CommandItem,
8801
8794
  {
8802
8795
  value: `${label} ${m.id} ${displayProviderLabel(m.provider)}`,
@@ -8807,7 +8800,7 @@ function ModelPickerMenu({
8807
8800
  },
8808
8801
  className: cn(selectorItemClass(key === currentKey || activeIndex === itemIndex)),
8809
8802
  children: [
8810
- /* @__PURE__ */ jsx30(
8803
+ /* @__PURE__ */ jsx28(
8811
8804
  CheckIcon3,
8812
8805
  {
8813
8806
  className: cn(
@@ -8816,8 +8809,8 @@ function ModelPickerMenu({
8816
8809
  )
8817
8810
  }
8818
8811
  ),
8819
- /* @__PURE__ */ jsx30("span", { className: "min-w-0 flex-1 truncate whitespace-nowrap", children: label }),
8820
- /* @__PURE__ */ jsx30("span", { className: "ml-auto max-w-[45%] shrink-0 truncate whitespace-nowrap text-right text-xs text-muted-foreground", children: m.id })
8812
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 flex-1 truncate whitespace-nowrap", children: label }),
8813
+ /* @__PURE__ */ jsx28("span", { className: "ml-auto max-w-[45%] shrink-0 truncate whitespace-nowrap text-right text-xs text-muted-foreground", children: m.id })
8821
8814
  ]
8822
8815
  },
8823
8816
  key
@@ -8843,7 +8836,7 @@ function ModelSelect({
8843
8836
  hideDefaultOption = false
8844
8837
  }) {
8845
8838
  const [open, setOpen] = useState16(false);
8846
- const previousOpenSignalRef = useRef14(openSignal);
8839
+ const previousOpenSignalRef = useRef13(openSignal);
8847
8840
  useEffect17(() => {
8848
8841
  if (disabled) setOpen(false);
8849
8842
  }, [disabled]);
@@ -8855,8 +8848,8 @@ function ModelSelect({
8855
8848
  if (previousOpenSignalRef.current !== openSignal) setOpen(true);
8856
8849
  previousOpenSignalRef.current = openSignal;
8857
8850
  }, [disabled, openSignal]);
8858
- return /* @__PURE__ */ jsxs25(Popover, { open, onOpenChange: disabled ? void 0 : setOpen, children: [
8859
- /* @__PURE__ */ jsx30(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx30(
8851
+ return /* @__PURE__ */ jsxs24(Popover, { open, onOpenChange: disabled ? void 0 : setOpen, children: [
8852
+ /* @__PURE__ */ jsx28(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(
8860
8853
  ModelSelectTrigger,
8861
8854
  {
8862
8855
  value,
@@ -8870,7 +8863,7 @@ function ModelSelect({
8870
8863
  "aria-describedby": ariaDescribedBy
8871
8864
  }
8872
8865
  ) }),
8873
- /* @__PURE__ */ jsx30(
8866
+ /* @__PURE__ */ jsx28(
8874
8867
  PopoverContent,
8875
8868
  {
8876
8869
  align: trigger === "slash" ? "center" : "start",
@@ -8879,7 +8872,7 @@ function ModelSelect({
8879
8872
  collisionPadding: 12,
8880
8873
  "data-boring-agent": "",
8881
8874
  className: cn("w-[min(92vw,340px)]", selectorContentClass),
8882
- children: /* @__PURE__ */ jsx30(
8875
+ children: /* @__PURE__ */ jsx28(
8883
8876
  ModelPickerMenu,
8884
8877
  {
8885
8878
  value,
@@ -8904,7 +8897,7 @@ function ThinkingSelect({
8904
8897
  className
8905
8898
  }) {
8906
8899
  const [open, setOpen] = useState16(false);
8907
- const previousOpenSignalRef = useRef14(openSignal);
8900
+ const previousOpenSignalRef = useRef13(openSignal);
8908
8901
  useEffect17(() => {
8909
8902
  if (disabled) setOpen(false);
8910
8903
  }, [disabled]);
@@ -8916,8 +8909,8 @@ function ThinkingSelect({
8916
8909
  if (previousOpenSignalRef.current !== openSignal) setOpen(true);
8917
8910
  previousOpenSignalRef.current = openSignal;
8918
8911
  }, [disabled, openSignal]);
8919
- return /* @__PURE__ */ jsxs25(Popover, { open, onOpenChange: disabled ? void 0 : setOpen, children: [
8920
- /* @__PURE__ */ jsx30(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx30(
8912
+ return /* @__PURE__ */ jsxs24(Popover, { open, onOpenChange: disabled ? void 0 : setOpen, children: [
8913
+ /* @__PURE__ */ jsx28(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(
8921
8914
  ThinkingSelectTrigger,
8922
8915
  {
8923
8916
  value,
@@ -8927,7 +8920,7 @@ function ThinkingSelect({
8927
8920
  className
8928
8921
  }
8929
8922
  ) }),
8930
- /* @__PURE__ */ jsx30(
8923
+ /* @__PURE__ */ jsx28(
8931
8924
  PopoverContent,
8932
8925
  {
8933
8926
  align: trigger === "slash" ? "center" : "end",
@@ -8936,7 +8929,7 @@ function ThinkingSelect({
8936
8929
  collisionPadding: 12,
8937
8930
  "data-boring-agent": "",
8938
8931
  className: cn("w-[min(92vw,240px)]", selectorContentClass),
8939
- children: /* @__PURE__ */ jsx30(
8932
+ children: /* @__PURE__ */ jsx28(
8940
8933
  ThinkingPickerMenu,
8941
8934
  {
8942
8935
  value,
@@ -8959,7 +8952,7 @@ var ThinkingSelectTrigger = forwardRef(function ThinkingSelectTrigger2({
8959
8952
  className,
8960
8953
  ...props
8961
8954
  }, ref) {
8962
- return /* @__PURE__ */ jsxs25(
8955
+ return /* @__PURE__ */ jsxs24(
8963
8956
  "button",
8964
8957
  {
8965
8958
  ref,
@@ -8980,13 +8973,13 @@ var ThinkingSelectTrigger = forwardRef(function ThinkingSelectTrigger2({
8980
8973
  onClick,
8981
8974
  ...props,
8982
8975
  children: [
8983
- trigger === "button" ? /* @__PURE__ */ jsx30(ThinkingLevelGlyph, { level: value }) : null,
8984
- trigger === "slash" ? /* @__PURE__ */ jsxs25(Fragment11, { children: [
8985
- /* @__PURE__ */ jsx30("span", { className: "text-muted-foreground", children: "Thinking \xB7 " }),
8986
- /* @__PURE__ */ jsx30("span", { className: "text-foreground", children: THINKING_LEVEL_STATUS_LABELS[value] })
8987
- ] }) : /* @__PURE__ */ jsxs25(Fragment11, { children: [
8988
- /* @__PURE__ */ jsx30("span", { children: THINKING_LEVEL_LABELS[value] }),
8989
- /* @__PURE__ */ jsx30(ChevronDownIcon5, { className: "h-3 w-3 shrink-0 text-muted-foreground/50", "aria-hidden": "true" })
8976
+ trigger === "button" ? /* @__PURE__ */ jsx28(ThinkingLevelGlyph, { level: value }) : null,
8977
+ trigger === "slash" ? /* @__PURE__ */ jsxs24(Fragment11, { children: [
8978
+ /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Thinking \xB7 " }),
8979
+ /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: THINKING_LEVEL_STATUS_LABELS[value] })
8980
+ ] }) : /* @__PURE__ */ jsxs24(Fragment11, { children: [
8981
+ /* @__PURE__ */ jsx28("span", { children: THINKING_LEVEL_LABELS[value] }),
8982
+ /* @__PURE__ */ jsx28(ChevronDownIcon5, { className: "h-3 w-3 shrink-0 text-muted-foreground/50", "aria-hidden": "true" })
8990
8983
  ] })
8991
8984
  ]
8992
8985
  }
@@ -9001,8 +8994,8 @@ function ThinkingPickerMenu({
9001
8994
  }) {
9002
8995
  const selectedIndex = Math.max(0, THINKING_LEVELS.indexOf(value));
9003
8996
  const [activeIndex, setActiveIndex] = useState16(selectedIndex);
9004
- const activeIndexRef = useRef14(selectedIndex);
9005
- const menuRef = useRef14(null);
8997
+ const activeIndexRef = useRef13(selectedIndex);
8998
+ const menuRef = useRef13(null);
9006
8999
  useDismissOnOutsidePointer(menuRef, onClose);
9007
9000
  const setKeyboardActiveIndex = (next) => {
9008
9001
  const resolved = typeof next === "function" ? next(activeIndexRef.current) : next;
@@ -9035,7 +9028,7 @@ function ThinkingPickerMenu({
9035
9028
  window.addEventListener("keydown", handler, { capture: true });
9036
9029
  return () => window.removeEventListener("keydown", handler, { capture: true });
9037
9030
  }, [activeIndex, disabled, onChange, onClose]);
9038
- return /* @__PURE__ */ jsx30("div", { ref: menuRef, "data-boring-agent": "", "data-boring-agent-part": "thinking-picker-menu", className: cn(composerPickerMenuClass, className), children: /* @__PURE__ */ jsx30(Command, { className: "bg-transparent text-[color:var(--popover-foreground)]", children: /* @__PURE__ */ jsx30(CommandList, { className: "max-h-[300px] p-0.5", children: THINKING_LEVELS.map((level, index) => /* @__PURE__ */ jsxs25(
9031
+ return /* @__PURE__ */ jsx28("div", { ref: menuRef, "data-boring-agent": "", "data-boring-agent-part": "thinking-picker-menu", className: cn(composerPickerMenuClass, className), children: /* @__PURE__ */ jsx28(Command, { className: "bg-transparent text-[color:var(--popover-foreground)]", children: /* @__PURE__ */ jsx28(CommandList, { className: "max-h-[300px] p-0.5", children: THINKING_LEVELS.map((level, index) => /* @__PURE__ */ jsxs24(
9039
9032
  CommandItem,
9040
9033
  {
9041
9034
  value: `Thinking ${THINKING_LEVEL_LABELS[level]} ${THINKING_LEVEL_DETAILS[level]}`,
@@ -9046,7 +9039,7 @@ function ThinkingPickerMenu({
9046
9039
  },
9047
9040
  className: selectorItemClass(level === value || index === activeIndex),
9048
9041
  children: [
9049
- /* @__PURE__ */ jsx30(
9042
+ /* @__PURE__ */ jsx28(
9050
9043
  CheckIcon3,
9051
9044
  {
9052
9045
  className: cn(
@@ -9055,9 +9048,9 @@ function ThinkingPickerMenu({
9055
9048
  )
9056
9049
  }
9057
9050
  ),
9058
- /* @__PURE__ */ jsx30(ThinkingLevelGlyph, { level }),
9059
- /* @__PURE__ */ jsx30("span", { className: "font-medium", children: THINKING_LEVEL_LABELS[level] }),
9060
- /* @__PURE__ */ jsx30("span", { className: "ml-auto text-xs text-muted-foreground", children: THINKING_LEVEL_DETAILS[level] })
9051
+ /* @__PURE__ */ jsx28(ThinkingLevelGlyph, { level }),
9052
+ /* @__PURE__ */ jsx28("span", { className: "font-medium", children: THINKING_LEVEL_LABELS[level] }),
9053
+ /* @__PURE__ */ jsx28("span", { className: "ml-auto text-xs text-muted-foreground", children: THINKING_LEVEL_DETAILS[level] })
9061
9054
  ]
9062
9055
  },
9063
9056
  level
@@ -9095,25 +9088,25 @@ import {
9095
9088
  Monitor,
9096
9089
  PlusIcon as PlusIcon2,
9097
9090
  SquareIcon,
9098
- XIcon as XIcon5
9091
+ XIcon as XIcon4
9099
9092
  } from "lucide-react";
9100
9093
  import { nanoid } from "nanoid";
9101
- import { useCallback as useCallback15, useEffect as useEffect18, useMemo as useMemo13, useRef as useRef15, useState as useState17 } from "react";
9094
+ import { useCallback as useCallback15, useEffect as useEffect18, useMemo as useMemo13, useRef as useRef14, useState as useState17 } from "react";
9102
9095
 
9103
9096
  // src/front/primitives/prompt-input-context.ts
9104
- import { createContext as createContext8, useContext as useContext8 } from "react";
9105
- var PromptInputController = createContext8(
9097
+ import { createContext as createContext7, useContext as useContext7 } from "react";
9098
+ var PromptInputController = createContext7(
9106
9099
  null
9107
9100
  );
9108
- var ProviderAttachmentsContext = createContext8(
9101
+ var ProviderAttachmentsContext = createContext7(
9109
9102
  null
9110
9103
  );
9111
- var useOptionalPromptInputController = () => useContext8(PromptInputController);
9112
- var useOptionalProviderAttachments = () => useContext8(ProviderAttachmentsContext);
9113
- var LocalAttachmentsContext = createContext8(null);
9104
+ var useOptionalPromptInputController = () => useContext7(PromptInputController);
9105
+ var useOptionalProviderAttachments = () => useContext7(ProviderAttachmentsContext);
9106
+ var LocalAttachmentsContext = createContext7(null);
9114
9107
  var usePromptInputAttachments = () => {
9115
9108
  const provider = useOptionalProviderAttachments();
9116
- const local = useContext8(LocalAttachmentsContext);
9109
+ const local = useContext7(LocalAttachmentsContext);
9117
9110
  const context = local ?? provider;
9118
9111
  if (!context) {
9119
9112
  throw new Error(
@@ -9122,23 +9115,23 @@ var usePromptInputAttachments = () => {
9122
9115
  }
9123
9116
  return context;
9124
9117
  };
9125
- var LocalReferencedSourcesContext = createContext8(null);
9118
+ var LocalReferencedSourcesContext = createContext7(null);
9126
9119
 
9127
9120
  // src/front/primitives/prompt-input-wrappers.tsx
9128
9121
  import {
9129
9122
  InputGroupAddon,
9130
9123
  InputGroupButton,
9131
- Tooltip as Tooltip3,
9132
- TooltipContent as TooltipContent3,
9133
- TooltipTrigger as TooltipTrigger3
9124
+ Tooltip as Tooltip2,
9125
+ TooltipContent as TooltipContent2,
9126
+ TooltipTrigger as TooltipTrigger2
9134
9127
  } from "@hachej/boring-ui-kit";
9135
9128
  import { Children as Children2 } from "react";
9136
- import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
9129
+ import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
9137
9130
  var PromptInputFooter = ({
9138
9131
  align = "block-end",
9139
9132
  className,
9140
9133
  ...props
9141
- }) => /* @__PURE__ */ jsx31(
9134
+ }) => /* @__PURE__ */ jsx29(
9142
9135
  InputGroupAddon,
9143
9136
  {
9144
9137
  align,
@@ -9148,7 +9141,7 @@ var PromptInputFooter = ({
9148
9141
  );
9149
9142
 
9150
9143
  // src/front/primitives/prompt-input.tsx
9151
- import { Fragment as Fragment12, jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
9144
+ import { Fragment as Fragment12, jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
9152
9145
  var PromptInput = ({
9153
9146
  className,
9154
9147
  accept,
@@ -9165,12 +9158,12 @@ var PromptInput = ({
9165
9158
  }) => {
9166
9159
  const controller = useOptionalPromptInputController();
9167
9160
  const usingProvider = !!controller;
9168
- const providerTextValueRef = useRef15("");
9161
+ const providerTextValueRef = useRef14("");
9169
9162
  if (usingProvider) {
9170
9163
  providerTextValueRef.current = controller.textInput.value;
9171
9164
  }
9172
- const inputRef = useRef15(null);
9173
- const formRef = useRef15(null);
9165
+ const inputRef = useRef14(null);
9166
+ const formRef = useRef14(null);
9174
9167
  const [items, setItems] = useState17([]);
9175
9168
  const setFileUrlLocal = useCallback15((id, url, status, path) => {
9176
9169
  setItems((prev) => prev.map((f) => {
@@ -9181,7 +9174,7 @@ var PromptInput = ({
9181
9174
  }, []);
9182
9175
  const files = usingProvider ? controller.attachments.files : items;
9183
9176
  const [referencedSources, setReferencedSources] = useState17([]);
9184
- const filesRef = useRef15(files);
9177
+ const filesRef = useRef14(files);
9185
9178
  useEffect18(() => {
9186
9179
  filesRef.current = files;
9187
9180
  }, [files]);
@@ -9491,8 +9484,8 @@ var PromptInput = ({
9491
9484
  },
9492
9485
  [usingProvider, controller, files, onSubmit, clear]
9493
9486
  );
9494
- const inner = /* @__PURE__ */ jsxs27(Fragment12, { children: [
9495
- /* @__PURE__ */ jsx32(
9487
+ const inner = /* @__PURE__ */ jsxs26(Fragment12, { children: [
9488
+ /* @__PURE__ */ jsx30(
9496
9489
  Input,
9497
9490
  {
9498
9491
  accept,
@@ -9505,7 +9498,7 @@ var PromptInput = ({
9505
9498
  type: "file"
9506
9499
  }
9507
9500
  ),
9508
- /* @__PURE__ */ jsx32(
9501
+ /* @__PURE__ */ jsx30(
9509
9502
  "form",
9510
9503
  {
9511
9504
  "data-boring-agent-part": "composer",
@@ -9513,12 +9506,12 @@ var PromptInput = ({
9513
9506
  onSubmit: handleSubmit,
9514
9507
  ref: formRef,
9515
9508
  ...props,
9516
- children: /* @__PURE__ */ jsx32(InputGroup, { className: "overflow-hidden", children })
9509
+ children: /* @__PURE__ */ jsx30(InputGroup, { className: "overflow-hidden", children })
9517
9510
  }
9518
9511
  )
9519
9512
  ] });
9520
- const withReferencedSources = /* @__PURE__ */ jsx32(LocalReferencedSourcesContext.Provider, { value: refsCtx, children: inner });
9521
- return /* @__PURE__ */ jsx32(LocalAttachmentsContext.Provider, { value: attachmentsCtx, children: withReferencedSources });
9513
+ const withReferencedSources = /* @__PURE__ */ jsx30(LocalReferencedSourcesContext.Provider, { value: refsCtx, children: inner });
9514
+ return /* @__PURE__ */ jsx30(LocalAttachmentsContext.Provider, { value: attachmentsCtx, children: withReferencedSources });
9522
9515
  };
9523
9516
  var PromptInputTextarea = ({
9524
9517
  onChange,
@@ -9596,7 +9589,7 @@ var PromptInputTextarea = ({
9596
9589
  } : {
9597
9590
  onChange
9598
9591
  };
9599
- return /* @__PURE__ */ jsx32(
9592
+ return /* @__PURE__ */ jsx30(
9600
9593
  InputGroupTextarea,
9601
9594
  {
9602
9595
  "data-boring-agent-part": "composer-input",
@@ -9623,13 +9616,13 @@ var PromptInputSubmit = ({
9623
9616
  ...props
9624
9617
  }) => {
9625
9618
  const isGenerating = status === "submitted" || status === "streaming";
9626
- let Icon = /* @__PURE__ */ jsx32(CornerDownLeftIcon, { className: "size-4" });
9619
+ let Icon = /* @__PURE__ */ jsx30(CornerDownLeftIcon, { className: "size-4" });
9627
9620
  if (status === "submitted") {
9628
- Icon = /* @__PURE__ */ jsx32(Spinner, {});
9621
+ Icon = /* @__PURE__ */ jsx30(Spinner, {});
9629
9622
  } else if (status === "streaming") {
9630
- Icon = /* @__PURE__ */ jsx32(SquareIcon, { className: "size-4" });
9623
+ Icon = /* @__PURE__ */ jsx30(SquareIcon, { className: "size-4" });
9631
9624
  } else if (status === "error") {
9632
- Icon = /* @__PURE__ */ jsx32(XIcon5, { className: "size-4" });
9625
+ Icon = /* @__PURE__ */ jsx30(XIcon4, { className: "size-4" });
9633
9626
  }
9634
9627
  const handleClick = useCallback15(
9635
9628
  (e) => {
@@ -9642,7 +9635,7 @@ var PromptInputSubmit = ({
9642
9635
  },
9643
9636
  [isGenerating, onStop, onClick]
9644
9637
  );
9645
- return /* @__PURE__ */ jsx32(
9638
+ return /* @__PURE__ */ jsx30(
9646
9639
  InputGroupButton2,
9647
9640
  {
9648
9641
  "aria-label": isGenerating ? "Stop" : "Submit",
@@ -9659,8 +9652,8 @@ var PromptInputSubmit = ({
9659
9652
  };
9660
9653
 
9661
9654
  // src/front/primitives/slash-command-picker.tsx
9662
- import { useEffect as useEffect19, useMemo as useMemo14, useRef as useRef16, useState as useState18 } from "react";
9663
- import { Fragment as Fragment13, jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
9655
+ import { useEffect as useEffect19, useMemo as useMemo14, useRef as useRef15, useState as useState18 } from "react";
9656
+ import { Fragment as Fragment13, jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
9664
9657
  var ALL_PLUGINS = "__all__";
9665
9658
  function commandGroup(cmd) {
9666
9659
  if (cmd.source === "skill") return "skills";
@@ -9671,9 +9664,9 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
9671
9664
  const [plugin, setPlugin] = useState18(ALL_PLUGINS);
9672
9665
  const [searchQuery, setSearchQuery] = useState18(query);
9673
9666
  const [activeIdx, setActiveIdx] = useState18(0);
9674
- const containerRef = useRef16(null);
9675
- const listRef = useRef16(null);
9676
- const inputRef = useRef16(null);
9667
+ const containerRef = useRef15(null);
9668
+ const listRef = useRef15(null);
9669
+ const inputRef = useRef15(null);
9677
9670
  useEffect19(() => {
9678
9671
  setSearchQuery(query);
9679
9672
  }, [query]);
@@ -9711,8 +9704,8 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
9711
9704
  },
9712
9705
  onDismiss
9713
9706
  });
9714
- return /* @__PURE__ */ jsxs28("div", { ref: containerRef, className: "mb-1 w-full overflow-hidden rounded-lg border border-border/60 bg-popover shadow-lg", children: [
9715
- /* @__PURE__ */ jsx33(
9707
+ return /* @__PURE__ */ jsxs27("div", { ref: containerRef, className: "mb-1 w-full overflow-hidden rounded-lg border border-border/60 bg-popover shadow-lg", children: [
9708
+ /* @__PURE__ */ jsx31(
9716
9709
  "input",
9717
9710
  {
9718
9711
  ref: inputRef,
@@ -9727,9 +9720,9 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
9727
9720
  autoComplete: "off"
9728
9721
  }
9729
9722
  ),
9730
- /* @__PURE__ */ jsx33("div", { className: "flex flex-wrap gap-1 border-b border-border/50 px-2 py-1.5", role: "tablist", "aria-label": "Filter by plugin", children: [ALL_PLUGINS, ...groups].map((g) => {
9723
+ /* @__PURE__ */ jsx31("div", { className: "flex flex-wrap gap-1 border-b border-border/50 px-2 py-1.5", role: "tablist", "aria-label": "Filter by plugin", children: [ALL_PLUGINS, ...groups].map((g) => {
9731
9724
  const selected = plugin === g;
9732
- return /* @__PURE__ */ jsx33(
9725
+ return /* @__PURE__ */ jsx31(
9733
9726
  "button",
9734
9727
  {
9735
9728
  type: "button",
@@ -9749,7 +9742,7 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
9749
9742
  g
9750
9743
  );
9751
9744
  }) }),
9752
- filtered.length === 0 ? /* @__PURE__ */ jsx33("div", { className: "px-3 py-2 text-[11px] text-muted-foreground", children: "No matching commands." }) : /* @__PURE__ */ jsx33("ul", { ref: listRef, className: "max-h-80 overflow-y-auto py-1", role: "listbox", "aria-label": "Commands", children: filtered.map((cmd, i) => /* @__PURE__ */ jsxs28(
9745
+ filtered.length === 0 ? /* @__PURE__ */ jsx31("div", { className: "px-3 py-2 text-[11px] text-muted-foreground", children: "No matching commands." }) : /* @__PURE__ */ jsx31("ul", { ref: listRef, className: "max-h-80 overflow-y-auto py-1", role: "listbox", "aria-label": "Commands", children: filtered.map((cmd, i) => /* @__PURE__ */ jsxs27(
9753
9746
  "li",
9754
9747
  {
9755
9748
  role: "option",
@@ -9767,20 +9760,20 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
9767
9760
  onSelect(cmd.name);
9768
9761
  },
9769
9762
  children: [
9770
- /* @__PURE__ */ jsxs28("span", { className: "flex items-center gap-1.5", children: [
9771
- /* @__PURE__ */ jsxs28("span", { className: "font-medium text-foreground/80", children: [
9763
+ /* @__PURE__ */ jsxs27("span", { className: "flex items-center gap-1.5", children: [
9764
+ /* @__PURE__ */ jsxs27("span", { className: "font-medium text-foreground/80", children: [
9772
9765
  "/",
9773
9766
  cmd.name
9774
9767
  ] }),
9775
- cmd.source === "skill" ? /* @__PURE__ */ jsxs28(Fragment13, { children: [
9776
- /* @__PURE__ */ jsx33("span", { className: "rounded-sm bg-accent/15 px-1 py-px text-[9px] font-medium uppercase tracking-wide text-accent-foreground", children: "skill" }),
9777
- cmd.sourcePlugin ? /* @__PURE__ */ jsx33("span", { className: "rounded-sm bg-muted px-1 py-px text-[9px] font-medium text-muted-foreground", children: cmd.sourcePlugin }) : null
9768
+ cmd.source === "skill" ? /* @__PURE__ */ jsxs27(Fragment13, { children: [
9769
+ /* @__PURE__ */ jsx31("span", { className: "rounded-sm bg-accent/15 px-1 py-px text-[9px] font-medium uppercase tracking-wide text-accent-foreground", children: "skill" }),
9770
+ cmd.sourcePlugin ? /* @__PURE__ */ jsx31("span", { className: "rounded-sm bg-muted px-1 py-px text-[9px] font-medium text-muted-foreground", children: cmd.sourcePlugin }) : null
9778
9771
  ] }) : cmd.sourcePlugin ? (
9779
9772
  // Originating plugin/package for non-skill commands.
9780
- /* @__PURE__ */ jsx33("span", { className: "rounded-sm bg-muted px-1 py-px text-[9px] font-medium text-muted-foreground", children: cmd.sourcePlugin })
9773
+ /* @__PURE__ */ jsx31("span", { className: "rounded-sm bg-muted px-1 py-px text-[9px] font-medium text-muted-foreground", children: cmd.sourcePlugin })
9781
9774
  ) : null
9782
9775
  ] }),
9783
- /* @__PURE__ */ jsx33("span", { className: "truncate text-[11px] opacity-50", children: cmd.description })
9776
+ /* @__PURE__ */ jsx31("span", { className: "truncate text-[11px] opacity-50", children: cmd.description })
9784
9777
  ]
9785
9778
  },
9786
9779
  cmd.name
@@ -9791,10 +9784,10 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
9791
9784
  // src/front/chat/components/ComposerAttachments.tsx
9792
9785
  import { AlertCircleIcon as AlertCircleIcon2, Loader2 as Loader22, PaperclipIcon as PaperclipIcon2 } from "lucide-react";
9793
9786
  import { IconButton as IconButton3 } from "@hachej/boring-ui-kit";
9794
- import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
9787
+ import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
9795
9788
  function AttachmentButton({ disabled, className }) {
9796
9789
  const attachments = usePromptInputAttachments();
9797
- return /* @__PURE__ */ jsx34(
9790
+ return /* @__PURE__ */ jsx32(
9798
9791
  IconButton3,
9799
9792
  {
9800
9793
  type: "button",
@@ -9807,21 +9800,21 @@ function AttachmentButton({ disabled, className }) {
9807
9800
  className: cn(composerActionClass, "composer-attachment-button !h-10 !w-10", className),
9808
9801
  "aria-label": "Attach files",
9809
9802
  title: disabled ? "Attachments are available when the composer is ready." : "Attach files",
9810
- children: /* @__PURE__ */ jsx34(PaperclipIcon2, { className: "h-4 w-4", strokeWidth: 1.75 })
9803
+ children: /* @__PURE__ */ jsx32(PaperclipIcon2, { className: "h-4 w-4", strokeWidth: 1.75 })
9811
9804
  }
9812
9805
  );
9813
9806
  }
9814
9807
  function AttachmentsList() {
9815
9808
  const attachments = usePromptInputAttachments();
9816
9809
  if (attachments.files.length === 0) return null;
9817
- return /* @__PURE__ */ jsx34(
9810
+ return /* @__PURE__ */ jsx32(
9818
9811
  Attachments,
9819
9812
  {
9820
9813
  "data-boring-agent-part": "composer-attachment-row",
9821
9814
  "data-align": "block-start",
9822
9815
  variant: "inline",
9823
9816
  className: "w-full flex-wrap items-center justify-start gap-2 px-5 pb-0 pt-3",
9824
- children: attachments.files.map((file) => /* @__PURE__ */ jsxs29(
9817
+ children: attachments.files.map((file) => /* @__PURE__ */ jsxs28(
9825
9818
  Attachment,
9826
9819
  {
9827
9820
  data: file,
@@ -9832,13 +9825,13 @@ function AttachmentsList() {
9832
9825
  file.status === "error" && "!border-destructive/50 !bg-destructive/10"
9833
9826
  ),
9834
9827
  children: [
9835
- /* @__PURE__ */ jsxs29("div", { className: "relative shrink-0", children: [
9836
- /* @__PURE__ */ jsx34(AttachmentPreview, { className: "!size-7 overflow-hidden !rounded-full bg-background/60" }),
9837
- file.status === "uploading" ? /* @__PURE__ */ jsx34("div", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-background/70", children: /* @__PURE__ */ jsx34(Loader22, { className: "size-3.5 animate-spin text-muted-foreground" }) }) : null,
9838
- file.status === "error" ? /* @__PURE__ */ jsx34("div", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-destructive/20", children: /* @__PURE__ */ jsx34(AlertCircleIcon2, { className: "size-3.5 text-destructive" }) }) : null
9828
+ /* @__PURE__ */ jsxs28("div", { className: "relative shrink-0", children: [
9829
+ /* @__PURE__ */ jsx32(AttachmentPreview, { className: "!size-7 overflow-hidden !rounded-full bg-background/60" }),
9830
+ file.status === "uploading" ? /* @__PURE__ */ jsx32("div", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-background/70", children: /* @__PURE__ */ jsx32(Loader22, { className: "size-3.5 animate-spin text-muted-foreground" }) }) : null,
9831
+ file.status === "error" ? /* @__PURE__ */ jsx32("div", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-destructive/20", children: /* @__PURE__ */ jsx32(AlertCircleIcon2, { className: "size-3.5 text-destructive" }) }) : null
9839
9832
  ] }),
9840
- /* @__PURE__ */ jsx34(AttachmentInfo, { className: "min-w-0 !max-w-[180px] truncate text-[13px] font-medium" }),
9841
- /* @__PURE__ */ jsx34(AttachmentRemove, { className: "composer-attachment-remove !size-5 !rounded-full !opacity-100 text-muted-foreground/80 hover:text-foreground" })
9833
+ /* @__PURE__ */ jsx32(AttachmentInfo, { className: "min-w-0 !max-w-[180px] truncate text-[13px] font-medium" }),
9834
+ /* @__PURE__ */ jsx32(AttachmentRemove, { className: "composer-attachment-remove !size-5 !rounded-full !opacity-100 text-muted-foreground/80 hover:text-foreground" })
9842
9835
  ]
9843
9836
  },
9844
9837
  file.id
@@ -9848,7 +9841,7 @@ function AttachmentsList() {
9848
9841
  }
9849
9842
 
9850
9843
  // src/front/chat/components/PiChatComposerSurface.tsx
9851
- import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
9844
+ import { jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
9852
9845
  var MAX_PROMPT_ATTACHMENTS = 2;
9853
9846
  var MAX_PROMPT_ATTACHMENT_BYTES = 10 * 1024 * 1024;
9854
9847
  var COMPOSER_INPUT_GROUP_MIN_HEIGHT = 56;
@@ -9908,6 +9901,8 @@ function PiChatComposerSurface({
9908
9901
  onDismissSlash,
9909
9902
  modelPickerOpen,
9910
9903
  selectedModel,
9904
+ sessionModel,
9905
+ modelOverride,
9911
9906
  modelOptions,
9912
9907
  modelControlled,
9913
9908
  hideDefaultModelOption = false,
@@ -9963,11 +9958,11 @@ function PiChatComposerSurface({
9963
9958
  useLayoutEffect3(() => {
9964
9959
  resizeTextarea(textareaRef.current);
9965
9960
  }, [draft, resizeTextarea, textareaRef]);
9966
- return /* @__PURE__ */ jsxs30("div", { className: cn(
9961
+ return /* @__PURE__ */ jsxs29("div", { className: cn(
9967
9962
  "relative z-20",
9968
9963
  chrome ? "pb-[calc(1rem+env(safe-area-inset-bottom))] pl-[calc(1rem+env(safe-area-inset-left))] pr-[calc(1rem+env(safe-area-inset-right))] pt-2 sm:pb-[calc(1.25rem+env(safe-area-inset-bottom))] sm:pl-[calc(1.5rem+env(safe-area-inset-left))] sm:pr-[calc(1.5rem+env(safe-area-inset-right))]" : "pb-[calc(0.5rem+env(safe-area-inset-bottom))] pl-[calc(0.75rem+env(safe-area-inset-left))] pr-[calc(0.75rem+env(safe-area-inset-right))] pt-1"
9969
9964
  ), children: [
9970
- /* @__PURE__ */ jsx35(
9965
+ /* @__PURE__ */ jsx33(
9971
9966
  "div",
9972
9967
  {
9973
9968
  "data-boring-agent-part": "chat-working-slot",
@@ -9977,7 +9972,7 @@ function PiChatComposerSurface({
9977
9972
  isStreaming ? "mb-2 max-h-8 opacity-100" : "mb-0 max-h-0 opacity-0"
9978
9973
  ),
9979
9974
  "aria-hidden": !isStreaming,
9980
- children: /* @__PURE__ */ jsxs30(
9975
+ children: /* @__PURE__ */ jsxs29(
9981
9976
  "div",
9982
9977
  {
9983
9978
  "data-testid": isStreaming ? "chat-working" : void 0,
@@ -9985,7 +9980,7 @@ function PiChatComposerSurface({
9985
9980
  "aria-live": isStreaming ? "polite" : void 0,
9986
9981
  className: "inline-flex items-center gap-2 rounded-full border border-border/50 bg-background/85 px-2.5 py-1 text-[12px] text-foreground shadow-sm backdrop-blur",
9987
9982
  children: [
9988
- /* @__PURE__ */ jsx35(
9983
+ /* @__PURE__ */ jsx33(
9989
9984
  motion2.span,
9990
9985
  {
9991
9986
  "aria-hidden": "true",
@@ -9994,14 +9989,14 @@ function PiChatComposerSurface({
9994
9989
  transition: prefersReducedMotion ? { duration: 0 } : { duration: 1.2, repeat: Infinity, ease: "easeInOut" }
9995
9990
  }
9996
9991
  ),
9997
- /* @__PURE__ */ jsx35("span", { children: "Working\u2026" })
9992
+ /* @__PURE__ */ jsx33("span", { children: "Working\u2026" })
9998
9993
  ]
9999
9994
  }
10000
9995
  )
10001
9996
  }
10002
9997
  ),
10003
- composerStatusNotice ? /* @__PURE__ */ jsx35(ComposerRuntimeNotice, { notice: composerStatusNotice }) : null,
10004
- composerBlocked && !workspaceWarmupBlocked ? /* @__PURE__ */ jsx35(
9998
+ composerStatusNotice ? /* @__PURE__ */ jsx33(ComposerRuntimeNotice, { notice: composerStatusNotice }) : null,
9999
+ composerBlocked && !workspaceWarmupBlocked ? /* @__PURE__ */ jsx33(
10005
10000
  ComposerBlockerNotice,
10006
10001
  {
10007
10002
  blocker: primaryComposerBlocker,
@@ -10009,8 +10004,8 @@ function PiChatComposerSurface({
10009
10004
  onAction: onComposerBlockerAction
10010
10005
  }
10011
10006
  ) : null,
10012
- queuePreview.length > 0 ? /* @__PURE__ */ jsx35(QueuedComposerNotice, { followUps: queuePreview, onEdit: onEditQueued }) : null,
10013
- hotReloadEnabled ? /* @__PURE__ */ jsx35(
10007
+ queuePreview.length > 0 ? /* @__PURE__ */ jsx33(QueuedComposerNotice, { followUps: queuePreview, onEdit: onEditQueued }) : null,
10008
+ hotReloadEnabled ? /* @__PURE__ */ jsx33(
10014
10009
  PluginUpdateStatus,
10015
10010
  {
10016
10011
  state: pluginUpdateState,
@@ -10018,14 +10013,14 @@ function PiChatComposerSurface({
10018
10013
  onRetry: onRunPluginUpdate
10019
10014
  }
10020
10015
  ) : null,
10021
- /* @__PURE__ */ jsx35(
10016
+ /* @__PURE__ */ jsx33(
10022
10017
  CommandRunStatus,
10023
10018
  {
10024
10019
  state: commandNotifyState,
10025
10020
  onDismiss: onDismissCommandNotify
10026
10021
  }
10027
10022
  ),
10028
- attachmentNotice ? /* @__PURE__ */ jsx35(
10023
+ attachmentNotice ? /* @__PURE__ */ jsx33(
10029
10024
  "div",
10030
10025
  {
10031
10026
  role: "status",
@@ -10034,12 +10029,12 @@ function PiChatComposerSurface({
10034
10029
  children: attachmentNotice
10035
10030
  }
10036
10031
  ) : null,
10037
- /* @__PURE__ */ jsxs30("div", { className: cn("@container group/composer relative mx-auto w-full", chrome ? "max-w-3xl" : "max-w-[680px]"), children: [
10038
- /* @__PURE__ */ jsxs30("div", { className: cn(
10032
+ /* @__PURE__ */ jsxs29("div", { className: cn("@container group/composer relative mx-auto w-full", chrome ? "max-w-3xl" : "max-w-[680px]"), children: [
10033
+ /* @__PURE__ */ jsxs29("div", { className: cn(
10039
10034
  "absolute inset-x-0 z-30",
10040
10035
  pickerPlacement === "above-compact" ? "bottom-[calc(100%+4px)] [&_[cmdk-list]]:!max-h-[200px]" : "bottom-[calc(100%+4px)]"
10041
10036
  ), children: [
10042
- mentionState ? /* @__PURE__ */ jsx35("div", { className: "mr-px ml-[43px]", children: /* @__PURE__ */ jsx35(
10037
+ mentionState ? /* @__PURE__ */ jsx33("div", { className: "mr-px ml-[43px]", children: /* @__PURE__ */ jsx33(
10043
10038
  MentionPicker,
10044
10039
  {
10045
10040
  mention: mentionState,
@@ -10051,7 +10046,7 @@ function PiChatComposerSurface({
10051
10046
  onDismiss: onDismissMention
10052
10047
  }
10053
10048
  ) }) : null,
10054
- slashQuery !== null ? /* @__PURE__ */ jsx35("div", { className: "mr-px ml-[43px]", children: /* @__PURE__ */ jsx35(
10049
+ slashQuery !== null ? /* @__PURE__ */ jsx33("div", { className: "mr-px ml-[43px]", children: /* @__PURE__ */ jsx33(
10055
10050
  SlashCommandPicker,
10056
10051
  {
10057
10052
  query: slashQuery,
@@ -10060,7 +10055,7 @@ function PiChatComposerSurface({
10060
10055
  onDismiss: onDismissSlash
10061
10056
  }
10062
10057
  ) }) : null,
10063
- mentionState === null && slashQuery === null && modelPickerOpen ? /* @__PURE__ */ jsx35("div", { className: "mr-px mb-1 ml-[43px]", children: /* @__PURE__ */ jsx35(
10058
+ mentionState === null && slashQuery === null && modelPickerOpen ? /* @__PURE__ */ jsx33("div", { className: "mr-px mb-1 ml-[43px]", children: /* @__PURE__ */ jsx33(
10064
10059
  ModelPickerMenu,
10065
10060
  {
10066
10061
  value: selectedModel,
@@ -10071,7 +10066,7 @@ function PiChatComposerSurface({
10071
10066
  onClose: () => onSetModelPickerOpen(false)
10072
10067
  }
10073
10068
  ) }) : null,
10074
- mentionState === null && slashQuery === null && thinkingPickerOpen ? /* @__PURE__ */ jsx35("div", { className: "mr-px mb-1 ml-[43px]", children: /* @__PURE__ */ jsx35(
10069
+ mentionState === null && slashQuery === null && thinkingPickerOpen ? /* @__PURE__ */ jsx33("div", { className: "mr-px mb-1 ml-[43px]", children: /* @__PURE__ */ jsx33(
10075
10070
  ThinkingPickerMenu,
10076
10071
  {
10077
10072
  value: selectedThinking,
@@ -10081,17 +10076,17 @@ function PiChatComposerSurface({
10081
10076
  }
10082
10077
  ) }) : null
10083
10078
  ] }),
10084
- composerContributions.map(({ id, Top }) => Top ? /* @__PURE__ */ jsx35(
10079
+ composerContributions.map(({ id, Top }) => Top ? /* @__PURE__ */ jsx33(
10085
10080
  "div",
10086
10081
  {
10087
10082
  "data-boring-agent-part": "composer-contribution-top",
10088
10083
  "data-boring-agent-contribution-id": id,
10089
10084
  className: cn("mx-auto mb-2 w-full empty:hidden", chrome ? "max-w-3xl" : "max-w-[680px]"),
10090
- children: /* @__PURE__ */ jsx35(Top, {})
10085
+ children: /* @__PURE__ */ jsx33(Top, {})
10091
10086
  },
10092
10087
  id
10093
10088
  ) : null),
10094
- /* @__PURE__ */ jsx35(
10089
+ /* @__PURE__ */ jsx33(
10095
10090
  "div",
10096
10091
  {
10097
10092
  "data-boring-agent-part": "composer-rail",
@@ -10110,7 +10105,7 @@ function PiChatComposerSurface({
10110
10105
  "[&[data-composer-multiline=true]_[data-boring-agent-part=composer-submit-addon]]:self-end",
10111
10106
  "[&[data-composer-multiline=true]_[data-boring-agent-part=composer-submit-addon]]:mb-2"
10112
10107
  ),
10113
- children: /* @__PURE__ */ jsxs30(
10108
+ children: /* @__PURE__ */ jsxs29(
10114
10109
  PromptInput,
10115
10110
  {
10116
10111
  "data-boring-state": status,
@@ -10126,15 +10121,15 @@ function PiChatComposerSurface({
10126
10121
  else onAttachmentNotice(err.message || "Attachment rejected.");
10127
10122
  },
10128
10123
  children: [
10129
- /* @__PURE__ */ jsx35(AttachmentsList, {}),
10130
- /* @__PURE__ */ jsxs30(
10124
+ /* @__PURE__ */ jsx33(AttachmentsList, {}),
10125
+ /* @__PURE__ */ jsxs29(
10131
10126
  "div",
10132
10127
  {
10133
10128
  "data-boring-agent-part": "composer-input-row",
10134
10129
  className: "flex min-h-[var(--composer-input-group-height)] w-full items-center",
10135
10130
  children: [
10136
- /* @__PURE__ */ jsx35("div", { className: "flex h-14 shrink-0 items-center pl-2", children: /* @__PURE__ */ jsx35(AttachmentButton, { disabled: disabled || isStreaming }) }),
10137
- /* @__PURE__ */ jsx35(
10131
+ /* @__PURE__ */ jsx33("div", { className: "flex h-14 shrink-0 items-center pl-2", children: /* @__PURE__ */ jsx33(AttachmentButton, { disabled: disabled || isStreaming }) }),
10132
+ /* @__PURE__ */ jsx33(
10138
10133
  PromptInputTextarea,
10139
10134
  {
10140
10135
  value: draft,
@@ -10158,24 +10153,24 @@ function PiChatComposerSurface({
10158
10153
  )
10159
10154
  }
10160
10155
  ),
10161
- /* @__PURE__ */ jsx35(
10156
+ /* @__PURE__ */ jsx33(
10162
10157
  PromptInputFooter,
10163
10158
  {
10164
10159
  align: "inline-end",
10165
10160
  "data-boring-agent-part": "composer-submit-addon",
10166
10161
  className: "!order-none !w-auto shrink-0 self-center justify-between border-0 bg-transparent !px-2 !py-0",
10167
- children: /* @__PURE__ */ jsxs30("div", { className: "ml-auto flex items-center gap-1.5", children: [
10168
- composerContributions.map(({ id, Action }) => Action ? /* @__PURE__ */ jsx35(
10162
+ children: /* @__PURE__ */ jsxs29("div", { className: "ml-auto flex items-center gap-1.5", children: [
10163
+ composerContributions.map(({ id, Action }) => Action ? /* @__PURE__ */ jsx33(
10169
10164
  "span",
10170
10165
  {
10171
10166
  "data-boring-agent-part": "composer-contribution-action",
10172
10167
  "data-boring-agent-contribution-id": id,
10173
10168
  className: "contents",
10174
- children: /* @__PURE__ */ jsx35(Action, { updateDraft })
10169
+ children: /* @__PURE__ */ jsx33(Action, { updateDraft })
10175
10170
  },
10176
10171
  id
10177
10172
  ) : null),
10178
- /* @__PURE__ */ jsx35(
10173
+ /* @__PURE__ */ jsx33(
10179
10174
  PromptInputSubmit,
10180
10175
  {
10181
10176
  "data-boring-agent-part": "composer-submit",
@@ -10205,7 +10200,7 @@ function PiChatComposerSurface({
10205
10200
  )
10206
10201
  }
10207
10202
  ),
10208
- hideComposerSettings ? null : /* @__PURE__ */ jsx35(
10203
+ hideComposerSettings ? null : /* @__PURE__ */ jsx33(
10209
10204
  "div",
10210
10205
  {
10211
10206
  "data-boring-agent-part": "composer-settings-row",
@@ -10213,11 +10208,13 @@ function PiChatComposerSurface({
10213
10208
  "mx-auto mt-2 grid min-h-8 w-full grid-cols-[minmax(0,1fr)_auto] items-center text-xs text-muted-foreground",
10214
10209
  chrome ? "max-w-3xl" : "max-w-[680px]"
10215
10210
  ),
10216
- children: /* @__PURE__ */ jsxs30("div", { className: "flex min-w-0 items-center justify-center gap-1", children: [
10217
- /* @__PURE__ */ jsx35(
10211
+ children: /* @__PURE__ */ jsxs29("div", { className: "flex min-w-0 items-center justify-center gap-1", children: [
10212
+ /* @__PURE__ */ jsx33(
10218
10213
  ModelSelectTrigger,
10219
10214
  {
10220
10215
  value: selectedModel,
10216
+ sessionModel,
10217
+ isOverride: modelOverride,
10221
10218
  options: modelOptions,
10222
10219
  disabled: isStreaming || modelControlled,
10223
10220
  trigger: "slash",
@@ -10232,7 +10229,7 @@ function PiChatComposerSurface({
10232
10229
  }
10233
10230
  }
10234
10231
  ),
10235
- thinkingControl ? /* @__PURE__ */ jsx35(
10232
+ thinkingControl ? /* @__PURE__ */ jsx33(
10236
10233
  ThinkingSelectTrigger,
10237
10234
  {
10238
10235
  value: selectedThinking,
@@ -10261,7 +10258,7 @@ function getHeaderValue(headers, name) {
10261
10258
  }
10262
10259
 
10263
10260
  // src/front/chat/piChatPanelHooks.ts
10264
- import { useCallback as useCallback17, useEffect as useEffect20, useMemo as useMemo15, useRef as useRef17, useState as useState19, useSyncExternalStore } from "react";
10261
+ import { useCallback as useCallback17, useEffect as useEffect20, useMemo as useMemo15, useRef as useRef16, useState as useState19, useSyncExternalStore } from "react";
10265
10262
 
10266
10263
  // src/front/chat/piChatPanelUtils.ts
10267
10264
  function headersContentKey(headers) {
@@ -10382,7 +10379,7 @@ function useExternalRemotePiSession({
10382
10379
  enabled = true
10383
10380
  }) {
10384
10381
  const [session, setSession] = useState19();
10385
- const remoteSessionOptionsRef = useRef17(remoteSessionOptions);
10382
+ const remoteSessionOptionsRef = useRef16(remoteSessionOptions);
10386
10383
  remoteSessionOptionsRef.current = remoteSessionOptions;
10387
10384
  const requestHeadersKey = headersContentKey(requestHeaders);
10388
10385
  const stableRequestHeaders = useMemo15(
@@ -10463,8 +10460,8 @@ function useRemotePiSessionState(session) {
10463
10460
  }
10464
10461
 
10465
10462
  // src/front/chat/PiChatPanel.tsx
10466
- import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
10467
- var DebugDrawer2 = lazy(() => import("../DebugDrawer-2TO5SE2D.js").then((m) => ({ default: m.DebugDrawer })));
10463
+ import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
10464
+ var DebugDrawer2 = lazy(() => import("../DebugDrawer-JNA43SVR.js").then((m) => ({ default: m.DebugDrawer })));
10468
10465
  var EMPTY_COMMANDS = [];
10469
10466
  var EMPTY_COMMAND_NAMES = [];
10470
10467
  var EMPTY_BLOCKERS = [];
@@ -10535,11 +10532,11 @@ function PiChatPanel({
10535
10532
  }) {
10536
10533
  const externalSessionId = sessionId?.trim() || void 0;
10537
10534
  const showSessionSidebar = showSessions ?? externalSessionId === void 0;
10538
- const onDataRef = useRef18(onData);
10535
+ const onDataRef = useRef17(onData);
10539
10536
  onDataRef.current = onData;
10540
- const onTurnCompleteRef = useRef18(onTurnComplete);
10537
+ const onTurnCompleteRef = useRef17(onTurnComplete);
10541
10538
  onTurnCompleteRef.current = onTurnComplete;
10542
- const sessionListRefreshRef = useRef18(void 0);
10539
+ const sessionListRefreshRef = useRef17(void 0);
10543
10540
  const requestHeadersKey = useMemo16(() => headersContentKey(requestHeaders), [requestHeaders]);
10544
10541
  const normalizedRequestHeaders = useMemo16(() => normalizedHeadersFromContentKey(requestHeadersKey), [requestHeadersKey]);
10545
10542
  const remoteSessionOptionsWithEvents = useMemo16(() => ({
@@ -10603,13 +10600,21 @@ function PiChatPanel({
10603
10600
  agentTypeId,
10604
10601
  apiBaseUrl,
10605
10602
  defaultModel,
10603
+ sessionId: activeSessionId,
10604
+ sessionHydrated: selectedChatState?.hydrated ?? false,
10605
+ sessionIsNew: Boolean(
10606
+ selectedChatState?.hydrated && selectedChatState.history.messageCount === 0 && selectedChatState.committedMessages.length === 0 && selectedChatState.queue.followUps.length === 0 && Object.keys(selectedChatState.optimisticOutbox).length === 0 && !selectedChatState.streamingMessage
10607
+ ),
10608
+ sessionModel: selectedChatState?.currentModel,
10606
10609
  fetch: fetch2,
10607
10610
  requestHeaders: normalizedRequestHeaders,
10608
10611
  storage,
10609
10612
  storageScope,
10610
10613
  enabled: modelDiscoveryEnabled
10611
10614
  });
10615
+ const sessionModel = selectedChatState?.currentModel;
10612
10616
  const selectedModel = model === void 0 ? modelDiscovery.model : model;
10617
+ const modelOverride = model === void 0 ? modelDiscovery.isOverride : Boolean(model && sessionModel && (model.provider !== sessionModel.provider || model.id !== sessionModel.id));
10613
10618
  const modelOptions = useMemo16(
10614
10619
  () => modelOptionsForSelection(availableModels ?? modelDiscovery.availableModels, selectedModel),
10615
10620
  [availableModels, modelDiscovery.availableModels, selectedModel]
@@ -10648,13 +10653,13 @@ function PiChatPanel({
10648
10653
  const [modelPickerOpen, setModelPickerOpen] = useState20(false);
10649
10654
  const [thinkingPickerOpen, setThinkingPickerOpen] = useState20(false);
10650
10655
  const [draft, setDraft] = useState20(() => initialDraft ?? "");
10651
- const draftRef = useRef18(draft);
10656
+ const draftRef = useRef17(draft);
10652
10657
  draftRef.current = draft;
10653
- const initialDraftGuard = useRef18(new InitialDraftAutoSubmitGuard());
10654
- const pendingAutoSubmitSettleRef = useRef18(void 0);
10655
- const acceptedAutoSubmitSettleRef = useRef18(void 0);
10656
- const resetInProgressRef = useRef18(false);
10657
- const autoCreateInFlightRef = useRef18(false);
10658
+ const initialDraftGuard = useRef17(new InitialDraftAutoSubmitGuard());
10659
+ const pendingAutoSubmitSettleRef = useRef17(void 0);
10660
+ const acceptedAutoSubmitSettleRef = useRef17(void 0);
10661
+ const resetInProgressRef = useRef17(false);
10662
+ const autoCreateInFlightRef = useRef17(false);
10658
10663
  const settlePendingAutoSubmit = useCallback18((sessionId2) => {
10659
10664
  const pendingSessionId = pendingAutoSubmitSettleRef.current;
10660
10665
  if (!pendingSessionId || sessionId2 && pendingSessionId !== sessionId2) return false;
@@ -10663,19 +10668,19 @@ function PiChatPanel({
10663
10668
  onAutoSubmitInitialDraftSettled?.();
10664
10669
  return true;
10665
10670
  }, [onAutoSubmitInitialDraftSettled]);
10666
- const prevStatusRef = useRef18("idle");
10667
- const statusRef = useRef18("idle");
10668
- const scrollToBottomRef = useRef18(() => {
10671
+ const prevStatusRef = useRef17("idle");
10672
+ const statusRef = useRef17("idle");
10673
+ const scrollToBottomRef = useRef17(() => {
10669
10674
  });
10670
- const textareaRef = useRef18(null);
10675
+ const textareaRef = useRef17(null);
10671
10676
  const [localNotices, setLocalNotices] = useState20([]);
10672
10677
  const [dismissedNoticeIds, setDismissedNoticeIds] = useState20(() => /* @__PURE__ */ new Set());
10673
10678
  const [pluginUpdateState, setPluginUpdateState] = useState20(null);
10674
10679
  const [commandNotifyState, setCommandNotifyState] = useState20(null);
10675
- const commandRunIdRef = useRef18(0);
10680
+ const commandRunIdRef = useRef17(0);
10676
10681
  const [serverSkillsRefreshKey, setServerSkillsRefreshKey] = useState20(0);
10677
10682
  const [localSubmittedSessionId, setLocalSubmittedSessionId] = useState20();
10678
- const localSubmittedSessionRef = useRef18(void 0);
10683
+ const localSubmittedSessionRef = useRef17(void 0);
10679
10684
  const { attachmentNotice, setAttachmentNotice } = useAttachmentNotice();
10680
10685
  const composerContributions = useComposerContributions();
10681
10686
  const contributedCommands = useMemo16(
@@ -11267,7 +11272,7 @@ function PiChatPanel({
11267
11272
  if (result === false) setComposerDraft(text);
11268
11273
  });
11269
11274
  }, [sendComposerMessage, setComposerDraft]);
11270
- const composerSurface = /* @__PURE__ */ jsx36(
11275
+ const composerSurface = /* @__PURE__ */ jsx34(
11271
11276
  PiChatComposerSurface,
11272
11277
  {
11273
11278
  chrome,
@@ -11307,6 +11312,8 @@ function PiChatPanel({
11307
11312
  onDismissSlash: dismissSlash,
11308
11313
  modelPickerOpen,
11309
11314
  selectedModel,
11315
+ sessionModel,
11316
+ modelOverride,
11310
11317
  modelOptions,
11311
11318
  modelControlled: model !== void 0,
11312
11319
  hideDefaultModelOption,
@@ -11332,7 +11339,7 @@ function PiChatPanel({
11332
11339
  onStop: stop
11333
11340
  }
11334
11341
  );
11335
- return /* @__PURE__ */ jsx36(ArtifactOpenProvider, { onOpenArtifact, children: /* @__PURE__ */ jsxs31(
11342
+ return /* @__PURE__ */ jsx34(ArtifactOpenProvider, { onOpenArtifact, children: /* @__PURE__ */ jsxs30(
11336
11343
  "div",
11337
11344
  {
11338
11345
  "data-boring-agent": "",
@@ -11350,7 +11357,7 @@ function PiChatPanel({
11350
11357
  role: "region",
11351
11358
  "aria-label": "Agent assistant",
11352
11359
  children: [
11353
- showSessionSidebar ? /* @__PURE__ */ jsx36("aside", { "data-boring-agent-part": "pi-chat-session-sidebar", className: "min-h-0 w-64 shrink-0 border-r border-border/60", children: /* @__PURE__ */ jsx36(
11360
+ showSessionSidebar ? /* @__PURE__ */ jsx34("aside", { "data-boring-agent-part": "pi-chat-session-sidebar", className: "min-h-0 w-64 shrink-0 border-r border-border/60", children: /* @__PURE__ */ jsx34(
11354
11361
  SessionList,
11355
11362
  {
11356
11363
  sessions: sessionList,
@@ -11364,7 +11371,7 @@ function PiChatPanel({
11364
11371
  loadingMore: sessions.loadingMore
11365
11372
  }
11366
11373
  ) }) : null,
11367
- /* @__PURE__ */ jsx36("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: /* @__PURE__ */ jsxs31(
11374
+ /* @__PURE__ */ jsx34("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: /* @__PURE__ */ jsxs30(
11368
11375
  "div",
11369
11376
  {
11370
11377
  className: cn(
@@ -11373,7 +11380,7 @@ function PiChatPanel({
11373
11380
  chrome && "mx-3 my-3 rounded-xl bg-[color:var(--surface-chat)] shadow-[0_1px_0_oklch(0_0_0/0.02),0_1px_2px_-1px_oklch(0_0_0/0.04),inset_0_0_0_1px_oklch(from_var(--border)_l_c_h/0.6)]"
11374
11381
  ),
11375
11382
  children: [
11376
- /* @__PURE__ */ jsx36(
11383
+ /* @__PURE__ */ jsx34(
11377
11384
  PiConversationSurface,
11378
11385
  {
11379
11386
  chrome,
@@ -11399,13 +11406,13 @@ function PiChatPanel({
11399
11406
  }
11400
11407
  ),
11401
11408
  composerSurface,
11402
- emptyHero ? /* @__PURE__ */ jsxs31(
11409
+ emptyHero ? /* @__PURE__ */ jsxs30(
11403
11410
  "div",
11404
11411
  {
11405
11412
  "data-boring-agent-part": "empty-hero-suggestions",
11406
11413
  className: "@container mx-auto w-full max-w-[640px] px-2 pb-4",
11407
11414
  children: [
11408
- /* @__PURE__ */ jsx36(ChatSuggestionGrid, { suggestions, onSelect: selectEmptySuggestion, className: "mt-4" }),
11415
+ /* @__PURE__ */ jsx34(ChatSuggestionGrid, { suggestions, onSelect: selectEmptySuggestion, className: "mt-4" }),
11409
11416
  emptyState?.footer
11410
11417
  ]
11411
11418
  }
@@ -11413,7 +11420,7 @@ function PiChatPanel({
11413
11420
  ]
11414
11421
  }
11415
11422
  ) }),
11416
- debug ? /* @__PURE__ */ jsx36(Suspense, { fallback: null, children: /* @__PURE__ */ jsx36("div", { "aria-label": "Chat debug metadata", className: "contents", role: "region", children: /* @__PURE__ */ jsx36(
11423
+ debug ? /* @__PURE__ */ jsx34(Suspense, { fallback: null, children: /* @__PURE__ */ jsx34("div", { "aria-label": "Chat debug metadata", className: "contents", role: "region", children: /* @__PURE__ */ jsx34(
11417
11424
  DebugDrawer2,
11418
11425
  {
11419
11426
  agentTypeId,
@@ -11602,7 +11609,13 @@ function getAgentCommands(options = {}) {
11602
11609
  return commands;
11603
11610
  }
11604
11611
  export {
11612
+ Artifact,
11613
+ ArtifactAction,
11614
+ ArtifactActions,
11615
+ ArtifactDescription,
11616
+ ArtifactHeader,
11605
11617
  ArtifactOpenProvider,
11618
+ ArtifactTitle,
11606
11619
  ChatEmptyState,
11607
11620
  ChatMessageContributionProvider,
11608
11621
  PiChatPanel as ChatPanel,