@cookielab.io/klovi 1.0.0 → 1.1.0

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.
@@ -40924,7 +40924,7 @@ var init_all = __esm(() => {
40924
40924
  var favicon_default = "./favicon-39pjvakn.svg";
40925
40925
 
40926
40926
  // src/frontend/App.tsx
40927
- var import_react16 = __toESM(require_react(), 1);
40927
+ var import_react18 = __toESM(require_react(), 1);
40928
40928
  var import_client = __toESM(require_client(), 1);
40929
40929
 
40930
40930
  // src/frontend/hooks/useFetch.ts
@@ -54061,6 +54061,9 @@ function DiffView({ filePath, oldString, newString }) {
54061
54061
  }, undefined, true, undefined, this);
54062
54062
  }
54063
54063
 
54064
+ // src/frontend/components/message/SmartToolOutput.tsx
54065
+ var import_react11 = __toESM(require_react(), 1);
54066
+
54064
54067
  // src/frontend/utils/format-detector.ts
54065
54068
  function detectOutputFormat(output) {
54066
54069
  const trimmed = output.trim();
@@ -54155,68 +54158,103 @@ function hasCodeStructure(text7) {
54155
54158
  return lines.length >= 2 && /^(export|import|const|let|var|function|class)\s/.test(text7);
54156
54159
  }
54157
54160
 
54158
- // src/frontend/components/message/SmartToolOutput.tsx
54161
+ // src/frontend/components/ui/ImageLightbox.tsx
54162
+ var import_react10 = __toESM(require_react(), 1);
54159
54163
  var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
54164
+ function ImageLightbox({ src, onClose }) {
54165
+ const [visible, setVisible] = import_react10.useState(false);
54166
+ const handleClose = import_react10.useCallback(() => {
54167
+ setVisible(false);
54168
+ setTimeout(onClose, 200);
54169
+ }, [onClose]);
54170
+ import_react10.useEffect(() => {
54171
+ requestAnimationFrame(() => {
54172
+ requestAnimationFrame(() => setVisible(true));
54173
+ });
54174
+ }, []);
54175
+ import_react10.useEffect(() => {
54176
+ const handleKey = (e) => {
54177
+ if (e.key === "Escape")
54178
+ handleClose();
54179
+ };
54180
+ document.addEventListener("keydown", handleKey);
54181
+ return () => document.removeEventListener("keydown", handleKey);
54182
+ }, [handleClose]);
54183
+ return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
54184
+ className: `lightbox-overlay ${visible ? "lightbox-visible" : ""}`,
54185
+ onClick: handleClose,
54186
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("img", {
54187
+ className: "lightbox-image",
54188
+ src,
54189
+ alt: "Full size preview"
54190
+ }, undefined, false, undefined, this)
54191
+ }, undefined, false, undefined, this);
54192
+ }
54193
+
54194
+ // src/frontend/components/message/SmartToolOutput.tsx
54195
+ var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
54160
54196
  function SmartToolOutput({ output, isError, resultImages }) {
54161
54197
  const truncated = truncateOutput(output);
54162
54198
  const wasTruncated = output.length > MAX_OUTPUT_LENGTH;
54163
54199
  const detectedLang = truncated ? detectOutputFormat(truncated) : null;
54200
+ const [lightboxSrc, setLightboxSrc] = import_react11.useState(null);
54201
+ const closeLightbox = import_react11.useCallback(() => setLightboxSrc(null), []);
54164
54202
  if (!output && (!resultImages || resultImages.length === 0))
54165
54203
  return null;
54166
- return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
54204
+ return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
54167
54205
  children: [
54168
- /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
54206
+ /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
54169
54207
  className: "tool-section-label",
54170
54208
  children: "Output"
54171
54209
  }, undefined, false, undefined, this),
54172
- output && (detectedLang && !isError ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(CodeBlock, {
54210
+ output && (detectedLang && !isError ? /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(CodeBlock, {
54173
54211
  language: detectedLang,
54174
54212
  children: truncated
54175
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
54213
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
54176
54214
  className: `tool-call-output ${isError ? "tool-call-error" : ""}`,
54177
54215
  children: truncated
54178
54216
  }, undefined, false, undefined, this)),
54179
- wasTruncated && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
54217
+ wasTruncated && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
54180
54218
  className: "tool-call-truncated",
54181
54219
  children: "... (truncated)"
54182
54220
  }, undefined, false, undefined, this),
54183
- resultImages && resultImages.length > 0 && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
54221
+ resultImages && resultImages.length > 0 && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
54184
54222
  className: "tool-result-images",
54185
- children: resultImages.map((img, i) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("a", {
54186
- href: `data:${img.mediaType};base64,${img.data}`,
54187
- target: "_blank",
54188
- rel: "noopener noreferrer",
54189
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("img", {
54190
- className: "tool-result-image",
54191
- src: `data:${img.mediaType};base64,${img.data}`,
54192
- alt: `Tool result ${i + 1}`
54193
- }, undefined, false, undefined, this)
54223
+ children: resultImages.map((img, i) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("img", {
54224
+ className: "tool-result-image",
54225
+ src: `data:${img.mediaType};base64,${img.data}`,
54226
+ alt: `Tool result ${i + 1}`,
54227
+ onClick: () => setLightboxSrc(`data:${img.mediaType};base64,${img.data}`)
54194
54228
  }, i, false, undefined, this))
54229
+ }, undefined, false, undefined, this),
54230
+ lightboxSrc && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(ImageLightbox, {
54231
+ src: lightboxSrc,
54232
+ onClose: closeLightbox
54195
54233
  }, undefined, false, undefined, this)
54196
54234
  ]
54197
54235
  }, undefined, true, undefined, this);
54198
54236
  }
54199
54237
 
54200
54238
  // src/frontend/components/message/BashToolContent.tsx
