@ottocode/web-sdk 0.1.269 → 0.1.270

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2379,6 +2379,20 @@ function Modal({
2379
2379
  document.addEventListener("keydown", handleEscape);
2380
2380
  return () => document.removeEventListener("keydown", handleEscape);
2381
2381
  }, [isOpen, closeOnEscape, onClose]);
2382
+ useEffect5(() => {
2383
+ if (!isOpen)
2384
+ return;
2385
+ const handleNativeBack = (event) => {
2386
+ const customEvent = event;
2387
+ if (!customEvent.detail || customEvent.detail.handled)
2388
+ return;
2389
+ customEvent.detail.handled = true;
2390
+ event.preventDefault();
2391
+ onClose();
2392
+ };
2393
+ window.addEventListener("otto:native-back", handleNativeBack);
2394
+ return () => window.removeEventListener("otto:native-back", handleNativeBack);
2395
+ }, [isOpen, onClose]);
2382
2396
  useEffect5(() => {
2383
2397
  if (isOpen) {
2384
2398
  document.body.style.overflow = "hidden";
@@ -11775,7 +11789,7 @@ var MessagePartItem = memo8(function MessagePartItem2({
11775
11789
  })
11776
11790
  }),
11777
11791
  /* @__PURE__ */ jsx56("div", {
11778
- className: `${isCompactThread ? "text-[14px]" : "text-base"} text-foreground leading-relaxed markdown-content max-w-full overflow-x-auto`,
11792
+ className: `${isCompactThread ? "text-[16.5px]" : "text-[17px]"} text-foreground leading-relaxed markdown-content max-w-full overflow-x-auto`,
11779
11793
  children: /* @__PURE__ */ jsx56(ReactMarkdown, {
11780
11794
  remarkPlugins: [remarkGfm],
11781
11795
  components: {
@@ -11943,7 +11957,7 @@ var MessagePartItem = memo8(function MessagePartItem2({
11943
11957
  });
11944
11958
  }
11945
11959
  const containerClasses = [
11946
- `flex flex-wrap items-center gap-x-2 gap-y-1 ${isCompactThread ? "text-[12px]" : "text-[13px]"} text-foreground/80 max-w-full`
11960
+ `flex flex-wrap items-center gap-x-2 gap-y-1 ${isCompactThread ? "text-[13px]" : "text-[14px]"} text-foreground/80 max-w-full`
11947
11961
  ];
11948
11962
  if (part.ephemeral)
11949
11963
  containerClasses.push("animate-pulse");
@@ -12436,7 +12450,7 @@ function CompactActivityGroup({
12436
12450
  },
12437
12451
  children: [
12438
12452
  /* @__PURE__ */ jsx57("div", {
12439
- className: "text-[11px] font-medium uppercase tracking-[0.18em] text-muted-foreground/70 mb-1",
12453
+ className: "text-[12px] font-medium uppercase tracking-[0.18em] text-muted-foreground/70 mb-1",
12440
12454
  children: "Exploring"
12441
12455
  }),
12442
12456
  /* @__PURE__ */ jsx57("div", {
@@ -12470,13 +12484,13 @@ function CompactActivityGroup({
12470
12484
  animation: isNewAppend ? `ottoEntryIn ${ANIM_MS}ms ${EASING} both` : undefined
12471
12485
  },
12472
12486
  children: /* @__PURE__ */ jsx57("p", {
12473
- className: `text-[11px] leading-relaxed font-mono whitespace-pre-wrap ${isLast ? "text-foreground/80" : "text-muted-foreground/60"}`,
12487
+ className: `text-[12px] leading-relaxed font-mono whitespace-pre-wrap ${isLast ? "text-foreground/80" : "text-muted-foreground/60"}`,
12474
12488
  children: entry.fullText
12475
12489
  })
12476
12490
  }, entry.id);
12477
12491
  }
12478
12492
  return /* @__PURE__ */ jsx57("div", {
12479
- className: `flex items-center px-1 ${isCompact ? "text-[13px]" : "text-[14px]"} leading-5 h-7 ${isLast ? "text-foreground" : "text-muted-foreground/70"}`,
12493
+ className: `flex items-center px-1 ${isCompact ? "text-[14px]" : "text-[15px]"} leading-5 h-7 ${isLast ? "text-foreground" : "text-muted-foreground/70"}`,
12480
12494
  style: {
12481
12495
  animation: isNewAppend ? `ottoEntryIn ${ANIM_MS}ms ${EASING} both` : undefined
12482
12496
  },
@@ -12491,7 +12505,7 @@ function CompactActivityGroup({
12491
12505
  ]
12492
12506
  }),
12493
12507
  /* @__PURE__ */ jsx57("div", {
12494
- className: `flex items-center ${isCompact ? "text-[11px]" : "text-xs"}`,
12508
+ className: `flex items-center ${isCompact ? "text-[12px]" : "text-xs"}`,
12495
12509
  style: {
12496
12510
  opacity: showSummary ? 1 : 0,
12497
12511
  height: showSummary ? "20px" : "0px",
@@ -12793,7 +12807,7 @@ function ActionToolBox({ part, showLine }) {
12793
12807
  },
12794
12808
  children: [
12795
12809
  /* @__PURE__ */ jsxs49("div", {
12796
- className: `flex items-center gap-2 ${isCompact ? "text-[12px]" : "text-[13px]"} font-medium uppercase tracking-[0.18em] text-muted-foreground/70`,
12810
+ className: `flex items-center gap-2 ${isCompact ? "text-[13px]" : "text-[14px]"} font-medium uppercase tracking-[0.18em] text-muted-foreground/70`,
12797
12811
  children: [
12798
12812
  /* @__PURE__ */ jsx58(Loader23, {
12799
12813
  className: "h-3 w-3 animate-spin flex-shrink-0"
@@ -12846,7 +12860,7 @@ function ActionToolBox({ part, showLine }) {
12846
12860
  },
12847
12861
  children: /* @__PURE__ */ jsx58("pre", {
12848
12862
  ref: contentMeasureRef,
12849
- className: "px-1 pt-2.5 pb-1 text-[11px] leading-relaxed text-foreground/60 font-mono whitespace-pre-wrap break-all",
12863
+ className: "px-1 pt-2.5 pb-1 text-[12px] leading-relaxed text-foreground/60 font-mono whitespace-pre-wrap break-all",
12850
12864
  children: displayContent
12851
12865
  })
12852
12866
  })
@@ -13820,7 +13834,7 @@ var UserMessageGroup = memo10(function UserMessageGroup2({
13820
13834
  ]
13821
13835
  }),
13822
13836
  /* @__PURE__ */ jsxs52("div", {
13823
- className: "inline-block max-w-full text-sm text-foreground leading-relaxed bg-emerald-500/5 border border-emerald-500/20 rounded-xl px-4 py-3 [word-break:break-word] overflow-hidden",
13837
+ className: "inline-block max-w-full text-[16.5px] text-foreground leading-relaxed bg-emerald-500/5 border border-emerald-500/20 rounded-xl px-4 py-3 [word-break:break-word] overflow-hidden",
13824
13838
  children: [
13825
13839
  hasImages && /* @__PURE__ */ jsx61("div", {
13826
13840
  className: "flex flex-wrap gap-2 mb-2",
@@ -13868,7 +13882,7 @@ var UserMessageGroup = memo10(function UserMessageGroup2({
13868
13882
  }, ctx.id))
13869
13883
  }),
13870
13884
  hasContent && /* @__PURE__ */ jsx61("div", {
13871
- className: "prose prose-invert prose-sm [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&_*]:[word-break:break-word] [&_*]:overflow-wrap-anywhere whitespace-pre-wrap",
13885
+ className: "prose prose-invert prose-sm [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&_p]:text-[16.5px] [&_li]:text-[16.5px] [&_*]:[word-break:break-word] [&_*]:overflow-wrap-anywhere whitespace-pre-wrap",
13872
13886
  children: /* @__PURE__ */ jsx61(ReactMarkdown2, {
13873
13887
  remarkPlugins: [remarkGfm2],
13874
13888
  components: {
@@ -17536,12 +17550,12 @@ function GitDiffViewer({ diff }) {
17536
17550
  className: "px-3 py-1.5 bg-sidebar-accent/30 border-b border-sidebar-border/60 flex items-center justify-between min-h-8",
17537
17551
  children: [
17538
17552
  /* @__PURE__ */ jsx74("span", {
17539
- className: "font-mono text-[12px] text-foreground truncate",
17553
+ className: "font-mono text-[13px] text-foreground truncate",
17540
17554
  title: diff.file,
17541
17555
  children: fileName
17542
17556
  }),
17543
17557
  /* @__PURE__ */ jsxs65("div", {
17544
- className: "flex items-center gap-2 text-[10px] flex-shrink-0",
17558
+ className: "flex items-center gap-2 text-[11px] flex-shrink-0",
17545
17559
  children: [
17546
17560
  /* @__PURE__ */ jsxs65("span", {
17547
17561
  className: "text-green-600 dark:text-green-500",
@@ -17561,7 +17575,7 @@ function GitDiffViewer({ diff }) {
17561
17575
  /* @__PURE__ */ jsx74("div", {
17562
17576
  className: "px-4 py-3 bg-green-500/10 border-b border-green-500/20",
17563
17577
  children: /* @__PURE__ */ jsxs65("p", {
17564
- className: "text-[12px] text-green-600 dark:text-green-400 font-medium",
17578
+ className: "text-[13px] text-green-600 dark:text-green-400 font-medium",
17565
17579
  children: [
17566
17580
  "New file: ",
17567
17581
  diff.insertions,
@@ -17612,12 +17626,12 @@ function GitDiffViewer({ diff }) {
17612
17626
  className: "px-3 py-1.5 bg-sidebar-accent/30 border-b border-sidebar-border/60 flex items-center justify-between min-h-8",
17613
17627
  children: [
17614
17628
  /* @__PURE__ */ jsx74("span", {
17615
- className: "font-mono text-[12px] text-foreground truncate",
17629
+ className: "font-mono text-[13px] text-foreground truncate",
17616
17630
  title: diff.file,
17617
17631
  children: fileName
17618
17632
  }),
17619
17633
  /* @__PURE__ */ jsx74("div", {
17620
- className: "flex items-center gap-2 text-[10px] flex-shrink-0",
17634
+ className: "flex items-center gap-2 text-[11px] flex-shrink-0",
17621
17635
  children: /* @__PURE__ */ jsx74("span", {
17622
17636
  className: "text-muted-foreground",
17623
17637
  children: "Binary file"
@@ -17637,7 +17651,7 @@ function GitDiffViewer({ diff }) {
17637
17651
  children: /* @__PURE__ */ jsx74("div", {
17638
17652
  className: "p-4 text-center",
17639
17653
  children: /* @__PURE__ */ jsx74("p", {
17640
- className: "text-[12px] text-muted-foreground",
17654
+ className: "text-[13px] text-muted-foreground",
17641
17655
  children: "Binary file - cannot display diff"
17642
17656
  })
17643
17657
  })
@@ -17704,8 +17718,8 @@ function GitDiffViewer({ diff }) {
17704
17718
  }
17705
17719
  const renderLine = (diffLine, index) => {
17706
17720
  let rowClassName = "flex hover:bg-muted/20";
17707
- let lineNumberClassName = "flex-shrink-0 w-20 px-2 py-0.5 text-xs font-mono select-none border-r border-border";
17708
- let contentClassName = "flex-1 px-4 py-0.5 font-mono text-xs whitespace-pre";
17721
+ let lineNumberClassName = "flex-shrink-0 w-20 px-2 py-0.5 text-[13px] font-mono select-none border-r border-border";
17722
+ let contentClassName = "flex-1 px-4 py-0.5 font-mono text-[13px] whitespace-pre";
17709
17723
  if (diffLine.type === "hunk") {
17710
17724
  rowClassName += " bg-blue-500/10";
17711
17725
  lineNumberClassName += " text-blue-600 dark:text-blue-400";
@@ -18755,7 +18769,7 @@ Please help me fix this.`;
18755
18769
  ]
18756
18770
  }),
18757
18771
  /* @__PURE__ */ jsxs68("div", {
18758
- className: "h-9 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between gap-2",
18772
+ className: "h-12 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between gap-2",
18759
18773
  children: [
18760
18774
  /* @__PURE__ */ jsxs68("div", {
18761
18775
  className: "flex items-center gap-2 min-w-0 flex-1",
@@ -18904,13 +18918,13 @@ var GitDiffPanel = memo22(function GitDiffPanel2({
18904
18918
  className: "flex-1 flex items-center gap-2 min-w-0",
18905
18919
  children: [
18906
18920
  /* @__PURE__ */ jsx79("span", {
18907
- className: "text-[12px] font-medium text-foreground font-mono truncate",
18921
+ className: "text-[13px] font-medium text-foreground font-mono truncate",
18908
18922
  title: `${selectedFile}
18909
18923
  ${activeDiff?.absPath || ""}`,
18910
18924
  children: selectedFile
18911
18925
  }),
18912
18926
  selectedFileStaged && /* @__PURE__ */ jsx79("span", {
18913
- className: "text-[11px] px-1.5 py-0.5 rounded bg-primary/10 text-primary flex-shrink-0",
18927
+ className: "text-[12px] px-1.5 py-0.5 rounded bg-primary/10 text-primary flex-shrink-0",
18914
18928
  children: "Staged"
18915
18929
  })
18916
18930
  ]
@@ -18920,7 +18934,7 @@ ${activeDiff?.absPath || ""}`,
18920
18934
  size: "sm",
18921
18935
  onClick: () => setShowFullFile((v) => !v),
18922
18936
  title: showFullFile ? "Show diff only (f)" : "Show full file with diff (f)",
18923
- className: "flex items-center gap-1.5 text-[12px] h-8 px-2.5",
18937
+ className: "flex items-center gap-1.5 text-[13px] h-8 px-2.5",
18924
18938
  children: [
18925
18939
  showFullFile ? /* @__PURE__ */ jsx79(Minimize22, {
18926
18940
  className: "w-3.5 h-3.5"
@@ -20109,7 +20123,7 @@ var SessionFilesSidebar = memo26(function SessionFilesSidebar2({
20109
20123
  })
20110
20124
  }),
20111
20125
  /* @__PURE__ */ jsxs76("div", {
20112
- className: "h-9 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between gap-2",
20126
+ className: "h-12 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between gap-2",
20113
20127
  children: [
20114
20128
  /* @__PURE__ */ jsxs76("div", {
20115
20129
  className: "flex items-center gap-2 min-w-0 flex-1",
@@ -20376,7 +20390,7 @@ function FullHeightDiffView({ patch }) {
20376
20390
  return /* @__PURE__ */ jsx87("div", {
20377
20391
  className: "bg-card/60 border border-border rounded-lg overflow-hidden h-full",
20378
20392
  children: /* @__PURE__ */ jsx87("div", {
20379
- className: "overflow-x-auto overflow-y-auto h-full text-xs font-mono",
20393
+ className: "overflow-x-auto overflow-y-auto h-full text-[13px] font-mono",
20380
20394
  children: diffLines.map((line, i) => {
20381
20395
  const key = `line-${i}-${line.content.slice(0, 20)}`;
20382
20396
  if (line.type === "meta" || line.type === "header") {
@@ -20564,16 +20578,16 @@ ${contentLines.map((line) => `+${line}`).join(`
20564
20578
  className: "flex-1 flex items-center gap-2 min-w-0",
20565
20579
  children: [
20566
20580
  /* @__PURE__ */ jsx87("span", {
20567
- className: "text-[12px] font-medium text-foreground font-mono truncate",
20581
+ className: "text-[13px] font-medium text-foreground font-mono truncate",
20568
20582
  title: selectedFile,
20569
20583
  children: selectedFile
20570
20584
  }),
20571
20585
  /* @__PURE__ */ jsx87("span", {
20572
- className: "text-[11px] px-1.5 py-0.5 rounded bg-primary/10 text-primary flex-shrink-0 capitalize",
20586
+ className: "text-[12px] px-1.5 py-0.5 rounded bg-primary/10 text-primary flex-shrink-0 capitalize",
20573
20587
  children: selectedOperation.operation
20574
20588
  }),
20575
20589
  selectedOperation.artifact?.summary && /* @__PURE__ */ jsxs78("div", {
20576
- className: "flex items-center gap-1 text-[11px] flex-shrink-0",
20590
+ className: "flex items-center gap-1 text-[12px] flex-shrink-0",
20577
20591
  children: [
20578
20592
  /* @__PURE__ */ jsxs78("span", {
20579
20593
  className: "text-green-500",
@@ -21273,7 +21287,7 @@ var ResearchSidebar = memo29(function ResearchSidebar2({
21273
21287
  ]
21274
21288
  }),
21275
21289
  /* @__PURE__ */ jsxs79("div", {
21276
- className: "h-9 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between",
21290
+ className: "h-12 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between",
21277
21291
  children: [
21278
21292
  /* @__PURE__ */ jsxs79("span", {
21279
21293
  className: "text-[10px]",
@@ -22487,7 +22501,7 @@ var SettingsSidebar = memo31(function SettingsSidebar2() {
22487
22501
  type: "button",
22488
22502
  onClick: () => setIsPreferencesOpen(true),
22489
22503
  title: "Open preferences",
22490
- className: "group shrink-0 w-full h-10 px-3 flex items-center gap-2 bg-muted/20 hover:bg-muted/60 border-t border-border transition-colors text-left cursor-pointer",
22504
+ className: "group shrink-0 w-full h-12 px-3 flex items-center gap-2 bg-muted/20 hover:bg-muted/60 border-t border-border transition-colors text-left cursor-pointer",
22491
22505
  children: [
22492
22506
  /* @__PURE__ */ jsx90(User3, {
22493
22507
  className: "w-4 h-4 text-muted-foreground group-hover:text-foreground transition-colors"
@@ -24886,7 +24900,7 @@ var SkillsSidebar = memo39(function SkillsSidebar2() {
24886
24900
  })
24887
24901
  }),
24888
24902
  /* @__PURE__ */ jsxs87("div", {
24889
- className: "h-9 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between gap-2",
24903
+ className: "h-12 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between gap-2",
24890
24904
  children: [
24891
24905
  /* @__PURE__ */ jsxs87("div", {
24892
24906
  className: "flex items-center gap-2 min-w-0 flex-1",
@@ -25031,22 +25045,22 @@ var SkillViewerPanel = memo41(function SkillViewerPanel2({
25031
25045
  className: "flex-1 flex items-center gap-2 min-w-0",
25032
25046
  children: [
25033
25047
  /* @__PURE__ */ jsx100("span", {
25034
- className: "text-[12px] text-muted-foreground flex-shrink-0",
25048
+ className: "text-[13px] text-muted-foreground flex-shrink-0",
25035
25049
  children: selectedSkill
25036
25050
  }),
25037
25051
  /* @__PURE__ */ jsx100("span", {
25038
- className: "text-[12px] text-muted-foreground",
25052
+ className: "text-[13px] text-muted-foreground",
25039
25053
  children: "/"
25040
25054
  }),
25041
25055
  /* @__PURE__ */ jsx100("span", {
25042
- className: "text-[12px] font-medium text-foreground font-mono truncate",
25056
+ className: "text-[13px] font-medium text-foreground font-mono truncate",
25043
25057
  title: displayPath,
25044
25058
  children: displayPath
25045
25059
  })
25046
25060
  ]
25047
25061
  }),
25048
25062
  /* @__PURE__ */ jsx100("span", {
25049
- className: "text-[11px] text-muted-foreground pr-1",
25063
+ className: "text-[12px] text-muted-foreground pr-1",
25050
25064
  children: language
25051
25065
  })
25052
25066
  ]
@@ -25070,8 +25084,8 @@ var SkillViewerPanel = memo41(function SkillViewerPanel2({
25070
25084
  margin: 0,
25071
25085
  padding: "1rem",
25072
25086
  background: "transparent",
25073
- fontSize: "0.75rem",
25074
- lineHeight: "1.25rem"
25087
+ fontSize: "0.8125rem",
25088
+ lineHeight: "1.3125rem"
25075
25089
  },
25076
25090
  codeTagProps: {
25077
25091
  style: {
@@ -25234,7 +25248,7 @@ var FileBrowserSidebar = memo42(function FileBrowserSidebar2() {
25234
25248
  }, item.path))
25235
25249
  }),
25236
25250
  /* @__PURE__ */ jsxs89("div", {
25237
- className: "h-9 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between gap-2",
25251
+ className: "h-12 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between gap-2",
25238
25252
  children: [
25239
25253
  /* @__PURE__ */ jsxs89("div", {
25240
25254
  className: "flex items-center gap-2 min-w-0 flex-1",
@@ -25383,12 +25397,12 @@ var FileViewerPanel = memo44(function FileViewerPanel2({
25383
25397
  className: "flex-1 flex items-center gap-2 min-w-0",
25384
25398
  children: [
25385
25399
  /* @__PURE__ */ jsx103("span", {
25386
- className: "text-[12px] font-medium text-foreground font-mono truncate",
25400
+ className: "text-[13px] font-medium text-foreground font-mono truncate",
25387
25401
  title: selectedFile,
25388
25402
  children: selectedFile
25389
25403
  }),
25390
25404
  data && /* @__PURE__ */ jsxs90("span", {
25391
- className: "text-[11px] text-muted-foreground flex-shrink-0",
25405
+ className: "text-[12px] text-muted-foreground flex-shrink-0",
25392
25406
  children: [
25393
25407
  data.lineCount,
25394
25408
  " lines"
@@ -25397,7 +25411,7 @@ var FileViewerPanel = memo44(function FileViewerPanel2({
25397
25411
  ]
25398
25412
  }),
25399
25413
  /* @__PURE__ */ jsx103("span", {
25400
- className: "text-[11px] text-muted-foreground pr-1",
25414
+ className: "text-[12px] text-muted-foreground pr-1",
25401
25415
  children: language
25402
25416
  })
25403
25417
  ]
@@ -25408,7 +25422,7 @@ var FileViewerPanel = memo44(function FileViewerPanel2({
25408
25422
  className: "h-full flex items-center justify-center text-muted-foreground",
25409
25423
  children: "Loading file..."
25410
25424
  }) : data ? renderMarkdown ? /* @__PURE__ */ jsx103("div", {
25411
- className: "p-4 text-[13px] text-foreground leading-5 markdown-content max-w-full overflow-x-auto",
25425
+ className: "p-4 text-[14px] text-foreground leading-6 markdown-content max-w-full overflow-x-auto",
25412
25426
  children: /* @__PURE__ */ jsx103(ReactMarkdown3, {
25413
25427
  remarkPlugins: [remarkGfm3],
25414
25428
  components: {
@@ -25459,8 +25473,8 @@ var FileViewerPanel = memo44(function FileViewerPanel2({
25459
25473
  margin: 0,
25460
25474
  padding: "1rem",
25461
25475
  background: "transparent",
25462
- fontSize: "0.75rem",
25463
- lineHeight: "1.25rem"
25476
+ fontSize: "0.8125rem",
25477
+ lineHeight: "1.3125rem"
25464
25478
  },
25465
25479
  codeTagProps: {
25466
25480
  style: {
@@ -25700,7 +25714,7 @@ function HighlightedPath({ path, query }) {
25700
25714
  });
25701
25715
  }
25702
25716
  // src/components/onboarding/OnboardingModal.tsx
25703
- import { memo as memo48 } from "react";
25717
+ import { memo as memo48, useEffect as useEffect50 } from "react";
25704
25718
 
25705
25719
  // src/components/onboarding/steps/ProviderSetupStep.tsx
25706
25720
  import { memo as memo46, useEffect as useEffect48, useState as useState46, useRef as useRef33 } from "react";
@@ -26136,6 +26150,98 @@ var ProviderSetupStep = memo46(function ProviderSetupStep2({
26136
26150
  setImportWalletError(null);
26137
26151
  setImportPrivateKey("");
26138
26152
  };
26153
+ useEffect48(() => {
26154
+ const handleNativeBack = (event) => {
26155
+ const customEvent = event;
26156
+ if (!customEvent.detail || customEvent.detail.handled)
26157
+ return;
26158
+ const markHandled = () => {
26159
+ customEvent.detail.handled = true;
26160
+ event.preventDefault();
26161
+ };
26162
+ if (isCustomProviderModalOpen) {
26163
+ markHandled();
26164
+ if (!isAddingCustomProvider) {
26165
+ setIsCustomProviderModalOpen(false);
26166
+ setCustomProviderId("");
26167
+ setCustomProviderLabel("");
26168
+ setCustomProviderBaseURL("");
26169
+ setCustomProviderApiKey("");
26170
+ setCustomProviderModels("");
26171
+ setCustomProviderCompatibility("openai-compatible");
26172
+ setCustomProviderAllowAnyModel(true);
26173
+ setCustomProviderError(null);
26174
+ setDiscoveredCustomModels([]);
26175
+ setCustomProviderDiscoveryMessage(null);
26176
+ }
26177
+ return;
26178
+ }
26179
+ if (isImportModalOpen) {
26180
+ markHandled();
26181
+ if (!isImportingWallet) {
26182
+ setIsImportModalOpen(false);
26183
+ setImportWalletError(null);
26184
+ setImportPrivateKey("");
26185
+ }
26186
+ return;
26187
+ }
26188
+ if (oauthSession) {
26189
+ markHandled();
26190
+ if (!isExchangingCode && !isOpeningPopup) {
26191
+ setOauthSession(null);
26192
+ setOauthCodeInput("");
26193
+ }
26194
+ return;
26195
+ }
26196
+ if (copilotModalOpen) {
26197
+ markHandled();
26198
+ if (!copilotTokenSaving && !copilotGhImporting && !copilotLoading) {
26199
+ setCopilotDevice(null);
26200
+ setCopilotPolling(false);
26201
+ setCopilotError(null);
26202
+ setCopilotTokenInput("");
26203
+ setCopilotTokenSaving(false);
26204
+ setCopilotGhImporting(false);
26205
+ setCopilotAuthMode("oauth");
26206
+ setCopilotCodeCopied(false);
26207
+ setCopilotModalOpen(false);
26208
+ setCopilotLoading(false);
26209
+ copilotCancelledRef.current = true;
26210
+ if (copilotPollRef.current) {
26211
+ clearTimeout(copilotPollRef.current);
26212
+ copilotPollRef.current = undefined;
26213
+ }
26214
+ }
26215
+ return;
26216
+ }
26217
+ if (addingProvider) {
26218
+ markHandled();
26219
+ setAddingProvider(null);
26220
+ setApiKeyInput("");
26221
+ return;
26222
+ }
26223
+ if (confirmingDelete) {
26224
+ markHandled();
26225
+ setConfirmingDelete(null);
26226
+ }
26227
+ };
26228
+ window.addEventListener("otto:native-back", handleNativeBack);
26229
+ return () => window.removeEventListener("otto:native-back", handleNativeBack);
26230
+ }, [
26231
+ addingProvider,
26232
+ confirmingDelete,
26233
+ copilotGhImporting,
26234
+ copilotLoading,
26235
+ copilotModalOpen,
26236
+ copilotTokenSaving,
26237
+ isAddingCustomProvider,
26238
+ isCustomProviderModalOpen,
26239
+ isExchangingCode,
26240
+ isImportingWallet,
26241
+ isImportModalOpen,
26242
+ isOpeningPopup,
26243
+ oauthSession
26244
+ ]);
26139
26245
  const handleImportWallet = async () => {
26140
26246
  if (!importPrivateKey.trim() || isImportingWallet)
26141
26247
  return;
@@ -26610,6 +26716,7 @@ var ProviderSetupStep = memo46(function ProviderSetupStep2({
26610
26716
  })
26611
26717
  }),
26612
26718
  isCustomProviderModalOpen && /* @__PURE__ */ jsx105("div", {
26719
+ "data-otto-nested-modal": "true",
26613
26720
  className: "fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 backdrop-blur-sm",
26614
26721
  children: /* @__PURE__ */ jsxs92("div", {
26615
26722
  className: "bg-background border border-border rounded-xl w-full max-w-2xl mx-6 shadow-2xl max-h-[90vh] overflow-y-auto",
@@ -26872,6 +26979,7 @@ var ProviderSetupStep = memo46(function ProviderSetupStep2({
26872
26979
  })
26873
26980
  }),
26874
26981
  isImportModalOpen && /* @__PURE__ */ jsx105("div", {
26982
+ "data-otto-nested-modal": "true",
26875
26983
  className: "fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 backdrop-blur-sm",
26876
26984
  children: /* @__PURE__ */ jsxs92("div", {
26877
26985
  className: "bg-background border border-border rounded-xl w-full max-w-lg mx-6 shadow-2xl",
@@ -26942,6 +27050,7 @@ var ProviderSetupStep = memo46(function ProviderSetupStep2({
26942
27050
  })
26943
27051
  }),
26944
27052
  oauthSession && /* @__PURE__ */ jsx105("div", {
27053
+ "data-otto-nested-modal": "true",
26945
27054
  className: "fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 backdrop-blur-sm",
26946
27055
  children: /* @__PURE__ */ jsxs92("div", {
26947
27056
  className: "bg-background border border-border rounded-xl w-full max-w-lg mx-6 shadow-2xl",
@@ -27051,6 +27160,7 @@ var ProviderSetupStep = memo46(function ProviderSetupStep2({
27051
27160
  })
27052
27161
  }),
27053
27162
  copilotModalOpen && /* @__PURE__ */ jsx105("div", {
27163
+ "data-otto-nested-modal": "true",
27054
27164
  className: "fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 backdrop-blur-sm",
27055
27165
  children: /* @__PURE__ */ jsxs92("div", {
27056
27166
  className: "bg-background border border-border rounded-xl w-full max-w-lg mx-6 shadow-2xl",
@@ -27612,6 +27722,22 @@ var OnboardingModal = memo48(function OnboardingModal2({
27612
27722
  importCopilotTokenFromGh,
27613
27723
  getCopilotDiagnostics
27614
27724
  } = useAuthStatus();
27725
+ useEffect50(() => {
27726
+ if (!isOpen)
27727
+ return;
27728
+ const handleNativeBack = (event) => {
27729
+ const customEvent = event;
27730
+ if (!customEvent.detail || customEvent.detail.handled)
27731
+ return;
27732
+ if (document.querySelector('[data-otto-nested-modal="true"]'))
27733
+ return;
27734
+ customEvent.detail.handled = true;
27735
+ event.preventDefault();
27736
+ reset();
27737
+ };
27738
+ window.addEventListener("otto:native-back", handleNativeBack);
27739
+ return () => window.removeEventListener("otto:native-back", handleNativeBack);
27740
+ }, [isOpen, reset]);
27615
27741
  if (!isOpen || !authStatus)
27616
27742
  return null;
27617
27743
  return /* @__PURE__ */ jsxs94("div", {
@@ -27650,7 +27776,7 @@ var OnboardingModal = memo48(function OnboardingModal2({
27650
27776
  });
27651
27777
  });
27652
27778
  // src/hooks/useClientEvents.ts
27653
- import { useEffect as useEffect50, useRef as useRef35 } from "react";
27779
+ import { useEffect as useEffect51, useRef as useRef35 } from "react";
27654
27780
  import { useQueryClient as useQueryClient20 } from "@tanstack/react-query";
27655
27781
  import {
27656
27782
  buildClientEventsStreamUrl,
@@ -27778,13 +27904,63 @@ async function requestLocalhostAccess(baseUrl) {
27778
27904
  throw new Error(`Local API returned ${response.status}`);
27779
27905
  }
27780
27906
  }
27907
+ var localAccessToastIds = new Map;
27908
+ var localAccessChecksInFlight = new Set;
27909
+ function localAccessStorageKey(baseUrl) {
27910
+ return `otto-local-access-confirmed:${baseUrl}`;
27911
+ }
27912
+ function hasConfirmedLocalAccess(baseUrl) {
27913
+ try {
27914
+ return window.localStorage.getItem(localAccessStorageKey(baseUrl)) === "1";
27915
+ } catch {
27916
+ return false;
27917
+ }
27918
+ }
27919
+ function markLocalAccessConfirmed(baseUrl) {
27920
+ try {
27921
+ window.localStorage.setItem(localAccessStorageKey(baseUrl), "1");
27922
+ } catch {}
27923
+ }
27924
+ async function maybeShowLocalAccessToast(baseUrl) {
27925
+ if (hasPlatformOpenUrl())
27926
+ return;
27927
+ if (!isLocalApiUrl(baseUrl) || hasConfirmedLocalAccess(baseUrl))
27928
+ return;
27929
+ if (localAccessToastIds.has(baseUrl) || localAccessChecksInFlight.has(baseUrl)) {
27930
+ return;
27931
+ }
27932
+ localAccessChecksInFlight.add(baseUrl);
27933
+ try {
27934
+ await requestLocalhostAccess(baseUrl);
27935
+ markLocalAccessConfirmed(baseUrl);
27936
+ return;
27937
+ } catch {} finally {
27938
+ localAccessChecksInFlight.delete(baseUrl);
27939
+ }
27940
+ if (localAccessToastIds.has(baseUrl))
27941
+ return;
27942
+ const id = toast("Safari may need permission to access the local otto server.", "default", 0);
27943
+ localAccessToastIds.set(baseUrl, id);
27944
+ useToastStore.getState().updateToast(id, {
27945
+ action: {
27946
+ label: "Allow access",
27947
+ onClick: async () => {
27948
+ await requestLocalhostAccess(baseUrl);
27949
+ markLocalAccessConfirmed(baseUrl);
27950
+ useToastStore.getState().removeToast(id);
27951
+ localAccessToastIds.delete(baseUrl);
27952
+ toast.success("Local otto server access confirmed.");
27953
+ }
27954
+ }
27955
+ });
27956
+ }
27781
27957
  function useClientEvents(activeSessionId) {
27782
27958
  const queryClient = useQueryClient20();
27783
27959
  const activeSessionIdRef = useRef35(activeSessionId);
27784
- useEffect50(() => {
27960
+ useEffect51(() => {
27785
27961
  activeSessionIdRef.current = activeSessionId;
27786
27962
  }, [activeSessionId]);
27787
- useEffect50(() => {
27963
+ useEffect51(() => {
27788
27964
  if (typeof window === "undefined" || window.parent !== window)
27789
27965
  return;
27790
27966
  if (!("Notification" in window))
@@ -27811,9 +27987,8 @@ function useClientEvents(activeSessionId) {
27811
27987
  }
27812
27988
  });
27813
27989
  }, []);
27814
- useEffect50(() => {
27990
+ useEffect51(() => {
27815
27991
  const controller = new AbortController;
27816
- let hasShownLocalAccessToast = false;
27817
27992
  const baseUrl = getBaseUrl();
27818
27993
  createClientEventsStream({
27819
27994
  baseUrl,
@@ -27853,19 +28028,7 @@ function useClientEvents(activeSessionId) {
27853
28028
  onError: (error) => {
27854
28029
  if (!controller.signal.aborted) {
27855
28030
  console.error("[client-events] Stream error:", error);
27856
- if (!hasShownLocalAccessToast && isLocalApiUrl(baseUrl)) {
27857
- hasShownLocalAccessToast = true;
27858
- const id = toast("Safari may need permission to access the local otto server.", "default", 0);
27859
- useToastStore.getState().updateToast(id, {
27860
- action: {
27861
- label: "Allow access",
27862
- onClick: async () => {
27863
- await requestLocalhostAccess(baseUrl);
27864
- toast.success("Local otto server access confirmed.");
27865
- }
27866
- }
27867
- });
27868
- }
28031
+ maybeShowLocalAccessToast(baseUrl);
27869
28032
  }
27870
28033
  }
27871
28034
  }, controller.signal);
@@ -27874,7 +28037,7 @@ function useClientEvents(activeSessionId) {
27874
28037
  return buildClientEventsStreamUrl({ baseUrl: getBaseUrl() });
27875
28038
  }
27876
28039
  // src/hooks/useTheme.ts
27877
- import { useEffect as useEffect51, useState as useState48, useCallback as useCallback34, useMemo as useMemo26 } from "react";
28040
+ import { useEffect as useEffect52, useState as useState48, useCallback as useCallback34, useMemo as useMemo26 } from "react";
27878
28041
  var STORAGE_KEY3 = "otto-theme";
27879
28042
  function resolveInitialTheme() {
27880
28043
  if (typeof window === "undefined") {
@@ -27891,7 +28054,7 @@ function resolveInitialTheme() {
27891
28054
  }
27892
28055
  function useTheme() {
27893
28056
  const [theme, setTheme] = useState48(() => resolveInitialTheme());
27894
- useEffect51(() => {
28057
+ useEffect52(() => {
27895
28058
  if (typeof document === "undefined")
27896
28059
  return;
27897
28060
  const root = document.documentElement;
@@ -27909,7 +28072,7 @@ function useTheme() {
27909
28072
  window.parent.postMessage({ type: "otto-set-theme", theme }, "*");
27910
28073
  }
27911
28074
  }, [theme]);
27912
- useEffect51(() => {
28075
+ useEffect52(() => {
27913
28076
  if (typeof window === "undefined")
27914
28077
  return;
27915
28078
  const handler = (e) => {
@@ -27926,11 +28089,11 @@ function useTheme() {
27926
28089
  return useMemo26(() => ({ theme, setTheme, toggleTheme }), [theme, toggleTheme]);
27927
28090
  }
27928
28091
  // src/hooks/useWorkingDirectory.ts
27929
- import { useEffect as useEffect52, useState as useState49 } from "react";
28092
+ import { useEffect as useEffect53, useState as useState49 } from "react";
27930
28093
  import { getCwd } from "@ottocode/api";
27931
28094
  function useWorkingDirectory() {
27932
28095
  const [dirName, setDirName] = useState49(null);
27933
- useEffect52(() => {
28096
+ useEffect53(() => {
27934
28097
  const fetchWorkingDirectory = async () => {
27935
28098
  try {
27936
28099
  const response = await getCwd({ baseURL: getBaseUrl() });
@@ -27954,7 +28117,7 @@ function useWorkingDirectory() {
27954
28117
  return dirName;
27955
28118
  }
27956
28119
  // src/hooks/useKeyboardShortcuts.ts
27957
- import { useEffect as useEffect53, useCallback as useCallback35 } from "react";
28120
+ import { useEffect as useEffect54, useCallback as useCallback35 } from "react";
27958
28121
 
27959
28122
  // src/stores/sidebarStore.ts
27960
28123
  import { create as create22 } from "zustand";
@@ -28199,7 +28362,7 @@ function useKeyboardShortcuts({
28199
28362
  onReturnToInput,
28200
28363
  closeDiff
28201
28364
  ]);
28202
- useEffect53(() => {
28365
+ useEffect54(() => {
28203
28366
  window.addEventListener("keydown", handleKeyDown);
28204
28367
  return () => window.removeEventListener("keydown", handleKeyDown);
28205
28368
  }, [handleKeyDown]);
@@ -28213,7 +28376,7 @@ function useKeyboardShortcuts({
28213
28376
  import {
28214
28377
  useState as useState50,
28215
28378
  useCallback as useCallback36,
28216
- useEffect as useEffect54
28379
+ useEffect as useEffect55
28217
28380
  } from "react";
28218
28381
  var SUPPORTED_TYPES2 = ["image/png", "image/jpeg", "image/gif", "image/webp"];
28219
28382
  function generateId2() {
@@ -28349,7 +28512,7 @@ function useImageUpload(options = {}) {
28349
28512
  addImages(imageFiles);
28350
28513
  }
28351
28514
  }, [addImages]);
28352
- useEffect54(() => {
28515
+ useEffect55(() => {
28353
28516
  if (!pageWide)
28354
28517
  return;
28355
28518
  let dragCounter = 0;
@@ -28410,7 +28573,7 @@ function useImageUpload(options = {}) {
28410
28573
  };
28411
28574
  }
28412
28575
  // src/hooks/useSetuPayments.ts
28413
- import { useEffect as useEffect55, useRef as useRef36 } from "react";
28576
+ import { useEffect as useEffect56, useRef as useRef36 } from "react";
28414
28577
  function useSetuPayments(sessionId) {
28415
28578
  const clientRef = useRef36(null);
28416
28579
  const loadingToastIdRef = useRef36(null);
@@ -28420,7 +28583,7 @@ function useSetuPayments(sessionId) {
28420
28583
  const updateToast = useToastStore((s) => s.updateToast);
28421
28584
  const setPendingTopup = useTopupApprovalStore((s) => s.setPendingTopup);
28422
28585
  const clearPendingTopup = useTopupApprovalStore((s) => s.clearPendingTopup);
28423
- useEffect55(() => {
28586
+ useEffect56(() => {
28424
28587
  if (!sessionId)
28425
28588
  return;
28426
28589
  const client5 = new SSEClient;
@@ -28734,4 +28897,4 @@ export {
28734
28897
  API_BASE_URL
28735
28898
  };
28736
28899
 
28737
- //# debugId=21934A37955AE7B764756E2164756E21
28900
+ //# debugId=B903566D47B5809664756E2164756E21