54201
- var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
54239
+ var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
54202
54240
  function BashToolContent({ call }) {
54203
54241
  const command = String(call.input.command || "");
54204
- return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(jsx_dev_runtime11.Fragment, {
54242
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(jsx_dev_runtime12.Fragment, {
54205
54243
  children: [
54206
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
54244
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
54207
54245
  style: { marginBottom: 8 },
54208
54246
  children: [
54209
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("div", {
54247
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
54210
54248
  className: "tool-section-label",
54211
54249
  children: "Command"
54212
54250
  }, undefined, false, undefined, this),
54213
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(CodeBlock, {
54251
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(CodeBlock, {
54214
54252
  language: "bash",
54215
54253
  children: command
54216
54254
  }, undefined, false, undefined, this)
54217
54255
  ]
54218
54256
  }, undefined, true, undefined, this),
54219
- /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(SmartToolOutput, {
54257
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(SmartToolOutput, {
54220
54258
  output: call.result,
54221
54259
  isError: call.isError,
54222
54260
  resultImages: call.resultImages
@@ -54226,7 +54264,7 @@ function BashToolContent({ call }) {
54226
54264
  }
54227
54265
 
54228
54266
  // src/frontend/components/message/ToolCall.tsx
54229
- var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
54267
+ var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
54230
54268
  var MAX_OUTPUT_LENGTH = 5000;
54231
54269
  var MAX_CONTENT_LENGTH = 2000;
54232
54270
  var MAX_THINKING_PREVIEW = 100;
@@ -54239,25 +54277,25 @@ function isJsonFallbackInput(call) {
54239
54277
  function DefaultToolContent({ call }) {
54240
54278
  const formattedInput = formatToolInput(call);
54241
54279
  const jsonInput = isJsonFallbackInput(call);
54242
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(jsx_dev_runtime12.Fragment, {
54280
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(jsx_dev_runtime13.Fragment, {
54243
54281
  children: [
54244
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
54282
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
54245
54283
  style: { marginBottom: 8 },
54246
54284
  children: [
54247
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
54285
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
54248
54286
  className: "tool-section-label",
54249
54287
  children: "Input"
54250
54288
  }, undefined, false, undefined, this),
54251
- jsonInput ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(CodeBlock, {
54289
+ jsonInput ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(CodeBlock, {
54252
54290
  language: "json",
54253
54291
  children: formattedInput
54254
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
54292
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
54255
54293
  className: "tool-call-input",
54256
54294
  children: formattedInput
54257
54295
  }, undefined, false, undefined, this)
54258
54296
  ]
54259
54297
  }, undefined, true, undefined, this),
54260
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(SmartToolOutput, {
54298
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(SmartToolOutput, {
54261
54299
  output: call.result,
54262
54300
  isError: call.isError,
54263
54301
  resultImages: call.resultImages
@@ -54271,35 +54309,35 @@ function ToolCall({ call, sessionId, project }) {
54271
54309
  const skillName = getSkillName(call);
54272
54310
  const hasSubAgent = call.name === "Task" && call.subAgentId && sessionId && project;
54273
54311
  const displayName = hasSubAgent ? "Sub-Agent" : mcpServer ? call.name.split("__").slice(1).join("__").replace(/__/g, " > ") : skillName ?? call.name;
54274
- return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
54312
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
54275
54313
  className: "tool-call",
54276
- children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(CollapsibleSection, {
54277
- title: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("span", {
54314
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(CollapsibleSection, {
54315
+ title: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
54278
54316
  children: [
54279
- mcpServer && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("span", {
54317
+ mcpServer && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
54280
54318
  className: "tool-mcp-server",
54281
54319
  children: mcpServer
54282
54320
  }, undefined, false, undefined, this),
54283
- skillName && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("span", {
54321
+ skillName && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
54284
54322
  className: "tool-skill-badge",
54285
54323
  children: "skill"
54286
54324
  }, undefined, false, undefined, this),
54287
- /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("span", {
54325
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
54288
54326
  className: "tool-call-name",
54289
54327
  children: displayName
54290
54328
  }, undefined, false, undefined, this),
54291
- summary && !skillName && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("span", {
54329
+ summary && !skillName && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
54292
54330
  className: "tool-call-summary",
54293
54331
  children: [
54294
54332
  " — ",
54295
54333
  summary
54296
54334
  ]
54297
54335
  }, undefined, true, undefined, this),
54298
- call.isError && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("span", {
54336
+ call.isError && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
54299
54337
  className: "tool-call-error",
54300
54338
  children: " (error)"
54301
54339
  }, undefined, false, undefined, this),
54302
- hasSubAgent && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("a", {
54340
+ hasSubAgent && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("a", {
54303
54341
  className: "subagent-link",
54304
54342
  href: `#/${project}/${sessionId}/subagent/${call.subAgentId}`,
54305
54343
  onClick: (e) => e.stopPropagation(),
@@ -54307,13 +54345,13 @@ function ToolCall({ call, sessionId, project }) {
54307
54345
  }, undefined, false, undefined, this)
54308
54346
  ]
54309
54347
  }, undefined, true, undefined, this),
54310
- children: isEditWithDiff(call) ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(DiffView, {
54348
+ children: isEditWithDiff(call) ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(DiffView, {
54311
54349
  filePath: String(call.input.file_path || ""),
54312
54350
  oldString: String(call.input.old_string),
54313
54351
  newString: String(call.input.new_string)
54314
- }, undefined, false, undefined, this) : call.name === "Bash" ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(BashToolContent, {
54352
+ }, undefined, false, undefined, this) : call.name === "Bash" ? /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(BashToolContent, {
54315
54353
  call
54316
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(DefaultToolContent, {
54354
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(DefaultToolContent, {
54317
54355
  call
54318
54356
  }, undefined, false, undefined, this)
54319
54357
  }, undefined, false, undefined, this)
@@ -54529,28 +54567,28 @@ function truncateOutput(s2) {
54529
54567
  }
54530
54568
 
54531
54569
  // src/frontend/components/message/ThinkingBlock.tsx
54532
- var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
54570
+ var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
54533
54571
  function ThinkingBlock({ block }) {
54534
54572
  const preview = block.text.length > MAX_THINKING_PREVIEW ? `${block.text.slice(0, MAX_THINKING_PREVIEW)}...` : block.text;
54535
- return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
54573
+ return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54536
54574
  className: "thinking-block",
54537
- children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(CollapsibleSection, {
54538
- title: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
54575
+ children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(CollapsibleSection, {
54576
+ title: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
54539
54577
  children: [
54540
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
54578
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
54541
54579
  style: { color: "var(--text-muted)" },
54542
54580
  children: "Thinking:"
54543
54581
  }, undefined, false, undefined, this),
54544
54582
  " ",
54545
- /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
54583
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
54546
54584
  className: "tool-call-summary",
54547
54585
  children: preview
54548
54586
  }, undefined, false, undefined, this)
54549
54587
  ]
54550
54588
  }, undefined, true, undefined, this),
54551
- children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
54589
+ children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54552
54590
  className: "thinking-content",
54553
- children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(MarkdownRenderer, {
54591
+ children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(MarkdownRenderer, {
54554
54592
  content: block.text
54555
54593
  }, undefined, false, undefined, this)
54556
54594
  }, undefined, false, undefined, this)
@@ -54559,20 +54597,20 @@ function ThinkingBlock({ block }) {
54559
54597
  }
54560
54598
 
54561
54599
  // src/frontend/components/message/AssistantMessage.tsx
54562
- var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
54600
+ var jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
54563
54601
  function renderGroup(group, sessionId, project) {
54564
54602
  return group.map((block, i) => {
54565
54603
  if (block.type === "thinking") {
54566
- return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(ThinkingBlock, {
54604
+ return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(ThinkingBlock, {
54567
54605
  block: block.block
54568
54606
  }, `thinking-${i}`, false, undefined, this);
54569
54607
  }
54570
54608
  if (block.type === "text") {
54571
- return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(MarkdownRenderer, {
54609
+ return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(MarkdownRenderer, {
54572
54610
  content: block.text
54573
54611
  }, `text-${i}`, false, undefined, this);
54574
54612
  }
54575
- return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(ToolCall, {
54613
+ return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(ToolCall, {
54576
54614
  call: block.call,
54577
54615
  sessionId,
54578
54616
  project
@@ -54580,21 +54618,21 @@ function renderGroup(group, sessionId, project) {
54580
54618
  });
54581
54619
  }
54582
54620
  function UsageFooter({ usage }) {
54583
- return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54621
+ return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54584
54622
  className: "token-usage",
54585
54623
  children: [
54586
54624
  usage.inputTokens.toLocaleString(),
54587
54625
  " in / ",
54588
54626
  usage.outputTokens.toLocaleString(),
54589
54627
  " out",
54590
- usage.cacheReadTokens && usage.cacheReadTokens > 0 && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
54628
+ usage.cacheReadTokens && usage.cacheReadTokens > 0 && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
54591
54629
  children: [
54592
54630
  " · ",
54593
54631
  usage.cacheReadTokens.toLocaleString(),
54594
54632
  " cache read"
54595
54633
  ]
54596
54634
  }, undefined, true, undefined, this),
54597
- usage.cacheCreationTokens && usage.cacheCreationTokens > 0 && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
54635
+ usage.cacheCreationTokens && usage.cacheCreationTokens > 0 && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
54598
54636
  children: [
54599
54637
  " · ",
54600
54638
  usage.cacheCreationTokens.toLocaleString(),
@@ -54619,21 +54657,21 @@ function AssistantMessage({
54619
54657
  const introGroup = hasNonText && firstIsText ? visibleGroups[0] : null;
54620
54658
  const treeGroups = hasNonText ? introGroup ? visibleGroups.slice(1) : visibleGroups : [];
54621
54659
  const flatGroups = hasNonText ? [] : visibleGroups;
54622
- return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54660
+ return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54623
54661
  className: "turn",
54624
54662
  children: [
54625
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54663
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54626
54664
  className: "turn-header",
54627
54665
  children: [
54628
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
54666
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
54629
54667
  className: "turn-badge turn-badge-assistant",
54630
54668
  children: "Assistant"
54631
54669
  }, undefined, false, undefined, this),
54632
- turn.model && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("span", {
54670
+ turn.model && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
54633
54671
  className: "turn-badge turn-badge-model",
54634
54672
  children: shortModel(turn.model)
54635
54673
  }, undefined, false, undefined, this),
54636
- turn.timestamp && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("time", {
54674
+ turn.timestamp && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("time", {
54637
54675
  className: "turn-timestamp",
54638
54676
  dateTime: turn.timestamp,
54639
54677
  "data-tooltip": formatFullDateTime(turn.timestamp),
@@ -54641,25 +54679,25 @@ function AssistantMessage({
54641
54679
  }, undefined, false, undefined, this)
54642
54680
  ]
54643
54681
  }, undefined, true, undefined, this),
54644
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54682
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54645
54683
  className: "message message-assistant",
54646
54684
  children: [
54647
- introGroup && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54685
+ introGroup && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54648
54686
  className: isPresentation && treeGroups.length === 0 ? "step-enter" : "",
54649
54687
  children: renderGroup(introGroup, sessionId, project)
54650
54688
  }, undefined, false, undefined, this),
54651
- treeGroups.length > 0 && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54689
+ treeGroups.length > 0 && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54652
54690
  className: "exec-tree",
54653
- children: treeGroups.map((group, i) => /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54691
+ children: treeGroups.map((group, i) => /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54654
54692
  className: `tree-node${isPresentation && i === treeGroups.length - 1 ? " step-enter" : ""}`,
54655
54693
  children: renderGroup(group, sessionId, project)
54656
54694
  }, i, false, undefined, this))
54657
54695
  }, undefined, false, undefined, this),
54658
- flatGroups.map((group, i) => /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
54696
+ flatGroups.map((group, i) => /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54659
54697
  className: isPresentation && i === flatGroups.length - 1 ? "step-enter" : "",
54660
54698
  children: renderGroup(group, sessionId, project)
54661
54699
  }, i, false, undefined, this)),
54662
- turn.usage && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(UsageFooter, {
54700
+ turn.usage && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(UsageFooter, {
54663
54701
  usage: turn.usage
54664
54702
  }, undefined, false, undefined, this)
54665
54703
  ]
@@ -54669,7 +54707,7 @@ function AssistantMessage({
54669
54707
  }
54670
54708
 
54671
54709
  // src/frontend/components/message/UserMessage.tsx
54672
- var jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
54710
+ var jsx_dev_runtime16 = __toESM(require_jsx_dev_runtime(), 1);
54673
54711
  var STATUS_RE = /^\[.+\]$/;
54674
54712
  var PLAN_PREFIX = "Implement the following plan";
54675
54713
  function UserMessage({
@@ -54680,14 +54718,14 @@ function UserMessage({
54680
54718
  project
54681
54719
  }) {
54682
54720
  if (turn.bashInput !== undefined) {
54683
- return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54721
+ return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54684
54722
  className: "status-notice bash-input-notice",
54685
54723
  children: [
54686
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
54724
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
54687
54725
  className: "bash-input-prompt",
54688
54726
  children: "$"
54689
54727
  }, undefined, false, undefined, this),
54690
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("code", {
54728
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("code", {
54691
54729
  className: "bash-input-command",
54692
54730
  children: turn.bashInput
54693
54731
  }, undefined, false, undefined, this)
@@ -54695,11 +54733,11 @@ function UserMessage({
54695
54733
  }, undefined, true, undefined, this);
54696
54734
  }
54697
54735
  if (turn.ideOpenedFile !== undefined) {
54698
- return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54736
+ return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54699
54737
  className: "status-notice ide-opened-file-notice",
54700
54738
  children: [
54701
54739
  "Opened ",
54702
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("code", {
54740
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("code", {
54703
54741
  className: "ide-opened-file-path",
54704
54742
  children: turn.ideOpenedFile
54705
54743
  }, undefined, false, undefined, this)
@@ -54708,7 +54746,7 @@ function UserMessage({
54708
54746
  }
54709
54747
  const isStatus = STATUS_RE.test(turn.text.trim());
54710
54748
  if (isStatus) {
54711
- return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54749
+ return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54712
54750
  className: "status-notice",
54713
54751
  children: turn.text
54714
54752
  }, undefined, false, undefined, this);
@@ -54718,27 +54756,27 @@ function UserMessage({
54718
54756
  const showImplLink = implSessionId && project && !isPlanMessage;
54719
54757
  const role = isSubAgent ? "Root Agent" : "User";
54720
54758
  const badgeClass = isSubAgent ? "turn-badge-agent" : "turn-badge-user";
54721
- return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54759
+ return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54722
54760
  className: "turn",
54723
54761
  children: [
54724
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54762
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54725
54763
  className: "turn-header",
54726
54764
  children: [
54727
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
54765
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
54728
54766
  className: `turn-badge ${badgeClass}`,
54729
54767
  children: role
54730
54768
  }, undefined, false, undefined, this),
54731
- showPlanLink && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("a", {
54769
+ showPlanLink && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("a", {
54732
54770
  className: "subagent-link",
54733
54771
  href: `#/${project}/${planSessionId}`,
54734
54772
  children: "View planning session"
54735
54773
  }, undefined, false, undefined, this),
54736
- showImplLink && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("a", {
54774
+ showImplLink && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("a", {
54737
54775
  className: "subagent-link",
54738
54776
  href: `#/${project}/${implSessionId}`,
54739
54777
  children: "View implementation session"
54740
54778
  }, undefined, false, undefined, this),
54741
- turn.timestamp && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("time", {
54779
+ turn.timestamp && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("time", {
54742
54780
  className: "turn-timestamp",
54743
54781
  dateTime: turn.timestamp,
54744
54782
  "data-tooltip": formatFullDateTime(turn.timestamp),
@@ -54746,28 +54784,28 @@ function UserMessage({
54746
54784
  }, undefined, false, undefined, this)
54747
54785
  ]
54748
54786
  }, undefined, true, undefined, this),
54749
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54787
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54750
54788
  className: `message ${isSubAgent ? "message-root-agent" : "message-user"}`,
54751
54789
  children: [
54752
- turn.command && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54790
+ turn.command && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54753
54791
  className: "command-call",
54754
54792
  children: [
54755
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
54793
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
54756
54794
  className: "tool-skill-badge",
54757
54795
  children: "skill"
54758
54796
  }, undefined, false, undefined, this),
54759
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
54797
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
54760
54798
  className: "command-call-label",
54761
54799
  children: turn.command.name
54762
54800
  }, undefined, false, undefined, this)
54763
54801
  ]
54764
54802
  }, undefined, true, undefined, this),
54765
- /* @__PURE__ */ jsx_dev_runtime15.jsxDEV(MarkdownRenderer, {
54803
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(MarkdownRenderer, {
54766
54804
  content: turn.text
54767
54805
  }, undefined, false, undefined, this),
54768
- turn.attachments && turn.attachments.length > 0 && /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
54806
+ turn.attachments && turn.attachments.length > 0 && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54769
54807
  className: "attachments",
54770
- children: turn.attachments.map((a, i) => /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("span", {
54808
+ children: turn.attachments.map((a, i) => /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
54771
54809
  className: "attachment-badge",
54772
54810
  children: [
54773
54811
  "image/",
@@ -54782,14 +54820,14 @@ function UserMessage({
54782
54820
  }
54783
54821
 
54784
54822
  // src/frontend/components/message/MessageList.tsx
54785
- var jsx_dev_runtime16 = __toESM(require_jsx_dev_runtime(), 1);
54823
+ var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
54786
54824
  function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project, isSubAgent, planSessionId, implSessionId) {
54787
54825
  const activeClass = isActive ? "active-message" : "";
54788
54826
  switch (turn.kind) {
54789
54827
  case "user":
54790
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54828
+ return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54791
54829
  className: isActive ? "active-message step-enter" : "",
54792
- children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(UserMessage, {
54830
+ children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(UserMessage, {
54793
54831
  turn,
54794
54832
  isSubAgent,
54795
54833
  planSessionId,
@@ -54798,9 +54836,9 @@ function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project,
54798
54836
  }, undefined, false, undefined, this)
54799
54837
  }, undefined, false, undefined, this);
54800
54838
  case "assistant":
54801
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54839
+ return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54802
54840
  className: activeClass,
54803
- children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(AssistantMessage, {
54841
+ children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(AssistantMessage, {
54804
54842
  turn,
54805
54843
  visibleSubSteps: visibleSubSteps?.get(index2),
54806
54844
  sessionId,
@@ -54808,17 +54846,17 @@ function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project,
54808
54846
  }, undefined, false, undefined, this)
54809
54847
  }, undefined, false, undefined, this);
54810
54848
  case "system":
54811
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54849
+ return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54812
54850
  className: `turn ${activeClass}`,
54813
54851
  children: [
54814
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54852
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54815
54853
  className: "turn-header",
54816
54854
  children: [
54817
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
54855
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
54818
54856
  className: "turn-badge turn-badge-system",
54819
54857
  children: "System"
54820
54858
  }, undefined, false, undefined, this),
54821
- turn.timestamp && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("time", {
54859
+ turn.timestamp && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("time", {
54822
54860
  className: "turn-timestamp",
54823
54861
  dateTime: turn.timestamp,
54824
54862
  "data-tooltip": formatFullDateTime(turn.timestamp),
@@ -54826,26 +54864,26 @@ function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project,
54826
54864
  }, undefined, false, undefined, this)
54827
54865
  ]
54828
54866
  }, undefined, true, undefined, this),
54829
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54867
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54830
54868
  className: "message message-system",
54831
- children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(MarkdownRenderer, {
54869
+ children: /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(MarkdownRenderer, {
54832
54870
  content: turn.text
54833
54871
  }, undefined, false, undefined, this)
54834
54872
  }, undefined, false, undefined, this)
54835
54873
  ]
54836
54874
  }, undefined, true, undefined, this);
54837
54875
  case "parse_error":
54838
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54876
+ return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54839
54877
  className: `turn ${activeClass}`,
54840
54878
  children: [
54841
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54879
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54842
54880
  className: "turn-header",
54843
54881
  children: [
54844
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
54882
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
54845
54883
  className: "turn-badge turn-badge-error",
54846
54884
  children: "Parse Error"
54847
54885
  }, undefined, false, undefined, this),
54848
- turn.lineNumber > 0 && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("span", {
54886
+ turn.lineNumber > 0 && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
54849
54887
  className: "parse-error-line",
54850
54888
  children: [
54851
54889
  "line ",
@@ -54854,24 +54892,24 @@ function renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project,
54854
54892
  }, undefined, true, undefined, this)
54855
54893
  ]
54856
54894
  }, undefined, true, undefined, this),
54857
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54895
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54858
54896
  className: "message message-parse-error",
54859
54897
  children: [
54860
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54898
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54861
54899
  className: "parse-error-type",
54862
54900
  children: turn.errorType === "json_parse" ? "Invalid JSON" : "Invalid Structure"
54863
54901
  }, undefined, false, undefined, this),
54864
- turn.errorDetails && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54902
+ turn.errorDetails && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54865
54903
  className: "parse-error-details",
54866
54904
  children: turn.errorDetails
54867
54905
  }, undefined, false, undefined, this),
54868
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("details", {
54906
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("details", {
54869
54907
  className: "parse-error-raw",
54870
54908
  children: [
54871
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("summary", {
54909
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("summary", {
54872
54910
  children: "Raw content"
54873
54911
  }, undefined, false, undefined, this),
54874
- /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("pre", {
54912
+ /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("pre", {
54875
54913
  children: turn.rawLine
54876
54914
  }, undefined, false, undefined, this)
54877
54915
  ]
@@ -54899,11 +54937,11 @@ function MessageList({
54899
54937
  return false;
54900
54938
  return !STATUS_RE2.test(t.text.trim());
54901
54939
  });
54902
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
54940
+ return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54903
54941
  className: "message-list",
54904
54942
  children: turns.map((turn, index2) => {
54905
54943
  const isActive = visibleSubSteps ? index2 === turns.length - 1 : false;
54906
- return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV(ErrorBoundary, {
54944
+ return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(ErrorBoundary, {
54907
54945
  inline: true,
54908
54946
  children: renderTurn(turn, index2, isActive, visibleSubSteps, sessionId, project, isSubAgent, planSessionId, index2 === firstUserTurnIndex ? implSessionId : undefined)
54909
54947
  }, turn.uuid || index2, false, undefined, this);
@@ -54912,26 +54950,26 @@ function MessageList({
54912
54950
  }
54913
54951
 
54914
54952
  // src/frontend/components/message/SubAgentView.tsx
54915
- var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
54953
+ var jsx_dev_runtime18 = __toESM(require_jsx_dev_runtime(), 1);
54916
54954
  function SubAgentView({ sessionId, project, agentId }) {
54917
54955
  const { data, loading, error, retry } = useFetch(`/api/sessions/${sessionId}/subagents/${agentId}?project=${encodeURIComponent(project)}`, [sessionId, project, agentId]);
54918
54956
  if (loading)
54919
- return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54957
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
54920
54958
  className: "loading",
54921
54959
  children: "Loading sub-agent conversation..."
54922
54960
  }, undefined, false, undefined, this);
54923
54961
  if (error) {
54924
- return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54962
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
54925
54963
  className: "fetch-error",
54926
54964
  children: [
54927
- /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
54965
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
54928
54966
  className: "fetch-error-message",
54929
54967
  children: [
54930
54968
  "Error: ",
54931
54969
  error
54932
54970
  ]
54933
54971
  }, undefined, true, undefined, this),
54934
- /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("button", {
54972
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("button", {
54935
54973
  type: "button",
54936
54974
  className: "btn btn-sm",
54937
54975
  onClick: retry,
@@ -54941,11 +54979,11 @@ function SubAgentView({ sessionId, project, agentId }) {
54941
54979
  }, undefined, true, undefined, this);
54942
54980
  }
54943
54981
  if (!data?.session || data.session.turns.length === 0)
54944
- return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("div", {
54982
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
54945
54983
  className: "subagent-empty",
54946
54984
  children: "No sub-agent conversation data available."
54947
54985
  }, undefined, false, undefined, this);
54948
- return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(MessageList, {
54986
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(MessageList, {
54949
54987
  turns: data.session.turns,
54950
54988
  sessionId,
54951
54989
  project,
@@ -54960,25 +54998,25 @@ function projectDisplayName(project) {
54960
54998
  }
54961
54999
 
54962
55000
  // src/frontend/components/project/HiddenProjectList.tsx
54963
- var jsx_dev_runtime18 = __toESM(require_jsx_dev_runtime(), 1);
55001
+ var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
54964
55002
  function HiddenProjectList({ hiddenIds, onUnhide, onBack }) {
54965
55003
  const { data, loading, error, retry } = useFetch("/api/projects", []);
54966
55004
  const projects = data?.projects ?? [];
54967
55005
  const hidden = projects.filter((p) => hiddenIds.has(p.encodedPath));
54968
55006
  if (loading)
54969
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55007
+ return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
54970
55008
  className: "loading",
54971
55009
  children: "Loading..."
54972
55010
  }, undefined, false, undefined, this);
54973
55011
  if (error) {
54974
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55012
+ return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
54975
55013
  className: "fetch-error",
54976
55014
  children: [
54977
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
55015
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("span", {
54978
55016
  className: "fetch-error-message",
54979
55017
  children: error
54980
55018
  }, undefined, false, undefined, this),
54981
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("button", {
55019
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("button", {
54982
55020
  type: "button",
54983
55021
  className: "btn btn-sm",
54984
55022
  onClick: retry,
@@ -54987,40 +55025,40 @@ function HiddenProjectList({ hiddenIds, onUnhide, onBack }) {
54987
55025
  ]
54988
55026
  }, undefined, true, undefined, this);
54989
55027
  }
54990
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55028
+ return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
54991
55029
  className: "hidden-projects-page",
54992
55030
  children: [
54993
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55031
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
54994
55032
  className: "back-btn",
54995
55033
  onClick: onBack,
54996
55034
  children: "← Back to projects"
54997
55035
  }, undefined, false, undefined, this),
54998
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("h2", {
55036
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("h2", {
54999
55037
  style: { margin: "16px 0 12px", fontSize: "1.1rem", color: "var(--text-primary)" },
55000
55038
  children: "Hidden Projects"
55001
55039
  }, undefined, false, undefined, this),
55002
- hidden.length === 0 ? /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55040
+ hidden.length === 0 ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55003
55041
  className: "empty-state",
55004
55042
  children: [
55005
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55043
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55006
55044
  className: "empty-state-title",
55007
55045
  children: "No hidden projects"
55008
55046
  }, undefined, false, undefined, this),
55009
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("p", {
55047
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("p", {
55010
55048
  children: "Projects you hide will appear here"
55011
55049
  }, undefined, false, undefined, this)
55012
55050
  ]
55013
- }, undefined, true, undefined, this) : hidden.map((project) => /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55051
+ }, undefined, true, undefined, this) : hidden.map((project) => /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55014
55052
  className: "list-item list-item-with-action",
55015
55053
  children: [
55016
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55054
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55017
55055
  className: "list-item-content",
55018
55056
  children: [
55019
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55057
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55020
55058
  className: "list-item-title",
55021
55059
  children: projectDisplayName(project)
55022
55060
  }, undefined, false, undefined, this),
55023
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
55061
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55024
55062
  className: "list-item-meta",
55025
55063
  children: [
55026
55064
  project.sessionCount,
@@ -55030,7 +55068,7 @@ function HiddenProjectList({ hiddenIds, onUnhide, onBack }) {
55030
55068
  }, undefined, true, undefined, this)
55031
55069
  ]
55032
55070
  }, undefined, true, undefined, this),
55033
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("button", {
55071
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("button", {
55034
55072
  type: "button",
55035
55073
  className: "btn btn-sm",
55036
55074
  onClick: () => onUnhide(project.encodedPath),
@@ -55043,8 +55081,8 @@ function HiddenProjectList({ hiddenIds, onUnhide, onBack }) {
55043
55081
  }
55044
55082
 
55045
55083
  // src/frontend/components/project/ProjectList.tsx
55046
- var import_react10 = __toESM(require_react(), 1);
55047
- var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
55084
+ var import_react12 = __toESM(require_react(), 1);
55085
+ var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
55048
55086
  function ProjectList({
55049
55087
  onSelect,
55050
55088
  selected,
@@ -55053,23 +55091,23 @@ function ProjectList({
55053
55091
  onShowHidden
55054
55092
  }) {
55055
55093
  const { data, loading, error, retry } = useFetch("/api/projects", []);
55056
- const [filter, setFilter] = import_react10.useState("");
55094
+ const [filter, setFilter] = import_react12.useState("");
55057
55095
  const projects = data?.projects ?? [];
55058
55096
  const filtered = projects.filter((p) => !hiddenIds.has(p.encodedPath) && (p.name.toLowerCase().includes(filter.toLowerCase()) || p.encodedPath.toLowerCase().includes(filter.toLowerCase())));
55059
55097
  if (loading)
55060
- return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55098
+ return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55061
55099
  className: "loading",
55062
55100
  children: "Loading projects..."
55063
55101
  }, undefined, false, undefined, this);
55064
55102
  if (error) {
55065
- return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55103
+ return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55066
55104
  className: "fetch-error",
55067
55105
  children: [
55068
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("span", {
55106
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
55069
55107
  className: "fetch-error-message",
55070
55108
  children: error
55071
55109
  }, undefined, false, undefined, this),
55072
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("button", {
55110
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("button", {
55073
55111
  type: "button",
55074
55112
  className: "btn btn-sm",
55075
55113
  onClick: retry,
@@ -55078,15 +55116,15 @@ function ProjectList({
55078
55116
  ]
55079
55117
  }, undefined, true, undefined, this);
55080
55118
  }
55081
- return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55119
+ return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55082
55120
  children: [
55083
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("input", {
55121
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("input", {
55084
55122
  className: "filter-input",
55085
55123
  placeholder: "Filter projects...",
55086
55124
  value: filter,
55087
55125
  onChange: (e) => setFilter(e.target.value)
55088
55126
  }, undefined, false, undefined, this),
55089
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55127
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55090
55128
  className: "list-section-title",
55091
55129
  children: [
55092
55130
  "Projects (",
@@ -55094,25 +55132,25 @@ function ProjectList({
55094
55132
  ")"
55095
55133
  ]
55096
55134
  }, undefined, true, undefined, this),
55097
- filtered.map((project) => /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55135
+ filtered.map((project) => /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55098
55136
  className: `list-item list-item-with-action ${selected === project.encodedPath ? "active" : ""}`,
55099
55137
  onClick: () => onSelect(project),
55100
55138
  children: [
55101
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55139
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55102
55140
  className: "list-item-content",
55103
55141
  children: [
55104
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55142
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55105
55143
  className: "list-item-title",
55106
55144
  children: projectDisplayName(project)
55107
55145
  }, undefined, false, undefined, this),
55108
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55146
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55109
55147
  className: "list-item-meta",
55110
55148
  children: [
55111
55149
  project.sessionCount,
55112
55150
  " session",
55113
55151
  project.sessionCount !== 1 ? "s" : "",
55114
55152
  " · ",
55115
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("time", {
55153
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("time", {
55116
55154
  dateTime: project.lastActivity,
55117
55155
  title: formatFullDateTime(project.lastActivity),
55118
55156
  children: formatRelativeTime(project.lastActivity)
@@ -55121,7 +55159,7 @@ function ProjectList({
55121
55159
  }, undefined, true, undefined, this)
55122
55160
  ]
55123
55161
  }, undefined, true, undefined, this),
55124
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("button", {
55162
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("button", {
55125
55163
  type: "button",
55126
55164
  className: "btn-hide",
55127
55165
  title: "Hide project",
@@ -55133,11 +55171,11 @@ function ProjectList({
55133
55171
  }, undefined, false, undefined, this)
55134
55172
  ]
55135
55173
  }, project.encodedPath, true, undefined, this)),
55136
- filtered.length === 0 && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55174
+ filtered.length === 0 && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55137
55175
  className: "empty-list-message",
55138
55176
  children: "No projects found"
55139
55177
  }, undefined, false, undefined, this),
55140
- hiddenIds.size > 0 && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
55178
+ hiddenIds.size > 0 && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55141
55179
  className: "hidden-projects-link",
55142
55180
  onClick: onShowHidden,
55143
55181
  children: [
@@ -55151,35 +55189,35 @@ function ProjectList({
55151
55189
  }
55152
55190
 
55153
55191
  // src/frontend/components/project/SessionList.tsx
55154
- var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
55192
+ var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
55155
55193
  function SessionList({ project, onSelect, onBack, selectedId }) {
55156
55194
  const { data, loading, error, retry } = useFetch(`/api/projects/${encodeURIComponent(project.encodedPath)}/sessions`, [project.encodedPath]);
55157
55195
  const sessions = data?.sessions ?? [];
55158
55196
  const parts = project.name.split("/").filter(Boolean);
55159
55197
  const displayName = parts.slice(-2).join("/");
55160
- return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55198
+ return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55161
55199
  children: [
55162
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55200
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55163
55201
  className: "back-btn",
55164
55202
  onClick: onBack,
55165
55203
  children: "← Projects"
55166
55204
  }, undefined, false, undefined, this),
55167
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55205
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55168
55206
  className: "list-section-title",
55169
55207
  children: displayName
55170
55208
  }, undefined, false, undefined, this),
55171
- loading && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55209
+ loading && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55172
55210
  className: "loading",
55173
55211
  children: "Loading sessions..."
55174
55212
  }, undefined, false, undefined, this),
55175
- error && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55213
+ error && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55176
55214
  className: "fetch-error",
55177
55215
  children: [
55178
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
55216
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
55179
55217
  className: "fetch-error-message",
55180
55218
  children: error
55181
55219
  }, undefined, false, undefined, this),
55182
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("button", {
55220
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("button", {
55183
55221
  type: "button",
55184
55222
  className: "btn btn-sm",
55185
55223
  onClick: retry,
@@ -55187,35 +55225,35 @@ function SessionList({ project, onSelect, onBack, selectedId }) {
55187
55225
  }, undefined, false, undefined, this)
55188
55226
  ]
55189
55227
  }, undefined, true, undefined, this),
55190
- !loading && !error && sessions.map((session) => /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55228
+ !loading && !error && sessions.map((session) => /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55191
55229
  className: `list-item ${selectedId === session.sessionId ? "active" : ""}${session.sessionType ? ` ${session.sessionType}` : ""}`,
55192
55230
  onClick: () => onSelect(session),
55193
55231
  children: [
55194
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55232
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55195
55233
  className: "list-item-title",
55196
55234
  children: session.firstMessage || session.slug
55197
55235
  }, undefined, false, undefined, this),
55198
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55236
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55199
55237
  className: "list-item-meta",
55200
55238
  children: [
55201
- session.sessionType && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
55239
+ session.sessionType && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
55202
55240
  className: `session-type-badge ${session.sessionType}`,
55203
55241
  children: session.sessionType === "plan" ? "Plan" : "Impl"
55204
55242
  }, undefined, false, undefined, this),
55205
55243
  " ",
55206
- session.model && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
55244
+ session.model && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
55207
55245
  children: [
55208
55246
  shortModel(session.model),
55209
55247
  " · "
55210
55248
  ]
55211
55249
  }, undefined, true, undefined, this),
55212
- session.gitBranch && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("span", {
55250
+ session.gitBranch && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
55213
55251
  children: [
55214
55252
  session.gitBranch,
55215
55253
  " · "
55216
55254
  ]
55217
55255
  }, undefined, true, undefined, this),
55218
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("time", {
55256
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("time", {
55219
55257
  dateTime: session.timestamp,
55220
55258
  title: formatFullDateTime(session.timestamp),
55221
55259
  children: formatTime(session.timestamp)
@@ -55224,7 +55262,7 @@ function SessionList({ project, onSelect, onBack, selectedId }) {
55224
55262
  }, undefined, true, undefined, this)
55225
55263
  ]
55226
55264
  }, session.sessionId, true, undefined, this)),
55227
- !loading && !error && sessions.length === 0 && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
55265
+ !loading && !error && sessions.length === 0 && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55228
55266
  className: "empty-list-message",
55229
55267
  children: "No sessions found"
55230
55268
  }, undefined, false, undefined, this)
@@ -55233,23 +55271,23 @@ function SessionList({ project, onSelect, onBack, selectedId }) {
55233
55271
  }
55234
55272
 
55235
55273
  // src/frontend/components/search/SearchModal.tsx
55236
- var import_react11 = __toESM(require_react(), 1);
55237
- var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
55274
+ var import_react13 = __toESM(require_react(), 1);
55275
+ var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
55238
55276
  var MAX_RESULTS = 20;
55239
55277
  function matchesQuery(result, query) {
55240
55278
  const q2 = query.toLowerCase();
55241
55279
  return result.firstMessage.toLowerCase().includes(q2) || result.projectName.toLowerCase().includes(q2) || result.gitBranch.toLowerCase().includes(q2);
55242
55280
  }
55243
55281
  function SearchModal({ sessions, onSelect, onClose }) {
55244
- const [query, setQuery] = import_react11.useState("");
55245
- const [highlightedIndex, setHighlightedIndex] = import_react11.useState(0);
55246
- const inputRef = import_react11.useRef(null);
55247
- const resultsRef = import_react11.useRef(null);
55282
+ const [query, setQuery] = import_react13.useState("");
55283
+ const [highlightedIndex, setHighlightedIndex] = import_react13.useState(0);
55284
+ const inputRef = import_react13.useRef(null);
55285
+ const resultsRef = import_react13.useRef(null);
55248
55286
  const filtered = query ? sessions.filter((s2) => matchesQuery(s2, query)).slice(0, MAX_RESULTS) : sessions.slice(0, MAX_RESULTS);
55249
- import_react11.useEffect(() => {
55287
+ import_react13.useEffect(() => {
55250
55288
  inputRef.current?.focus();
55251
55289
  }, []);
55252
- import_react11.useEffect(() => {
55290
+ import_react13.useEffect(() => {
55253
55291
  const container = resultsRef.current;
55254
55292
  if (!container)
55255
55293
  return;
@@ -55259,10 +55297,10 @@ function SearchModal({ sessions, onSelect, onClose }) {
55259
55297
  item.scrollIntoView({ block: "nearest" });
55260
55298
  }
55261
55299
  }, [highlightedIndex]);
55262
- const handleSelect = import_react11.useCallback((result) => {
55300
+ const handleSelect = import_react13.useCallback((result) => {
55263
55301
  onSelect(result.encodedPath, result.sessionId);
55264
55302
  }, [onSelect]);
55265
- const handleKeyDown = import_react11.useCallback((e) => {
55303
+ const handleKeyDown = import_react13.useCallback((e) => {
55266
55304
  switch (e.key) {
55267
55305
  case "ArrowDown":
55268
55306
  e.preventDefault();
@@ -55284,16 +55322,16 @@ function SearchModal({ sessions, onSelect, onClose }) {
55284
55322
  break;
55285
55323
  }
55286
55324
  }, [filtered, highlightedIndex, handleSelect, onClose]);
55287
- return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55325
+ return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55288
55326
  className: "search-overlay",
55289
55327
  onMouseDown: onClose,
55290
- children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55328
+ children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55291
55329
  className: "search-modal",
55292
55330
  onMouseDown: (e) => e.stopPropagation(),
55293
55331
  children: [
55294
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55332
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55295
55333
  className: "search-input-wrapper",
55296
- children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("input", {
55334
+ children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("input", {
55297
55335
  ref: inputRef,
55298
55336
  className: "search-input",
55299
55337
  type: "text",
@@ -55306,31 +55344,31 @@ function SearchModal({ sessions, onSelect, onClose }) {
55306
55344
  onKeyDown: handleKeyDown
55307
55345
  }, undefined, false, undefined, this)
55308
55346
  }, undefined, false, undefined, this),
55309
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55347
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55310
55348
  className: "search-results",
55311
55349
  ref: resultsRef,
55312
- children: filtered.length === 0 ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55350
+ children: filtered.length === 0 ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55313
55351
  className: "search-empty",
55314
55352
  children: "No results found"
55315
- }, undefined, false, undefined, this) : filtered.map((result, index2) => /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55353
+ }, undefined, false, undefined, this) : filtered.map((result, index2) => /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55316
55354
  className: `search-result-item ${index2 === highlightedIndex ? "highlighted" : ""}`,
55317
55355
  "data-search-item": true,
55318
55356
  onClick: () => handleSelect(result),
55319
55357
  onMouseEnter: () => setHighlightedIndex(index2),
55320
55358
  children: [
55321
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55359
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55322
55360
  className: "search-result-title",
55323
55361
  children: [
55324
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
55362
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("span", {
55325
55363
  children: result.firstMessage
55326
55364
  }, undefined, false, undefined, this),
55327
- result.sessionType && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
55365
+ result.sessionType && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("span", {
55328
55366
  className: `session-type-badge ${result.sessionType}`,
55329
55367
  children: result.sessionType
55330
55368
  }, undefined, false, undefined, this)
55331
55369
  ]
55332
55370
  }, undefined, true, undefined, this),
55333
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55371
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55334
55372
  className: "search-result-meta",
55335
55373
  children: [
55336
55374
  result.projectName,
@@ -55339,7 +55377,7 @@ function SearchModal({ sessions, onSelect, onClose }) {
55339
55377
  result.gitBranch ? ` · ${result.gitBranch}` : "",
55340
55378
  " ·",
55341
55379
  " ",
55342
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("time", {
55380
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("time", {
55343
55381
  dateTime: result.timestamp,
55344
55382
  title: formatFullDateTime(result.timestamp),
55345
55383
  children: formatRelativeTime(result.timestamp)
@@ -55349,28 +55387,28 @@ function SearchModal({ sessions, onSelect, onClose }) {
55349
55387
  ]
55350
55388
  }, `${result.encodedPath}-${result.sessionId}`, true, undefined, this))
55351
55389
  }, undefined, false, undefined, this),
55352
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
55390
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55353
55391
  className: "search-footer",
55354
55392
  children: [
55355
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
55393
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("span", {
55356
55394
  children: [
55357
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("kbd", {
55395
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("kbd", {
55358
55396
  children: "↑↓"
55359
55397
  }, undefined, false, undefined, this),
55360
55398
  " navigate"
55361
55399
  ]
55362
55400
  }, undefined, true, undefined, this),
55363
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
55401
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("span", {
55364
55402
  children: [
55365
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("kbd", {
55403
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("kbd", {
55366
55404
  children: "↵"
55367
55405
  }, undefined, false, undefined, this),
55368
55406
  " open"
55369
55407
  ]
55370
55408
  }, undefined, true, undefined, this),
55371
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("span", {
55409
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("span", {
55372
55410
  children: [
55373
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("kbd", {
55411
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("kbd", {
55374
55412
  children: "esc"
55375
55413
  }, undefined, false, undefined, this),
55376
55414
  " close"
@@ -55384,12 +55422,12 @@ function SearchModal({ sessions, onSelect, onClose }) {
55384
55422
  }
55385
55423
 
55386
55424
  // src/frontend/components/session/PresentationShell.tsx
55387
- var import_react14 = __toESM(require_react(), 1);
55425
+ var import_react16 = __toESM(require_react(), 1);
55388
55426
 
55389
55427
  // src/frontend/hooks/useKeyboard.ts
55390
- var import_react12 = __toESM(require_react(), 1);
55428
+ var import_react14 = __toESM(require_react(), 1);
55391
55429
  function useKeyboard(handlers2, active) {
55392
- import_react12.useEffect(() => {
55430
+ import_react14.useEffect(() => {
55393
55431
  if (!active)
55394
55432
  return;
55395
55433
  function handleKeyDown(e) {
@@ -55432,7 +55470,7 @@ function useKeyboard(handlers2, active) {
55432
55470
  }
55433
55471
 
55434
55472
  // src/frontend/hooks/usePresentationMode.ts
55435
- var import_react13 = __toESM(require_react(), 1);
55473
+ var import_react15 = __toESM(require_react(), 1);
55436
55474
  function countSubSteps(turn) {
55437
55475
  if (turn.kind !== "assistant")
55438
55476
  return 1;
@@ -55440,10 +55478,10 @@ function countSubSteps(turn) {
55440
55478
  return Math.max(groupContentBlocks(a.contentBlocks).length, 1);
55441
55479
  }
55442
55480
  function usePresentationMode(turns) {
55443
- const [active, setActive] = import_react13.useState(false);
55444
- const [fullscreen, setFullscreen] = import_react13.useState(false);
55445
- const [currentStep, setCurrentStep] = import_react13.useState(0);
55446
- const steps = import_react13.useMemo(() => {
55481
+ const [active, setActive] = import_react15.useState(false);
55482
+ const [fullscreen, setFullscreen] = import_react15.useState(false);
55483
+ const [currentStep, setCurrentStep] = import_react15.useState(0);
55484
+ const steps = import_react15.useMemo(() => {
55447
55485
  const result = [];
55448
55486
  for (let i = 0;i < turns.length; i++) {
55449
55487
  const sub = countSubSteps(turns[i]);
@@ -55454,7 +55492,7 @@ function usePresentationMode(turns) {
55454
55492
  return result;
55455
55493
  }, [turns]);
55456
55494
  const totalSteps = steps.length;
55457
- const turnBoundaries = import_react13.useMemo(() => {
55495
+ const turnBoundaries = import_react15.useMemo(() => {
55458
55496
  const boundaries = [];
55459
55497
  for (let i = 0;i < steps.length; i++) {
55460
55498
  const next2 = steps[i + 1];
@@ -55464,7 +55502,7 @@ function usePresentationMode(turns) {
55464
55502
  }
55465
55503
  return boundaries;
55466
55504
  }, [steps]);
55467
- const { visibleTurns, visibleSubSteps } = import_react13.useMemo(() => {
55505
+ const { visibleTurns, visibleSubSteps } = import_react15.useMemo(() => {
55468
55506
  if (!active || steps.length === 0) {
55469
55507
  return { visibleTurns: turns, visibleSubSteps: new Map };
55470
55508
  }
@@ -55478,22 +55516,22 @@ function usePresentationMode(turns) {
55478
55516
  subSteps.set(maxTurnIndex, step.subStep + 1);
55479
55517
  return { visibleTurns: visible, visibleSubSteps: subSteps };
55480
55518
  }, [active, currentStep, steps, turns]);
55481
- const enter = import_react13.useCallback(() => {
55519
+ const enter = import_react15.useCallback(() => {
55482
55520
  setActive(true);
55483
55521
  setCurrentStep(0);
55484
55522
  }, []);
55485
- const exit3 = import_react13.useCallback(() => {
55523
+ const exit3 = import_react15.useCallback(() => {
55486
55524
  setActive(false);
55487
55525
  setFullscreen(false);
55488
55526
  setCurrentStep(0);
55489
55527
  }, []);
55490
- const next = import_react13.useCallback(() => {
55528
+ const next = import_react15.useCallback(() => {
55491
55529
  setCurrentStep((s2) => Math.min(s2 + 1, steps.length - 1));
55492
55530
  }, [steps.length]);
55493
- const prev = import_react13.useCallback(() => {
55531
+ const prev = import_react15.useCallback(() => {
55494
55532
  setCurrentStep((s2) => Math.max(s2 - 1, 0));
55495
55533
  }, []);
55496
- const nextTurn = import_react13.useCallback(() => {
55534
+ const nextTurn = import_react15.useCallback(() => {
55497
55535
  setCurrentStep((s2) => {
55498
55536
  for (const b of turnBoundaries) {
55499
55537
  if (b > s2)
@@ -55502,7 +55540,7 @@ function usePresentationMode(turns) {
55502
55540
  return s2;
55503
55541
  });
55504
55542
  }, [turnBoundaries]);
55505
- const prevTurn = import_react13.useCallback(() => {
55543
+ const prevTurn = import_react15.useCallback(() => {
55506
55544
  setCurrentStep((s2) => {
55507
55545
  for (let i = turnBoundaries.length - 1;i >= 0; i--) {
55508
55546
  if (turnBoundaries[i] < s2)
@@ -55511,7 +55549,7 @@ function usePresentationMode(turns) {
55511
55549
  return s2;
55512
55550
  });
55513
55551
  }, [turnBoundaries]);
55514
- const toggleFullscreen = import_react13.useCallback(() => {
55552
+ const toggleFullscreen = import_react15.useCallback(() => {
55515
55553
  setFullscreen((f) => !f);
55516
55554
  }, []);
55517
55555
  return {
@@ -55532,7 +55570,7 @@ function usePresentationMode(turns) {
55532
55570
  }
55533
55571
 
55534
55572
  // src/frontend/components/session/PresentationShell.tsx
55535
- var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
55573
+ var jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
55536
55574
  function PresentationShell({
55537
55575
  turns,
55538
55576
  onExit,
@@ -55540,9 +55578,9 @@ function PresentationShell({
55540
55578
  project,
55541
55579
  isSubAgent
55542
55580
  }) {
55543
- const scrollRef = import_react14.useRef(null);
55581
+ const scrollRef = import_react16.useRef(null);
55544
55582
  const presentation = usePresentationMode(turns);
55545
- import_react14.useEffect(() => {
55583
+ import_react16.useEffect(() => {
55546
55584
  if (turns.length > 0 && !presentation.active) {
55547
55585
  presentation.enter();
55548
55586
  }
@@ -55556,28 +55594,28 @@ function PresentationShell({
55556
55594
  onFullscreen: presentation.toggleFullscreen
55557
55595
  }, presentation.active);
55558
55596
  const currentStep = presentation.currentStep;
55559
- import_react14.useEffect(() => {
55597
+ import_react16.useEffect(() => {
55560
55598
  if (currentStep >= 0 && scrollRef.current) {
55561
55599
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
55562
55600
  }
55563
55601
  }, [currentStep]);
55564
55602
  const progress = presentation.totalSteps > 0 ? (presentation.currentStep + 1) / presentation.totalSteps * 100 : 0;
55565
- return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55603
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
55566
55604
  className: `presentation-mode ${presentation.fullscreen ? "fullscreen" : ""}`,
55567
55605
  ref: scrollRef,
55568
55606
  style: { overflowY: "auto", height: "calc(100vh - 92px)" },
55569
55607
  children: [
55570
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(MessageList, {
55608
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(MessageList, {
55571
55609
  turns: presentation.visibleTurns,
55572
55610
  visibleSubSteps: presentation.visibleSubSteps,
55573
55611
  sessionId,
55574
55612
  project,
55575
55613
  isSubAgent
55576
55614
  }, undefined, false, undefined, this),
55577
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55615
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
55578
55616
  className: "presentation-progress",
55579
55617
  children: [
55580
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("span", {
55618
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("span", {
55581
55619
  children: [
55582
55620
  "Step ",
55583
55621
  presentation.currentStep + 1,
@@ -55585,14 +55623,14 @@ function PresentationShell({
55585
55623
  presentation.totalSteps
55586
55624
  ]
55587
55625
  }, undefined, true, undefined, this),
55588
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55626
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
55589
55627
  className: "presentation-progress-bar",
55590
- children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
55628
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
55591
55629
  className: "presentation-progress-fill",
55592
55630
  style: { width: `${progress}%` }
55593
55631
  }, undefined, false, undefined, this)
55594
55632
  }, undefined, false, undefined, this),
55595
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("span", {
55633
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("span", {
55596
55634
  style: { fontSize: "0.75rem" },
55597
55635
  children: "← → step · ↑ ↓ message · Esc exit · F fullscreen"
55598
55636
  }, undefined, false, undefined, this)
@@ -55603,26 +55641,26 @@ function PresentationShell({
55603
55641
  }
55604
55642
 
55605
55643
  // src/frontend/components/session/SessionPresentation.tsx
55606
- var jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
55644
+ var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
55607
55645
  function SessionPresentation({ sessionId, project, onExit }) {
55608
55646
  const { data, loading, error, retry } = useFetch(`/api/sessions/${sessionId}?project=${encodeURIComponent(project)}`, [sessionId, project]);
55609
55647
  if (loading)
55610
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
55648
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("div", {
55611
55649
  className: "loading",
55612
55650
  children: "Loading session..."
55613
55651
  }, undefined, false, undefined, this);
55614
55652
  if (error) {
55615
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
55653
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("div", {
55616
55654
  className: "fetch-error",
55617
55655
  children: [
55618
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("span", {
55656
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("span", {
55619
55657
  className: "fetch-error-message",
55620
55658
  children: [
55621
55659
  "Error: ",
55622
55660
  error
55623
55661
  ]
55624
55662
  }, undefined, true, undefined, this),
55625
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("button", {
55663
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("button", {
55626
55664
  type: "button",
55627
55665
  className: "btn btn-sm",
55628
55666
  onClick: retry,
@@ -55633,7 +55671,7 @@ function SessionPresentation({ sessionId, project, onExit }) {
55633
55671
  }
55634
55672
  if (!data?.session)
55635
55673
  return null;
55636
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(PresentationShell, {
55674
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(PresentationShell, {
55637
55675
  turns: data.session.turns,
55638
55676
  onExit,
55639
55677
  sessionId,
@@ -55642,26 +55680,26 @@ function SessionPresentation({ sessionId, project, onExit }) {
55642
55680
  }
55643
55681
 
55644
55682
  // src/frontend/components/session/SessionView.tsx
55645
- var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
55683
+ var jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
55646
55684
  function SessionView({ sessionId, project }) {
55647
55685
  const { data, loading, error, retry } = useFetch(`/api/sessions/${sessionId}?project=${encodeURIComponent(project)}`, [sessionId, project]);
55648
55686
  if (loading)
55649
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("div", {
55687
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("div", {
55650
55688
  className: "loading",
55651
55689
  children: "Loading session..."
55652
55690
  }, undefined, false, undefined, this);
55653
55691
  if (error) {
55654
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("div", {
55692
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("div", {
55655
55693
  className: "fetch-error",
55656
55694
  children: [
55657
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("span", {
55695
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("span", {
55658
55696
  className: "fetch-error-message",
55659
55697
  children: [
55660
55698
  "Error: ",
55661
55699
  error
55662
55700
  ]
55663
55701
  }, undefined, true, undefined, this),
55664
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("button", {
55702
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("button", {
55665
55703
  type: "button",
55666
55704
  className: "btn btn-sm",
55667
55705
  onClick: retry,
@@ -55673,7 +55711,7 @@ function SessionView({ sessionId, project }) {
55673
55711
  if (!data?.session)
55674
55712
  return null;
55675
55713
  const session = data.session;
55676
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(MessageList, {
55714
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(MessageList, {
55677
55715
  turns: session.turns,
55678
55716
  sessionId,
55679
55717
  project,
@@ -55683,7 +55721,7 @@ function SessionView({ sessionId, project }) {
55683
55721
  }
55684
55722
 
55685
55723
  // src/frontend/components/session/SubAgentPresentation.tsx
55686
- var jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
55724
+ var jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
55687
55725
  function SubAgentPresentation({
55688
55726
  sessionId,
55689
55727
  project,
@@ -55692,22 +55730,22 @@ function SubAgentPresentation({
55692
55730
  }) {
55693
55731
  const { data, loading, error, retry } = useFetch(`/api/sessions/${sessionId}/subagents/${agentId}?project=${encodeURIComponent(project)}`, [sessionId, project, agentId]);
55694
55732
  if (loading)
55695
- return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("div", {
55733
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
55696
55734
  className: "loading",
55697
55735
  children: "Loading sub-agent conversation..."
55698
55736
  }, undefined, false, undefined, this);
55699
55737
  if (error) {
55700
- return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("div", {
55738
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
55701
55739
  className: "fetch-error",
55702
55740
  children: [
55703
- /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("span", {
55741
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("span", {
55704
55742
  className: "fetch-error-message",
55705
55743
  children: [
55706
55744
  "Error: ",
55707
55745
  error
55708
55746
  ]
55709
55747
  }, undefined, true, undefined, this),
55710
- /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("button", {
55748
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("button", {
55711
55749
  type: "button",
55712
55750
  className: "btn btn-sm",
55713
55751
  onClick: retry,
@@ -55718,7 +55756,7 @@ function SubAgentPresentation({
55718
55756
  }
55719
55757
  if (!data?.session || data.session.turns.length === 0)
55720
55758
  return null;
55721
- return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(PresentationShell, {
55759
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(PresentationShell, {
55722
55760
  turns: data.session.turns,
55723
55761
  onExit,
55724
55762
  sessionId,
@@ -55728,7 +55766,7 @@ function SubAgentPresentation({
55728
55766
  }
55729
55767
 
55730
55768
  // src/frontend/hooks/useHiddenProjects.ts
55731
- var import_react15 = __toESM(require_react(), 1);
55769
+ var import_react17 = __toESM(require_react(), 1);
55732
55770
  var STORAGE_KEY = "klovi-hidden-projects";
55733
55771
  function loadHiddenIds() {
55734
55772
  try {
@@ -55750,8 +55788,8 @@ function persistHiddenIds(ids) {
55750
55788
  localStorage.setItem(STORAGE_KEY, JSON.stringify(store));
55751
55789
  }
55752
55790
  function useHiddenProjects() {
55753
- const [hiddenIds, setHiddenIds] = import_react15.useState(() => loadHiddenIds());
55754
- const hide = import_react15.useCallback((encodedPath) => {
55791
+ const [hiddenIds, setHiddenIds] = import_react17.useState(() => loadHiddenIds());
55792
+ const hide = import_react17.useCallback((encodedPath) => {
55755
55793
  setHiddenIds((prev) => {
55756
55794
  const next = new Set(prev);
55757
55795
  next.add(encodedPath);
@@ -55759,7 +55797,7 @@ function useHiddenProjects() {
55759
55797
  return next;
55760
55798
  });
55761
55799
  }, []);
55762
- const unhide = import_react15.useCallback((encodedPath) => {
55800
+ const unhide = import_react17.useCallback((encodedPath) => {
55763
55801
  setHiddenIds((prev) => {
55764
55802
  const next = new Set(prev);
55765
55803
  next.delete(encodedPath);
@@ -55767,12 +55805,12 @@ function useHiddenProjects() {
55767
55805
  return next;
55768
55806
  });
55769
55807
  }, []);
55770
- const isHidden = import_react15.useCallback((encodedPath) => hiddenIds.has(encodedPath), [hiddenIds]);
55808
+ const isHidden = import_react17.useCallback((encodedPath) => hiddenIds.has(encodedPath), [hiddenIds]);
55771
55809
  return { hiddenIds, hide, unhide, isHidden };
55772
55810
  }
55773
55811
 
55774
55812
  // src/frontend/App.tsx
55775
- var jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
55813
+ var jsx_dev_runtime27 = __toESM(require_jsx_dev_runtime(), 1);
55776
55814
  function viewToHash(view) {
55777
55815
  if (view.kind === "hidden")
55778
55816
  return "#/hidden";
@@ -55845,7 +55883,7 @@ function getHeaderInfo(view) {
55845
55883
  }
55846
55884
  function getSidebarContent(view, selectProject, hiddenIds, hide, goHidden, selectSession, goHome) {
55847
55885
  if (view.kind === "home" || view.kind === "hidden") {
55848
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(ProjectList, {
55886
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(ProjectList, {
55849
55887
  onSelect: selectProject,
55850
55888
  hiddenIds,
55851
55889
  onHide: hide,
@@ -55853,21 +55891,21 @@ function getSidebarContent(view, selectProject, hiddenIds, hide, goHidden, selec
55853
55891
  }, undefined, false, undefined, this);
55854
55892
  }
55855
55893
  if (view.kind === "project") {
55856
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(SessionList, {
55894
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(SessionList, {
55857
55895
  project: view.project,
55858
55896
  onSelect: selectSession,
55859
55897
  onBack: goHome
55860
55898
  }, undefined, false, undefined, this);
55861
55899
  }
55862
55900
  if (view.kind === "subagent") {
55863
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(SessionList, {
55901
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(SessionList, {
55864
55902
  project: view.project,
55865
55903
  onSelect: selectSession,
55866
55904
  onBack: goHome,
55867
55905
  selectedId: view.sessionId
55868
55906
  }, undefined, false, undefined, this);
55869
55907
  }
55870
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(SessionList, {
55908
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(SessionList, {
55871
55909
  project: view.project,
55872
55910
  onSelect: selectSession,
55873
55911
  onBack: goHome,
@@ -55878,17 +55916,17 @@ function App() {
55878
55916
  const { setting: themeSetting, cycle: cycleTheme } = useTheme();
55879
55917
  const { size: fontSize, increase, decrease } = useFontSize();
55880
55918
  const { hiddenIds, hide, unhide } = useHiddenProjects();
55881
- const [view, setView] = import_react16.useState({ kind: "home" });
55882
- const [ready, setReady] = import_react16.useState(false);
55883
- const [searchOpen, setSearchOpen] = import_react16.useState(false);
55884
- const [searchSessions, setSearchSessions] = import_react16.useState([]);
55885
- import_react16.useEffect(() => {
55919
+ const [view, setView] = import_react18.useState({ kind: "home" });
55920
+ const [ready, setReady] = import_react18.useState(false);
55921
+ const [searchOpen, setSearchOpen] = import_react18.useState(false);
55922
+ const [searchSessions, setSearchSessions] = import_react18.useState([]);
55923
+ import_react18.useEffect(() => {
55886
55924
  restoreFromHash().then((v2) => {
55887
55925
  setView(v2);
55888
55926
  setReady(true);
55889
55927
  });
55890
55928
  }, []);
55891
- import_react16.useEffect(() => {
55929
+ import_react18.useEffect(() => {
55892
55930
  if (!ready)
55893
55931
  return;
55894
55932
  const newHash = viewToHash(view);
@@ -55896,7 +55934,7 @@ function App() {
55896
55934
  history.pushState(null, "", newHash);
55897
55935
  }
55898
55936
  }, [view, ready]);
55899
- import_react16.useEffect(() => {
55937
+ import_react18.useEffect(() => {
55900
55938
  const handler = () => {
55901
55939
  restoreFromHash().then(setView);
55902
55940
  };
@@ -55919,19 +55957,19 @@ function App() {
55919
55957
  const goHome = () => setView({ kind: "home" });
55920
55958
  const goHidden = () => setView({ kind: "hidden" });
55921
55959
  const canPresent = view.kind === "session" || view.kind === "subagent";
55922
- const togglePresentation = import_react16.useCallback(() => {
55960
+ const togglePresentation = import_react18.useCallback(() => {
55923
55961
  if (view.kind === "session" || view.kind === "subagent") {
55924
55962
  setView({ ...view, presenting: !view.presenting });
55925
55963
  }
55926
55964
  }, [view]);
55927
- const fetchSearchSessions = import_react16.useCallback(() => {
55965
+ const fetchSearchSessions = import_react18.useCallback(() => {
55928
55966
  fetch("/api/search/sessions").then((res) => res.json()).then((data) => setSearchSessions(data.sessions)).catch(() => {});
55929
55967
  }, []);
55930
- const openSearch = import_react16.useCallback(() => {
55968
+ const openSearch = import_react18.useCallback(() => {
55931
55969
  setSearchOpen(true);
55932
55970
  fetchSearchSessions();
55933
55971
  }, [fetchSearchSessions]);
55934
- const handleSearchSelect = import_react16.useCallback(async (encodedPath, sessionId) => {
55972
+ const handleSearchSelect = import_react18.useCallback(async (encodedPath, sessionId) => {
55935
55973
  setSearchOpen(false);
55936
55974
  try {
55937
55975
  const [projectsRes, sessionsRes] = await Promise.all([
@@ -55947,7 +55985,7 @@ function App() {
55947
55985
  }
55948
55986
  } catch {}
55949
55987
  }, []);
55950
- import_react16.useEffect(() => {
55988
+ import_react18.useEffect(() => {
55951
55989
  function handleCmdK(e) {
55952
55990
  if ((e.metaKey || e.ctrlKey) && e.key === "k") {
55953
55991
  e.preventDefault();
@@ -55961,7 +55999,7 @@ function App() {
55961
55999
  window.addEventListener("keydown", handleCmdK);
55962
56000
  return () => window.removeEventListener("keydown", handleCmdK);
55963
56001
  }, [fetchSearchSessions]);
55964
- import_react16.useEffect(() => {
56002
+ import_react18.useEffect(() => {
55965
56003
  function handleKeyDown(e) {
55966
56004
  if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement)
55967
56005
  return;
@@ -55992,24 +56030,24 @@ function App() {
55992
56030
  const sidebarContent = getSidebarContent(view, selectProject, hiddenIds, hide, goHidden, selectSession, goHome);
55993
56031
  const isPresenting = canPresent && view.presenting;
55994
56032
  if (!ready) {
55995
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
56033
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
55996
56034
  className: "loading",
55997
56035
  children: "Loading..."
55998
56036
  }, undefined, false, undefined, this);
55999
56037
  }
56000
- return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(jsx_dev_runtime26.Fragment, {
56038
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(jsx_dev_runtime27.Fragment, {
56001
56039
  children: [
56002
- searchOpen && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(SearchModal, {
56040
+ searchOpen && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(SearchModal, {
56003
56041
  sessions: searchSessions,
56004
56042
  onSelect: handleSearchSelect,
56005
56043
  onClose: () => setSearchOpen(false)
56006
56044
  }, undefined, false, undefined, this),
56007
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Layout, {
56045
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Layout, {
56008
56046
  sidebar: sidebarContent,
56009
56047
  hideSidebar: isPresenting,
56010
56048
  onSearchClick: openSearch,
56011
56049
  children: [
56012
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Header, {
56050
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Header, {
56013
56051
  title: headerTitle,
56014
56052
  breadcrumb,
56015
56053
  copyCommand: view.kind === "session" && isClaudeModel(view.session.model) ? `claude --resume ${view.session.sessionId}` : undefined,
@@ -56024,63 +56062,63 @@ function App() {
56024
56062
  onTogglePresentation: togglePresentation,
56025
56063
  showPresentationToggle: canPresent
56026
56064
  }, undefined, false, undefined, this),
56027
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(ErrorBoundary, {
56065
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(ErrorBoundary, {
56028
56066
  children: [
56029
- view.kind === "home" && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(jsx_dev_runtime26.Fragment, {
56067
+ view.kind === "home" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(jsx_dev_runtime27.Fragment, {
56030
56068
  children: [
56031
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
56069
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
56032
56070
  className: "empty-state",
56033
56071
  children: [
56034
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("img", {
56072
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("img", {
56035
56073
  src: favicon_default,
56036
56074
  alt: "",
56037
56075
  width: "64",
56038
56076
  height: "64",
56039
56077
  className: "empty-state-logo"
56040
56078
  }, undefined, false, undefined, this),
56041
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
56079
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
56042
56080
  className: "empty-state-title",
56043
56081
  children: "Welcome to Klovi"
56044
56082
  }, undefined, false, undefined, this),
56045
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("p", {
56083
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("p", {
56046
56084
  children: "Select a project from the sidebar to browse your AI coding sessions"
56047
56085
  }, undefined, false, undefined, this)
56048
56086
  ]
56049
56087
  }, undefined, true, undefined, this),
56050
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(DashboardStats, {}, undefined, false, undefined, this)
56088
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(DashboardStats, {}, undefined, false, undefined, this)
56051
56089
  ]
56052
56090
  }, undefined, true, undefined, this),
56053
- view.kind === "hidden" && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(HiddenProjectList, {
56091
+ view.kind === "hidden" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(HiddenProjectList, {
56054
56092
  hiddenIds,
56055
56093
  onUnhide: unhide,
56056
56094
  onBack: goHome
56057
56095
  }, undefined, false, undefined, this),
56058
- view.kind === "project" && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
56096
+ view.kind === "project" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
56059
56097
  className: "empty-state",
56060
56098
  children: [
56061
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("div", {
56099
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("div", {
56062
56100
  className: "empty-state-title",
56063
56101
  children: "Select a session"
56064
56102
  }, undefined, false, undefined, this),
56065
- /* @__PURE__ */ jsx_dev_runtime26.jsxDEV("p", {
56103
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV("p", {
56066
56104
  children: "Choose a conversation from the sidebar"
56067
56105
  }, undefined, false, undefined, this)
56068
56106
  ]
56069
56107
  }, undefined, true, undefined, this),
56070
- view.kind === "session" && (view.presenting ? /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(SessionPresentation, {
56108
+ view.kind === "session" && (view.presenting ? /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(SessionPresentation, {
56071
56109
  sessionId: view.session.sessionId,
56072
56110
  project: view.project.encodedPath,
56073
56111
  onExit: togglePresentation
56074
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(SessionView, {
56112
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(SessionView, {
56075
56113
  sessionId: view.session.sessionId,
56076
56114
  project: view.project.encodedPath
56077
56115
  }, undefined, false, undefined, this)),
56078
- view.kind === "subagent" && (view.presenting ? /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(SubAgentPresentation, {
56116
+ view.kind === "subagent" && (view.presenting ? /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(SubAgentPresentation, {
56079
56117
  sessionId: view.sessionId,
56080
56118
  project: view.project.encodedPath,
56081
56119
  agentId: view.agentId,
56082
56120
  onExit: togglePresentation
56083
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(SubAgentView, {
56121
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(SubAgentView, {
56084
56122
  sessionId: view.sessionId,
56085
56123
  project: view.project.encodedPath,
56086
56124
  agentId: view.agentId
@@ -56093,4 +56131,4 @@ function App() {
56093
56131
  }, undefined, true, undefined, this);
56094
56132
  }
56095
56133
  var root4 = import_client.createRoot(document.getElementById("root"));
56096
- root4.render(/* @__PURE__ */ jsx_dev_runtime26.jsxDEV(App, {}, undefined, false, undefined, this));
56134
+ root4.render(/* @__PURE__ */ jsx_dev_runtime27.jsxDEV(App, {}, undefined, false, undefined, this));