@ottocode/web-sdk 0.1.230 → 0.1.231

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
@@ -583,7 +583,6 @@ import {
583
583
  FileText as FileText2,
584
584
  FileIcon,
585
585
  FlaskConical,
586
- RefreshCw as RefreshCw2,
587
586
  ChevronUp
588
587
  } from "lucide-react";
589
588
 
@@ -1707,6 +1706,26 @@ function useUpdateDefaults() {
1707
1706
  const queryClient = useQueryClient();
1708
1707
  return useMutation({
1709
1708
  mutationFn: (data) => apiClient.updateDefaults(data),
1709
+ onMutate: async (data) => {
1710
+ await queryClient.cancelQueries({ queryKey: ["config"] });
1711
+ const previousConfig = queryClient.getQueryData(["config"]);
1712
+ if (previousConfig) {
1713
+ const defaultUpdates = Object.fromEntries(Object.entries(data).filter(([key, value]) => key !== "scope" && value !== undefined));
1714
+ queryClient.setQueryData(["config"], {
1715
+ ...previousConfig,
1716
+ defaults: {
1717
+ ...previousConfig.defaults,
1718
+ ...defaultUpdates
1719
+ }
1720
+ });
1721
+ }
1722
+ return { previousConfig };
1723
+ },
1724
+ onError: (_error, _data, context) => {
1725
+ if (context?.previousConfig) {
1726
+ queryClient.setQueryData(["config"], context.previousConfig);
1727
+ }
1728
+ },
1710
1729
  onSuccess: () => {
1711
1730
  queryClient.invalidateQueries({ queryKey: ["config"] });
1712
1731
  }
@@ -1716,28 +1735,27 @@ function useUpdateDefaults() {
1716
1735
  // src/hooks/usePreferences.ts
1717
1736
  import { useCallback as useCallback4, useMemo as useMemo2, useSyncExternalStore } from "react";
1718
1737
  var STORAGE_KEY = "otto-preferences";
1719
- var DEFAULT_PREFERENCES = {
1738
+ var DEFAULT_STORED_PREFERENCES = {
1720
1739
  vimMode: false,
1721
- compactThread: true,
1722
- fullWidthContent: false
1740
+ compactThread: true
1723
1741
  };
1724
1742
  function resolveInitialPreferences() {
1725
1743
  if (typeof window === "undefined") {
1726
- return DEFAULT_PREFERENCES;
1744
+ return DEFAULT_STORED_PREFERENCES;
1727
1745
  }
1728
1746
  try {
1729
1747
  const stored = window.localStorage.getItem(STORAGE_KEY);
1730
1748
  if (stored) {
1731
1749
  const parsed = JSON.parse(stored);
1732
1750
  return {
1733
- ...DEFAULT_PREFERENCES,
1734
- ...parsed
1751
+ vimMode: typeof parsed.vimMode === "boolean" ? parsed.vimMode : DEFAULT_STORED_PREFERENCES.vimMode,
1752
+ compactThread: typeof parsed.compactThread === "boolean" ? parsed.compactThread : DEFAULT_STORED_PREFERENCES.compactThread
1735
1753
  };
1736
1754
  }
1737
1755
  } catch (error) {
1738
1756
  console.warn("Failed to load preferences", error);
1739
1757
  }
1740
- return DEFAULT_PREFERENCES;
1758
+ return DEFAULT_STORED_PREFERENCES;
1741
1759
  }
1742
1760
  var preferences = resolveInitialPreferences();
1743
1761
  var listeners = new Set;
@@ -1745,7 +1763,7 @@ function getSnapshot() {
1745
1763
  return preferences;
1746
1764
  }
1747
1765
  function getServerSnapshot() {
1748
- return DEFAULT_PREFERENCES;
1766
+ return DEFAULT_STORED_PREFERENCES;
1749
1767
  }
1750
1768
  function subscribe(listener) {
1751
1769
  listeners.add(listener);
@@ -1769,10 +1787,31 @@ function updateStore(updates) {
1769
1787
  }
1770
1788
  function usePreferences() {
1771
1789
  const currentPreferences = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
1790
+ const { data: config2 } = useConfig();
1791
+ const updateDefaults = useUpdateDefaults();
1772
1792
  const updatePreferences = useCallback4((updates) => {
1773
- updateStore(updates);
1774
- }, []);
1775
- return useMemo2(() => ({ preferences: currentPreferences, updatePreferences }), [currentPreferences, updatePreferences]);
1793
+ const localUpdates = {};
1794
+ if (updates.vimMode !== undefined) {
1795
+ localUpdates.vimMode = updates.vimMode;
1796
+ }
1797
+ if (updates.compactThread !== undefined) {
1798
+ localUpdates.compactThread = updates.compactThread;
1799
+ }
1800
+ if (Object.keys(localUpdates).length > 0) {
1801
+ updateStore(localUpdates);
1802
+ }
1803
+ if (updates.fullWidthContent !== undefined && updates.fullWidthContent !== config2?.defaults?.fullWidthContent) {
1804
+ updateDefaults.mutate({
1805
+ fullWidthContent: updates.fullWidthContent,
1806
+ scope: "global"
1807
+ });
1808
+ }
1809
+ }, [config2?.defaults?.fullWidthContent, updateDefaults]);
1810
+ const resolvedPreferences = useMemo2(() => ({
1811
+ ...currentPreferences,
1812
+ fullWidthContent: config2?.defaults?.fullWidthContent ?? false
1813
+ }), [currentPreferences, config2?.defaults?.fullWidthContent]);
1814
+ return useMemo2(() => ({ preferences: resolvedPreferences, updatePreferences }), [resolvedPreferences, updatePreferences]);
1776
1815
  }
1777
1816
 
1778
1817
  // src/hooks/useShareStatus.ts
@@ -3199,10 +3238,9 @@ var ChatInput = memo3(forwardRef5(function ChatInput2({
3199
3238
  modelName,
3200
3239
  providerName,
3201
3240
  authType,
3241
+ isFreeModel,
3202
3242
  researchContexts = [],
3203
3243
  onResearchContextRemove,
3204
- onRefreshBalance,
3205
- isBalanceLoading = false,
3206
3244
  onModelInfoClick,
3207
3245
  agent,
3208
3246
  agents = [],
@@ -3220,26 +3258,16 @@ var ChatInput = memo3(forwardRef5(function ChatInput2({
3220
3258
  const updateDefaultsMutation = useUpdateDefaults();
3221
3259
  const files = filesData?.files || [];
3222
3260
  const changedFiles = filesData?.changedFiles || [];
3223
- const setuBalance = useSetuStore((s) => s.balance);
3224
3261
  const setuSubscription = useSetuStore((s) => s.subscription);
3225
- const setuPayg = useSetuStore((s) => s.payg);
3226
3262
  const isSetu = providerName === "setu";
3227
- const setuStatusLabel = useMemo4(() => {
3263
+ const setuPlanLabel = useMemo4(() => {
3228
3264
  if (!isSetu)
3229
3265
  return null;
3230
- const effectivePayg = setuPayg?.effectiveSpendableUsd !== undefined ? setuPayg.effectiveSpendableUsd : setuBalance;
3231
3266
  if (setuSubscription?.active) {
3232
- const credits = `${setuSubscription.creditsRemaining?.toFixed(1) ?? ""} credits`;
3233
- if (effectivePayg !== null && effectivePayg !== undefined && effectivePayg > 0) {
3234
- return `GO ${credits} · $${effectivePayg.toFixed(2)}`;
3235
- }
3236
- return `GO ${credits}`;
3237
- }
3238
- if (effectivePayg !== null && effectivePayg !== undefined) {
3239
- return `$${effectivePayg.toFixed(2)}`;
3267
+ return setuSubscription.tierName ?? "GO";
3240
3268
  }
3241
3269
  return null;
3242
- }, [isSetu, setuPayg, setuBalance, setuSubscription]);
3270
+ }, [isSetu, setuSubscription]);
3243
3271
  useEffect7(() => {
3244
3272
  if (!showAgentDropdown)
3245
3273
  return;
@@ -3640,57 +3668,47 @@ var ChatInput = memo3(forwardRef5(function ChatInput2({
3640
3668
  }),
3641
3669
  /* @__PURE__ */ jsx14("div", {
3642
3670
  className: "justify-self-center",
3643
- children: (providerName || modelName || authType) && /* @__PURE__ */ jsxs8("div", {
3671
+ children: (providerName || modelName || authType) && /* @__PURE__ */ jsx14("div", {
3644
3672
  className: "text-[10px] text-muted-foreground flex items-center gap-1 px-2 py-0.5",
3645
- children: [
3646
- /* @__PURE__ */ jsxs8("button", {
3647
- type: "button",
3648
- onClick: onModelInfoClick,
3649
- className: "flex items-center gap-1 transition-colors hover:text-foreground cursor-pointer",
3650
- children: [
3651
- providerName && /* @__PURE__ */ jsxs8(Fragment2, {
3652
- children: [
3653
- /* @__PURE__ */ jsx14(ProviderLogo, {
3654
- provider: providerName,
3655
- size: 12,
3656
- className: "opacity-70"
3657
- }),
3658
- /* @__PURE__ */ jsx14("span", {
3659
- className: "opacity-40",
3660
- children: "/"
3661
- })
3662
- ]
3663
- }),
3664
- modelName && /* @__PURE__ */ jsx14("span", {
3665
- children: modelName
3666
- }),
3667
- authType && authType === "oauth" && /* @__PURE__ */ jsx14("span", {
3668
- className: "opacity-50",
3669
- children: "(pro)"
3670
- })
3671
- ]
3672
- }),
3673
- isSetu && setuStatusLabel && /* @__PURE__ */ jsxs8(Fragment2, {
3674
- children: [
3675
- /* @__PURE__ */ jsx14("span", {
3676
- className: "text-emerald-600 dark:text-emerald-400",
3677
- children: setuStatusLabel
3678
- }),
3679
- onRefreshBalance && /* @__PURE__ */ jsx14("button", {
3680
- type: "button",
3681
- onClick: (e) => {
3682
- e.stopPropagation();
3683
- onRefreshBalance();
3684
- },
3685
- disabled: isBalanceLoading,
3686
- className: "p-0.5 hover:bg-background/50 rounded transition-colors disabled:opacity-50",
3687
- children: /* @__PURE__ */ jsx14(RefreshCw2, {
3688
- className: `h-2.5 w-2.5 text-muted-foreground ${isBalanceLoading ? "animate-spin" : ""}`
3673
+ children: /* @__PURE__ */ jsxs8("button", {
3674
+ type: "button",
3675
+ onClick: onModelInfoClick,
3676
+ className: "flex items-center gap-1 transition-colors hover:text-foreground cursor-pointer",
3677
+ children: [
3678
+ providerName && /* @__PURE__ */ jsxs8(Fragment2, {
3679
+ children: [
3680
+ /* @__PURE__ */ jsx14(ProviderLogo, {
3681
+ provider: providerName,
3682
+ size: 12,
3683
+ className: "opacity-70"
3684
+ }),
3685
+ /* @__PURE__ */ jsx14("span", {
3686
+ className: "opacity-40",
3687
+ children: "/"
3689
3688
  })
3690
- })
3691
- ]
3692
- })
3693
- ]
3689
+ ]
3690
+ }),
3691
+ modelName && /* @__PURE__ */ jsx14("span", {
3692
+ children: modelName
3693
+ }),
3694
+ authType && authType === "oauth" && /* @__PURE__ */ jsx14("span", {
3695
+ className: "opacity-50",
3696
+ children: "(pro)"
3697
+ }),
3698
+ isSetu && setuPlanLabel && /* @__PURE__ */ jsxs8("span", {
3699
+ className: "opacity-50",
3700
+ children: [
3701
+ "(",
3702
+ setuPlanLabel.toLowerCase(),
3703
+ ")"
3704
+ ]
3705
+ }),
3706
+ isFreeModel && /* @__PURE__ */ jsx14("span", {
3707
+ className: "opacity-50",
3708
+ children: "(free)"
3709
+ })
3710
+ ]
3711
+ })
3694
3712
  })
3695
3713
  }),
3696
3714
  /* @__PURE__ */ jsxs8("div", {
@@ -3749,8 +3767,8 @@ var ChatInput = memo3(forwardRef5(function ChatInput2({
3749
3767
  import {
3750
3768
  memo as memo4,
3751
3769
  useState as useState12,
3752
- useCallback as useCallback11,
3753
- useEffect as useEffect13,
3770
+ useCallback as useCallback10,
3771
+ useEffect as useEffect12,
3754
3772
  useRef as useRef7,
3755
3773
  forwardRef as forwardRef8,
3756
3774
  useImperativeHandle as useImperativeHandle4,
@@ -4821,79 +4839,13 @@ function formatResearchContextForMessage(contexts) {
4821
4839
  `);
4822
4840
  }
4823
4841
 
4824
- // src/hooks/useSetuBalance.ts
4825
- import { useEffect as useEffect9, useCallback as useCallback10 } from "react";
4826
- function useSetuBalance(providerName) {
4827
- const setBalance = useSetuStore((s) => s.setBalance);
4828
- const setUsdcBalance = useSetuStore((s) => s.setUsdcBalance);
4829
- const setWalletAddress = useSetuStore((s) => s.setWalletAddress);
4830
- const setLoading = useSetuStore((s) => s.setLoading);
4831
- const setScope = useSetuStore((s) => s.setScope);
4832
- const setPayg = useSetuStore((s) => s.setPayg);
4833
- const setSubscription = useSetuStore((s) => s.setSubscription);
4834
- const setLimits = useSetuStore((s) => s.setLimits);
4835
- const balance = useSetuStore((s) => s.balance);
4836
- const usdcBalance = useSetuStore((s) => s.usdcBalance);
4837
- const network = useSetuStore((s) => s.network);
4838
- const fetchBalance = useCallback10(async () => {
4839
- if (providerName !== "setu") {
4840
- return;
4841
- }
4842
- setLoading(true);
4843
- try {
4844
- const [setuData, usdcData, walletData] = await Promise.all([
4845
- apiClient.getSetuBalance(),
4846
- apiClient.getSetuUsdcBalance(network),
4847
- apiClient.getSetuWallet()
4848
- ]);
4849
- if (setuData) {
4850
- setBalance(setuData.balance);
4851
- setWalletAddress(setuData.walletAddress);
4852
- setScope(setuData.scope ?? null);
4853
- setPayg(setuData.payg ?? null);
4854
- setSubscription(setuData.subscription ?? null);
4855
- setLimits(setuData.limits ?? null);
4856
- } else if (walletData?.configured && walletData.publicKey) {
4857
- setWalletAddress(walletData.publicKey);
4858
- }
4859
- if (usdcData) {
4860
- setUsdcBalance(usdcData.usdcBalance);
4861
- if (!setuData && usdcData.walletAddress) {
4862
- setWalletAddress(usdcData.walletAddress);
4863
- }
4864
- }
4865
- } catch {} finally {
4866
- setLoading(false);
4867
- }
4868
- }, [
4869
- providerName,
4870
- network,
4871
- setBalance,
4872
- setUsdcBalance,
4873
- setWalletAddress,
4874
- setLoading,
4875
- setScope,
4876
- setPayg,
4877
- setSubscription,
4878
- setLimits
4879
- ]);
4880
- useEffect9(() => {
4881
- if (providerName === "setu" && (balance === null || usdcBalance === null)) {
4882
- fetchBalance();
4883
- }
4884
- }, [providerName, balance, usdcBalance, fetchBalance]);
4885
- return {
4886
- fetchBalance
4887
- };
4888
- }
4889
-
4890
4842
  // src/components/chat/ConfigModal.tsx
4891
- import { useEffect as useEffect12, useRef as useRef6, useState as useState11, useLayoutEffect } from "react";
4843
+ import { useEffect as useEffect11, useRef as useRef6, useState as useState11, useLayoutEffect } from "react";
4892
4844
 
4893
4845
  // src/components/chat/UnifiedModelSelector.tsx
4894
4846
  import {
4895
4847
  useState as useState9,
4896
- useEffect as useEffect10,
4848
+ useEffect as useEffect9,
4897
4849
  useRef as useRef4,
4898
4850
  useMemo as useMemo6,
4899
4851
  useImperativeHandle as useImperativeHandle2,
@@ -5014,12 +4966,12 @@ var UnifiedModelSelector = forwardRef6(function UnifiedModelSelector2({ provider
5014
4966
  }
5015
4967
  return list;
5016
4968
  }, [filteredModels]);
5017
- useEffect10(() => {
4969
+ useEffect9(() => {
5018
4970
  if (isOpen) {
5019
4971
  setHighlightedIndex(0);
5020
4972
  }
5021
4973
  }, [isOpen]);
5022
- useEffect10(() => {
4974
+ useEffect9(() => {
5023
4975
  if (isOpen && highlightedIndex >= 0 && highlightedIndex < itemRefs.current.length) {
5024
4976
  itemRefs.current[highlightedIndex]?.scrollIntoView({
5025
4977
  block: "nearest",
@@ -5027,7 +4979,7 @@ var UnifiedModelSelector = forwardRef6(function UnifiedModelSelector2({ provider
5027
4979
  });
5028
4980
  }
5029
4981
  }, [highlightedIndex, isOpen]);
5030
- useEffect10(() => {
4982
+ useEffect9(() => {
5031
4983
  const handleClickOutside = (event) => {
5032
4984
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
5033
4985
  setIsOpen(false);
@@ -5199,7 +5151,7 @@ var UnifiedModelSelector = forwardRef6(function UnifiedModelSelector2({ provider
5199
5151
  // src/components/chat/UnifiedAgentSelector.tsx
5200
5152
  import {
5201
5153
  useState as useState10,
5202
- useEffect as useEffect11,
5154
+ useEffect as useEffect10,
5203
5155
  useRef as useRef5,
5204
5156
  useMemo as useMemo7,
5205
5157
  useImperativeHandle as useImperativeHandle3,
@@ -5232,12 +5184,12 @@ var UnifiedAgentSelector = forwardRef7(function UnifiedAgentSelector2({ agent, a
5232
5184
  const results = fuse.search(searchQuery);
5233
5185
  return results.map((result) => result.item);
5234
5186
  }, [agents, searchQuery, fuse]);
5235
- useEffect11(() => {
5187
+ useEffect10(() => {
5236
5188
  if (isOpen) {
5237
5189
  setHighlightedIndex(0);
5238
5190
  }
5239
5191
  }, [isOpen]);
5240
- useEffect11(() => {
5192
+ useEffect10(() => {
5241
5193
  if (isOpen && highlightedIndex >= 0 && highlightedIndex < itemRefs.current.length) {
5242
5194
  itemRefs.current[highlightedIndex]?.scrollIntoView({
5243
5195
  block: "nearest",
@@ -5245,7 +5197,7 @@ var UnifiedAgentSelector = forwardRef7(function UnifiedAgentSelector2({ agent, a
5245
5197
  });
5246
5198
  }
5247
5199
  }, [highlightedIndex, isOpen]);
5248
- useEffect11(() => {
5200
+ useEffect10(() => {
5249
5201
  const handleClickOutside = (event) => {
5250
5202
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
5251
5203
  setIsOpen(false);
@@ -5434,7 +5386,7 @@ function ConfigModal({
5434
5386
  const reasoningLevel = config2?.defaults?.reasoningLevel ?? "high";
5435
5387
  const agentSelectorRef = useRef6(null);
5436
5388
  const modelSelectorRef = useRef6(null);
5437
- useEffect12(() => {
5389
+ useEffect11(() => {
5438
5390
  if (isOpen && initialFocus) {
5439
5391
  setTimeout(() => {
5440
5392
  if (initialFocus === "agent") {
@@ -5564,6 +5516,7 @@ var ChatInputContainer = memo4(forwardRef8(function ChatInputContainer2({ sessio
5564
5516
  const modelSupportsReasoning = allModels?.[provider]?.models?.find((m) => m.id === model)?.reasoningText;
5565
5517
  const modelSupportsVision = allModels?.[provider]?.models?.find((m) => m.id === model)?.vision;
5566
5518
  const modelSupportsAttachment = allModels?.[provider]?.models?.find((m) => m.id === model)?.attachment;
5519
+ const modelIsFree = allModels?.[provider]?.models?.find((m) => m.id === model)?.free;
5567
5520
  const {
5568
5521
  images,
5569
5522
  documents,
@@ -5584,29 +5537,27 @@ var ChatInputContainer = memo4(forwardRef8(function ChatInputContainer2({ sessio
5584
5537
  id: ctx.id,
5585
5538
  label: ctx.label
5586
5539
  })), [pendingResearchContexts]);
5587
- const handleResearchContextRemove = useCallback11((contextId) => {
5540
+ const handleResearchContextRemove = useCallback10((contextId) => {
5588
5541
  removeResearchContext(sessionId, contextId);
5589
5542
  }, [sessionId, removeResearchContext]);
5590
5543
  const providerAuthType = allModels?.[provider]?.authType;
5591
- const { fetchBalance } = useSetuBalance(provider);
5592
- const isBalanceLoading = useSetuStore((s) => s.isLoading);
5593
- useEffect13(() => {
5544
+ useEffect12(() => {
5594
5545
  if (session) {
5595
5546
  setAgent(session.agent);
5596
5547
  setProvider(session.provider);
5597
5548
  setModel(session.model);
5598
5549
  }
5599
5550
  }, [session]);
5600
- useEffect13(() => {
5551
+ useEffect12(() => {
5601
5552
  setActiveSessionId(sessionId);
5602
5553
  return () => setActiveSessionId(null);
5603
5554
  }, [sessionId, setActiveSessionId]);
5604
- useEffect13(() => {
5555
+ useEffect12(() => {
5605
5556
  setInputKey((prev) => prev + 1);
5606
5557
  }, []);
5607
5558
  const pendingRestoreText = useQueueStore((state) => state.pendingRestoreText);
5608
5559
  const consumeRestoreText = useQueueStore((state) => state.consumeRestoreText);
5609
- useEffect13(() => {
5560
+ useEffect12(() => {
5610
5561
  if (pendingRestoreText) {
5611
5562
  const text = consumeRestoreText();
5612
5563
  if (text) {
@@ -5619,7 +5570,7 @@ var ChatInputContainer = memo4(forwardRef8(function ChatInputContainer2({ sessio
5619
5570
  chatInputRef.current?.focus();
5620
5571
  }
5621
5572
  }));
5622
- const handleSendMessage = useCallback11(async (content) => {
5573
+ const handleSendMessage = useCallback10(async (content) => {
5623
5574
  try {
5624
5575
  const researchCtxs = consumeResearchContexts(sessionId);
5625
5576
  const researchPrefix = formatResearchContextForMessage(researchCtxs);
@@ -5667,14 +5618,14 @@ ${content}` : content;
5667
5618
  config2?.defaults?.reasoningText,
5668
5619
  modelSupportsReasoning
5669
5620
  ]);
5670
- const handleToggleConfig = useCallback11(() => {
5621
+ const handleToggleConfig = useCallback10(() => {
5671
5622
  setIsConfigOpen((prev) => !prev);
5672
5623
  }, []);
5673
- const handleCloseConfig = useCallback11(() => {
5624
+ const handleCloseConfig = useCallback10(() => {
5674
5625
  setIsConfigOpen(false);
5675
5626
  setConfigFocusTarget(null);
5676
5627
  }, []);
5677
- const handleCommand = useCallback11(async (commandId) => {
5628
+ const handleCommand = useCallback10(async (commandId) => {
5678
5629
  if (commandId === "models") {
5679
5630
  setConfigFocusTarget("model");
5680
5631
  setIsConfigOpen(true);
@@ -5746,7 +5697,7 @@ ${content}` : content;
5746
5697
  onDeleteSession,
5747
5698
  queryClient
5748
5699
  ]);
5749
- const handleAgentChange = useCallback11(async (value) => {
5700
+ const handleAgentChange = useCallback10(async (value) => {
5750
5701
  setAgent(value);
5751
5702
  try {
5752
5703
  await updateSession.mutateAsync({ agent: value });
@@ -5754,7 +5705,7 @@ ${content}` : content;
5754
5705
  console.error("Failed to update agent:", error);
5755
5706
  }
5756
5707
  }, [updateSession]);
5757
- const handleModelSelectorChange = useCallback11(async (newProvider, newModel) => {
5708
+ const handleModelSelectorChange = useCallback10(async (newProvider, newModel) => {
5758
5709
  setProvider(newProvider);
5759
5710
  setModel(newModel);
5760
5711
  try {
@@ -5766,7 +5717,7 @@ ${content}` : content;
5766
5717
  console.error("Failed to update model:", error);
5767
5718
  }
5768
5719
  }, [updateSession]);
5769
- const handleProviderChange = useCallback11(async (newProvider) => {
5720
+ const handleProviderChange = useCallback10(async (newProvider) => {
5770
5721
  setProvider(newProvider);
5771
5722
  if (model) {
5772
5723
  try {
@@ -5779,7 +5730,7 @@ ${content}` : content;
5779
5730
  }
5780
5731
  }
5781
5732
  }, [model, updateSession]);
5782
- const handleModelChange = useCallback11(async (newModel) => {
5733
+ const handleModelChange = useCallback10(async (newModel) => {
5783
5734
  setModel(newModel);
5784
5735
  try {
5785
5736
  await updateSession.mutateAsync({ provider, model: newModel });
@@ -5787,7 +5738,7 @@ ${content}` : content;
5787
5738
  console.error("Failed to update model:", error);
5788
5739
  }
5789
5740
  }, [provider, updateSession]);
5790
- const handlePlanModeToggle = useCallback11(async (isPlanMode) => {
5741
+ const handlePlanModeToggle = useCallback10(async (isPlanMode) => {
5791
5742
  const newAgent = isPlanMode ? "plan" : "build";
5792
5743
  setAgent(newAgent);
5793
5744
  try {
@@ -5832,10 +5783,9 @@ ${content}` : content;
5832
5783
  modelName: model,
5833
5784
  providerName: provider,
5834
5785
  authType: providerAuthType,
5786
+ isFreeModel: modelIsFree,
5835
5787
  researchContexts,
5836
5788
  onResearchContextRemove: handleResearchContextRemove,
5837
- onRefreshBalance: provider === "setu" ? fetchBalance : undefined,
5838
- isBalanceLoading,
5839
5789
  onModelInfoClick: () => {
5840
5790
  setConfigFocusTarget("model");
5841
5791
  setIsConfigOpen(true);
@@ -5848,7 +5798,7 @@ ${content}` : content;
5848
5798
  });
5849
5799
  }));
5850
5800
  // src/components/chat/ConfigSelector.tsx
5851
- import { useEffect as useEffect14 } from "react";
5801
+ import { useEffect as useEffect13 } from "react";
5852
5802
  import { Settings } from "lucide-react";
5853
5803
  import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
5854
5804
  function ConfigSelector({
@@ -5869,7 +5819,7 @@ function ConfigSelector({
5869
5819
  provider,
5870
5820
  model
5871
5821
  });
5872
- useEffect14(() => {
5822
+ useEffect13(() => {
5873
5823
  if (config2 && !agent && !provider && !model) {
5874
5824
  onAgentChange(config2.defaults.agent);
5875
5825
  onProviderChange(config2.defaults.provider);
@@ -5884,7 +5834,7 @@ function ConfigSelector({
5884
5834
  onProviderChange,
5885
5835
  onModelChange
5886
5836
  ]);
5887
- useEffect14(() => {
5837
+ useEffect13(() => {
5888
5838
  if (modelsData && modelsData.models.length > 0) {
5889
5839
  const currentModelExists = modelsData.models.some((m) => m.id === model);
5890
5840
  if (!currentModelExists) {
@@ -5989,12 +5939,12 @@ function StopButton({ sessionId, onStop, disabled }) {
5989
5939
  });
5990
5940
  }
5991
5941
  // src/components/messages/MessageThread.tsx
5992
- import { useEffect as useEffect21, useRef as useRef13, useState as useState28, useMemo as useMemo14, memo as memo12, useCallback as useCallback15 } from "react";
5942
+ import { useEffect as useEffect20, useRef as useRef13, useState as useState28, useMemo as useMemo14, memo as memo12, useCallback as useCallback14 } from "react";
5993
5943
  import { ArrowDown } from "lucide-react";
5994
5944
  import { useQueryClient as useQueryClient8 } from "@tanstack/react-query";
5995
5945
 
5996
5946
  // src/components/messages/AssistantMessageGroup.tsx
5997
- import { memo as memo7, useState as useState24, useCallback as useCallback12, useMemo as useMemo10 } from "react";
5947
+ import { memo as memo7, useState as useState24, useCallback as useCallback11, useMemo as useMemo10 } from "react";
5998
5948
  import {
5999
5949
  Sparkles as Sparkles3,
6000
5950
  GitBranch as GitBranch5,
@@ -8697,7 +8647,7 @@ import { useState as useState17 } from "react";
8697
8647
  import {
8698
8648
  ChevronDown as ChevronDown4,
8699
8649
  ChevronRight as ChevronRight7,
8700
- RefreshCw as RefreshCw3,
8650
+ RefreshCw as RefreshCw2,
8701
8651
  CreditCard as CreditCard2,
8702
8652
  Scissors
8703
8653
  } from "lucide-react";
@@ -8803,7 +8753,7 @@ function ErrorRenderer({
8803
8753
  onClick: onRetry,
8804
8754
  className: "flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
8805
8755
  children: [
8806
- /* @__PURE__ */ jsx45(RefreshCw3, {
8756
+ /* @__PURE__ */ jsx45(RefreshCw2, {
8807
8757
  className: "w-3 h-3"
8808
8758
  }),
8809
8759
  "Retry"
@@ -8870,7 +8820,7 @@ function ErrorRenderer({
8870
8820
  onClick: onRetry,
8871
8821
  className: "flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
8872
8822
  children: [
8873
- /* @__PURE__ */ jsx45(RefreshCw3, {
8823
+ /* @__PURE__ */ jsx45(RefreshCw2, {
8874
8824
  className: "w-3 h-3"
8875
8825
  }),
8876
8826
  "Retry"
@@ -8907,7 +8857,7 @@ function ErrorRenderer({
8907
8857
  onClick: onRetry,
8908
8858
  className: "flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
8909
8859
  children: [
8910
- /* @__PURE__ */ jsx45(RefreshCw3, {
8860
+ /* @__PURE__ */ jsx45(RefreshCw2, {
8911
8861
  className: "w-3 h-3"
8912
8862
  }),
8913
8863
  "Retry"
@@ -8956,7 +8906,7 @@ function ErrorRenderer({
8956
8906
  onClick: onRetry,
8957
8907
  className: "flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded border border-border text-foreground hover:bg-muted transition-colors",
8958
8908
  children: [
8959
- /* @__PURE__ */ jsx45(RefreshCw3, {
8909
+ /* @__PURE__ */ jsx45(RefreshCw2, {
8960
8910
  className: "w-3 h-3"
8961
8911
  }),
8962
8912
  "Retry"
@@ -9079,7 +9029,7 @@ function ErrorRenderer({
9079
9029
  onClick: onRetry,
9080
9030
  className: "flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
9081
9031
  children: [
9082
- /* @__PURE__ */ jsx45(RefreshCw3, {
9032
+ /* @__PURE__ */ jsx45(RefreshCw2, {
9083
9033
  className: "w-3 h-3"
9084
9034
  }),
9085
9035
  "Retry"
@@ -9734,7 +9684,7 @@ function DatabaseToolRenderer({
9734
9684
  }
9735
9685
 
9736
9686
  // src/components/messages/renderers/TerminalRenderer.tsx
9737
- import { useEffect as useEffect15, useState as useState18 } from "react";
9687
+ import { useEffect as useEffect14, useState as useState18 } from "react";
9738
9688
  import { Terminal as Terminal4 } from "lucide-react";
9739
9689
 
9740
9690
  // src/lib/nerd-font.ts
@@ -9805,7 +9755,7 @@ function TerminalRenderer({
9805
9755
  compact
9806
9756
  }) {
9807
9757
  const [, setFontReady] = useState18(false);
9808
- useEffect15(() => {
9758
+ useEffect14(() => {
9809
9759
  loadNerdFont().then(() => setFontReady(true));
9810
9760
  }, []);
9811
9761
  const result = contentJson.result || {};
@@ -10449,7 +10399,7 @@ function formatFileSize(bytes) {
10449
10399
  return `${(kb / 1024).toFixed(1)}MB`;
10450
10400
  }
10451
10401
  // src/components/messages/renderers/ReasoningRenderer.tsx
10452
- import { useState as useState19, useRef as useRef8, useEffect as useEffect16 } from "react";
10402
+ import { useState as useState19, useRef as useRef8, useEffect as useEffect15 } from "react";
10453
10403
  import { ChevronDown as ChevronDown5, ChevronRight as ChevronRight9 } from "lucide-react";
10454
10404
  import { jsx as jsx51, jsxs as jsxs44 } from "react/jsx-runtime";
10455
10405
  function ReasoningRenderer({ part }) {
@@ -10463,7 +10413,7 @@ function ReasoningRenderer({ part }) {
10463
10413
  } else if (typeof data === "string") {
10464
10414
  content = data;
10465
10415
  }
10466
- useEffect16(() => {
10416
+ useEffect15(() => {
10467
10417
  if (scrollRef.current && isExpanded && !part.completedAt && !isHoveredRef.current) {
10468
10418
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
10469
10419
  }
@@ -11211,7 +11161,7 @@ var MessagePartItem = memo6(function MessagePartItem2({
11211
11161
  });
11212
11162
 
11213
11163
  // src/components/messages/CompactActivityGroup.tsx
11214
- import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect2, useMemo as useMemo9, useRef as useRef9, useState as useState21 } from "react";
11164
+ import { useEffect as useEffect16, useLayoutEffect as useLayoutEffect2, useMemo as useMemo9, useRef as useRef9, useState as useState21 } from "react";
11215
11165
  import { Brain as Brain4, Search as Search6 } from "lucide-react";
11216
11166
 
11217
11167
  // src/components/messages/compactActivity.ts
@@ -11530,7 +11480,7 @@ function CompactActivityGroup({
11530
11480
  const summaryText = [summaryTitle, ...summary.details].join(" · ");
11531
11481
  const hasReasoning = entries.some((e) => e.toolName === "reasoning");
11532
11482
  const lastEntry = entries.length > 0 ? entries[entries.length - 1] : null;
11533
- useEffect17(() => {
11483
+ useEffect16(() => {
11534
11484
  if (!collapsed && !latched) {
11535
11485
  setShowSummary(false);
11536
11486
  return;
@@ -11560,14 +11510,14 @@ function CompactActivityGroup({
11560
11510
  observer.observe(el);
11561
11511
  return () => observer.disconnect();
11562
11512
  }, [showSummary]);
11563
- useEffect17(() => {
11513
+ useEffect16(() => {
11564
11514
  return () => {
11565
11515
  if (scrollAnimationRef.current !== null) {
11566
11516
  window.cancelAnimationFrame(scrollAnimationRef.current);
11567
11517
  }
11568
11518
  };
11569
11519
  }, []);
11570
- useEffect17(() => {
11520
+ useEffect16(() => {
11571
11521
  if (showSummary || hoveredRef.current)
11572
11522
  return;
11573
11523
  const el = scrollRef.current;
@@ -11604,7 +11554,7 @@ function CompactActivityGroup({
11604
11554
  };
11605
11555
  scrollAnimationRef.current = window.requestAnimationFrame(tick);
11606
11556
  }, [entries.length, lastEntry?.fullText, showSummary, contentHeight]);
11607
- useEffect17(() => {
11557
+ useEffect16(() => {
11608
11558
  prevCountRef.current = entries.length;
11609
11559
  }, [entries.length]);
11610
11560
  const isLive = !showSummary;
@@ -11727,7 +11677,7 @@ function CompactActivityGroup({
11727
11677
  }
11728
11678
 
11729
11679
  // src/components/messages/ActionToolBox.tsx
11730
- import { useEffect as useEffect18, useLayoutEffect as useLayoutEffect3, useRef as useRef10, useState as useState22 } from "react";
11680
+ import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect3, useRef as useRef10, useState as useState22 } from "react";
11731
11681
  import {
11732
11682
  Terminal as Terminal6,
11733
11683
  FileEdit as FileEdit3,
@@ -11862,7 +11812,7 @@ function ActionToolBox({ part, showLine }) {
11862
11812
  const streamedContent = getContentFromStream(toolName, streamedInput);
11863
11813
  const displayContent = toolName === "bash" ? streamedOutput || streamedContent || (args ? getContentFromArgs(toolName, args) : "") : args ? getContentFromArgs(toolName, args) : streamedContent;
11864
11814
  const hasDisplayContent = displayContent.trim().length > 0;
11865
- useEffect18(() => {
11815
+ useEffect17(() => {
11866
11816
  if (!isComplete && !latched) {
11867
11817
  setShowSummary(false);
11868
11818
  return;
@@ -11888,14 +11838,14 @@ function ActionToolBox({ part, showLine }) {
11888
11838
  const nextHeight = Math.min(el.scrollHeight, MAX_SCROLL_H2 - 12);
11889
11839
  setContentHeight((prev) => prev === nextHeight ? prev : nextHeight);
11890
11840
  }, [displayContent, hasDisplayContent]);
11891
- useEffect18(() => {
11841
+ useEffect17(() => {
11892
11842
  return () => {
11893
11843
  if (scrollAnimationRef.current !== null) {
11894
11844
  window.cancelAnimationFrame(scrollAnimationRef.current);
11895
11845
  }
11896
11846
  };
11897
11847
  }, []);
11898
- useEffect18(() => {
11848
+ useEffect17(() => {
11899
11849
  const el = scrollRef.current;
11900
11850
  if (!el || hoveredRef.current)
11901
11851
  return;
@@ -12433,7 +12383,7 @@ var AssistantMessageGroup = memo7(function AssistantMessageGroup2({
12433
12383
  const [showBranchModal, setShowBranchModal] = useState24(false);
12434
12384
  const [copied, setCopied] = useState24(false);
12435
12385
  const { pendingApprovals, removePendingApproval } = useToolApprovalStore();
12436
- const handleApprove = useCallback12(async (callId) => {
12386
+ const handleApprove = useCallback11(async (callId) => {
12437
12387
  if (!sessionId)
12438
12388
  return;
12439
12389
  try {
@@ -12443,7 +12393,7 @@ var AssistantMessageGroup = memo7(function AssistantMessageGroup2({
12443
12393
  console.error("Failed to approve tool call:", error);
12444
12394
  }
12445
12395
  }, [sessionId, removePendingApproval]);
12446
- const handleReject = useCallback12(async (callId) => {
12396
+ const handleReject = useCallback11(async (callId) => {
12447
12397
  if (!sessionId)
12448
12398
  return;
12449
12399
  try {
@@ -12456,7 +12406,7 @@ var AssistantMessageGroup = memo7(function AssistantMessageGroup2({
12456
12406
  const messagePendingApprovals = useMemo10(() => {
12457
12407
  return pendingApprovals.filter((a) => a.messageId === message.id);
12458
12408
  }, [pendingApprovals, message.id]);
12459
- const handleApproveAll = useCallback12(async () => {
12409
+ const handleApproveAll = useCallback11(async () => {
12460
12410
  if (!sessionId)
12461
12411
  return;
12462
12412
  try {
@@ -12563,7 +12513,7 @@ var AssistantMessageGroup = memo7(function AssistantMessageGroup2({
12563
12513
  });
12564
12514
  };
12565
12515
  const isComplete = message.status === "complete";
12566
- const handleCopy = useCallback12(() => {
12516
+ const handleCopy = useCallback11(() => {
12567
12517
  const textParts = parts.filter((p) => p.type === "text").map((p) => {
12568
12518
  try {
12569
12519
  const parsed = JSON.parse(p.content || "{}");
@@ -12577,7 +12527,7 @@ var AssistantMessageGroup = memo7(function AssistantMessageGroup2({
12577
12527
  setCopied(true);
12578
12528
  setTimeout(() => setCopied(false), 2000);
12579
12529
  }, [parts]);
12580
- const handleBranchClick = useCallback12(() => {
12530
+ const handleBranchClick = useCallback11(() => {
12581
12531
  setShowBranchModal(true);
12582
12532
  }, []);
12583
12533
  if (isQueued) {
@@ -13153,11 +13103,11 @@ import {
13153
13103
  ArrowUpRight,
13154
13104
  Share2 as Share22,
13155
13105
  ExternalLink as ExternalLink4,
13156
- RefreshCw as RefreshCw4
13106
+ RefreshCw as RefreshCw3
13157
13107
  } from "lucide-react";
13158
13108
 
13159
13109
  // src/components/sessions/EditableTitle.tsx
13160
- import { useState as useState26, useRef as useRef11, useEffect as useEffect19, useCallback as useCallback13 } from "react";
13110
+ import { useState as useState26, useRef as useRef11, useEffect as useEffect18, useCallback as useCallback12 } from "react";
13161
13111
  import { Pencil as Pencil2 } from "lucide-react";
13162
13112
  import { jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
13163
13113
  function EditableTitle({
@@ -13169,23 +13119,23 @@ function EditableTitle({
13169
13119
  const [draft, setDraft] = useState26(title || "");
13170
13120
  const inputRef = useRef11(null);
13171
13121
  const { mutate: updateSession } = useUpdateSession(sessionId);
13172
- useEffect19(() => {
13122
+ useEffect18(() => {
13173
13123
  if (isEditing && inputRef.current) {
13174
13124
  inputRef.current.focus();
13175
13125
  inputRef.current.select();
13176
13126
  }
13177
13127
  }, [isEditing]);
13178
- useEffect19(() => {
13128
+ useEffect18(() => {
13179
13129
  setDraft(title || "");
13180
13130
  }, [title]);
13181
- const save = useCallback13(() => {
13131
+ const save = useCallback12(() => {
13182
13132
  const trimmed = draft.trim();
13183
13133
  if (trimmed && trimmed !== (title || "")) {
13184
13134
  updateSession({ title: trimmed });
13185
13135
  }
13186
13136
  setIsEditing(false);
13187
13137
  }, [draft, title, updateSession]);
13188
- const cancel = useCallback13(() => {
13138
+ const cancel = useCallback12(() => {
13189
13139
  setDraft(title || "");
13190
13140
  setIsEditing(false);
13191
13141
  }, [title]);
@@ -13349,7 +13299,7 @@ function SessionHeader({
13349
13299
  shareStatus.pendingMessages && shareStatus.pendingMessages > 0 ? /* @__PURE__ */ jsxs52("span", {
13350
13300
  className: "flex items-center gap-0.5 text-amber-600 dark:text-amber-400",
13351
13301
  children: [
13352
- /* @__PURE__ */ jsx60(RefreshCw4, {
13302
+ /* @__PURE__ */ jsx60(RefreshCw3, {
13353
13303
  className: "h-2.5 w-2.5"
13354
13304
  }),
13355
13305
  shareStatus.pendingMessages
@@ -13454,7 +13404,7 @@ import {
13454
13404
  ArrowUpRight as ArrowUpRight2,
13455
13405
  Share2 as Share23,
13456
13406
  ExternalLink as ExternalLink5,
13457
- RefreshCw as RefreshCw5
13407
+ RefreshCw as RefreshCw4
13458
13408
  } from "lucide-react";
13459
13409
 
13460
13410
  // src/components/common/UsageRing.tsx
@@ -13728,7 +13678,7 @@ var UsageModal = memo10(function UsageModal2() {
13728
13678
  });
13729
13679
 
13730
13680
  // src/hooks/useProviderUsage.ts
13731
- import { useEffect as useEffect20, useCallback as useCallback14, useRef as useRef12 } from "react";
13681
+ import { useEffect as useEffect19, useCallback as useCallback13, useRef as useRef12 } from "react";
13732
13682
  var POLL_INTERVAL = 60000;
13733
13683
  var STALE_THRESHOLD = 30000;
13734
13684
  var inflight = new Set;
@@ -13738,7 +13688,7 @@ function useProviderUsage(provider, authType) {
13738
13688
  const setLastFetched = useUsageStore((s) => s.setLastFetched);
13739
13689
  const usage = useUsageStore((s) => provider ? s.usage[provider] : undefined);
13740
13690
  const isOAuthProvider = authType === "oauth" && (provider === "anthropic" || provider === "openai");
13741
- const fetchUsage = useCallback14(async () => {
13691
+ const fetchUsage = useCallback13(async () => {
13742
13692
  if (!provider || !isOAuthProvider)
13743
13693
  return;
13744
13694
  if (inflight.has(provider))
@@ -13759,7 +13709,7 @@ function useProviderUsage(provider, authType) {
13759
13709
  }, [provider, isOAuthProvider, setUsage, setLoading, setLastFetched]);
13760
13710
  const fetchRef = useRef12(fetchUsage);
13761
13711
  fetchRef.current = fetchUsage;
13762
- useEffect20(() => {
13712
+ useEffect19(() => {
13763
13713
  if (!isOAuthProvider)
13764
13714
  return;
13765
13715
  fetchRef.current();
@@ -13858,7 +13808,7 @@ function LeanHeader({
13858
13808
  shareStatus.pendingMessages && shareStatus.pendingMessages > 0 ? /* @__PURE__ */ jsxs55("span", {
13859
13809
  className: "flex items-center gap-0.5 text-amber-600 dark:text-amber-400",
13860
13810
  children: [
13861
- /* @__PURE__ */ jsx63(RefreshCw5, {
13811
+ /* @__PURE__ */ jsx63(RefreshCw4, {
13862
13812
  className: "h-2.5 w-2.5"
13863
13813
  }),
13864
13814
  shareStatus.pendingMessages
@@ -14160,7 +14110,7 @@ var MessageThread = memo12(function MessageThread2({
14160
14110
  const pendingTopup = useTopupApprovalStore((s) => s.pendingTopup);
14161
14111
  const clearPendingTopup = useTopupApprovalStore((s) => s.clearPendingTopup);
14162
14112
  const showTopupApproval = pendingTopup && pendingTopup.sessionId === sessionId;
14163
- const handleScroll = useCallback15(() => {
14113
+ const handleScroll = useCallback14(() => {
14164
14114
  const container = scrollContainerRef.current;
14165
14115
  if (!container)
14166
14116
  return;
@@ -14196,7 +14146,7 @@ var MessageThread = memo12(function MessageThread2({
14196
14146
  setShowLeanHeader(headerRect.bottom < containerRect.top);
14197
14147
  }
14198
14148
  }, []);
14199
- useEffect21(() => {
14149
+ useEffect20(() => {
14200
14150
  if (disableAutoScroll)
14201
14151
  return;
14202
14152
  const sessionChanged = session?.id !== lastSessionIdRef.current;
@@ -14212,7 +14162,7 @@ var MessageThread = memo12(function MessageThread2({
14212
14162
  }
14213
14163
  }
14214
14164
  }, [messages.length, session?.id, disableAutoScroll]);
14215
- useEffect21(() => {
14165
+ useEffect20(() => {
14216
14166
  if (disableAutoScroll)
14217
14167
  return;
14218
14168
  const justStartedGenerating = isGenerating && !prevIsGeneratingRef.current;
@@ -14236,7 +14186,7 @@ var MessageThread = memo12(function MessageThread2({
14236
14186
  setAutoScroll(true);
14237
14187
  }
14238
14188
  }, [messages.length, isGenerating, disableAutoScroll]);
14239
- useEffect21(() => {
14189
+ useEffect20(() => {
14240
14190
  if (disableAutoScroll)
14241
14191
  return;
14242
14192
  const container = scrollContainerRef.current;
@@ -14266,7 +14216,7 @@ var MessageThread = memo12(function MessageThread2({
14266
14216
  }
14267
14217
  animationFrameRef.current = requestAnimationFrame(animate);
14268
14218
  }, [messages, autoScroll]);
14269
- useEffect21(() => {
14219
+ useEffect20(() => {
14270
14220
  return () => {
14271
14221
  if (userScrollTimeoutRef.current) {
14272
14222
  clearTimeout(userScrollTimeoutRef.current);
@@ -14289,7 +14239,7 @@ var MessageThread = memo12(function MessageThread2({
14289
14239
  return messages.filter((message) => message.role !== "system");
14290
14240
  }, [messages]);
14291
14241
  const contentWidthClass = preferences2.fullWidthContent ? compact ? "w-full space-y-4" : "w-full space-y-6" : compact ? "max-w-3xl mx-auto space-y-4" : "max-w-3xl mx-auto space-y-6";
14292
- const createRetryHandler = useCallback15((messageId) => {
14242
+ const createRetryHandler = useCallback14((messageId) => {
14293
14243
  return async () => {
14294
14244
  if (!sessionId)
14295
14245
  return;
@@ -14323,7 +14273,7 @@ var MessageThread = memo12(function MessageThread2({
14323
14273
  }
14324
14274
  };
14325
14275
  }, [sessionId, queryClient]);
14326
- const handleCompact = useCallback15(async () => {
14276
+ const handleCompact = useCallback14(async () => {
14327
14277
  if (!sessionId)
14328
14278
  return;
14329
14279
  try {
@@ -14430,7 +14380,7 @@ var MessageThread = memo12(function MessageThread2({
14430
14380
  import { memo as memo15, useMemo as useMemo15 } from "react";
14431
14381
 
14432
14382
  // src/hooks/useSessionStream.ts
14433
- import { useEffect as useEffect22, useRef as useRef14 } from "react";
14383
+ import { useEffect as useEffect21, useRef as useRef14 } from "react";
14434
14384
  import { useQueryClient as useQueryClient9 } from "@tanstack/react-query";
14435
14385
 
14436
14386
  // src/lib/sse-client.ts
@@ -14444,8 +14394,10 @@ class SSEClient {
14444
14394
  }
14445
14395
  this.abortController = new AbortController;
14446
14396
  this.running = true;
14397
+ const isTunnel = !url.includes("localhost") && !url.includes("127.0.0.1");
14447
14398
  try {
14448
14399
  const response = await fetch(url, {
14400
+ method: isTunnel ? "POST" : "GET",
14449
14401
  headers: { Accept: "text/event-stream" },
14450
14402
  signal: this.abortController.signal
14451
14403
  });
@@ -14554,7 +14506,7 @@ function useSessionStream(sessionId, enabled = true) {
14554
14506
  updatePendingApproval,
14555
14507
  setPendingApprovals
14556
14508
  } = useToolApprovalStore();
14557
- useEffect22(() => {
14509
+ useEffect21(() => {
14558
14510
  if (!sessionId || !enabled) {
14559
14511
  return;
14560
14512
  }
@@ -15104,6 +15056,26 @@ function useSessionStream(sessionId, enabled = true) {
15104
15056
  const agent = typeof payload?.agent === "string" ? payload.agent : "";
15105
15057
  const provider = typeof payload?.provider === "string" ? payload.provider : "";
15106
15058
  const model = typeof payload?.model === "string" ? payload.model : "";
15059
+ const content = typeof payload?.content === "string" ? payload.content : null;
15060
+ const userParts = role === "user" && content ? [
15061
+ {
15062
+ id: `${id}-text`,
15063
+ messageId: id,
15064
+ index: 0,
15065
+ stepIndex: null,
15066
+ type: "text",
15067
+ content: JSON.stringify({ text: content }),
15068
+ contentJson: { text: content },
15069
+ agent,
15070
+ provider,
15071
+ model,
15072
+ startedAt: Date.now(),
15073
+ completedAt: Date.now(),
15074
+ toolName: null,
15075
+ toolCallId: null,
15076
+ toolDurationMs: null
15077
+ }
15078
+ ] : [];
15107
15079
  queryClient.setQueryData(["messages", sessionId], (oldMessages) => {
15108
15080
  if (!oldMessages)
15109
15081
  return oldMessages;
@@ -15113,7 +15085,7 @@ function useSessionStream(sessionId, enabled = true) {
15113
15085
  id,
15114
15086
  sessionId,
15115
15087
  role,
15116
- status: "pending",
15088
+ status: role === "user" ? "complete" : "pending",
15117
15089
  agent,
15118
15090
  provider,
15119
15091
  model,
@@ -15124,7 +15096,7 @@ function useSessionStream(sessionId, enabled = true) {
15124
15096
  completionTokens: null,
15125
15097
  totalTokens: null,
15126
15098
  error: null,
15127
- parts: []
15099
+ parts: userParts
15128
15100
  };
15129
15101
  const next = [...oldMessages, newMessage];
15130
15102
  next.sort((a, b) => a.createdAt - b.createdAt);
@@ -15270,11 +15242,11 @@ function useSessionStream(sessionId, enabled = true) {
15270
15242
  }
15271
15243
 
15272
15244
  // src/hooks/useToolApprovalShortcuts.ts
15273
- import { useEffect as useEffect23, useCallback as useCallback16 } from "react";
15245
+ import { useEffect as useEffect22, useCallback as useCallback15 } from "react";
15274
15246
  function useToolApprovalShortcuts(sessionId) {
15275
15247
  const { pendingApprovals, removePendingApproval } = useToolApprovalStore();
15276
15248
  const sessionPendingApprovals = pendingApprovals;
15277
- const handleApprove = useCallback16(async (callId) => {
15249
+ const handleApprove = useCallback15(async (callId) => {
15278
15250
  if (!sessionId)
15279
15251
  return;
15280
15252
  try {
@@ -15284,7 +15256,7 @@ function useToolApprovalShortcuts(sessionId) {
15284
15256
  console.error("Failed to approve tool call:", error);
15285
15257
  }
15286
15258
  }, [sessionId, removePendingApproval]);
15287
- const handleReject = useCallback16(async (callId) => {
15259
+ const handleReject = useCallback15(async (callId) => {
15288
15260
  if (!sessionId)
15289
15261
  return;
15290
15262
  try {
@@ -15294,7 +15266,7 @@ function useToolApprovalShortcuts(sessionId) {
15294
15266
  console.error("Failed to reject tool call:", error);
15295
15267
  }
15296
15268
  }, [sessionId, removePendingApproval]);
15297
- const handleApproveAll = useCallback16(async () => {
15269
+ const handleApproveAll = useCallback15(async () => {
15298
15270
  if (!sessionId)
15299
15271
  return;
15300
15272
  try {
@@ -15306,7 +15278,7 @@ function useToolApprovalShortcuts(sessionId) {
15306
15278
  console.error("Failed to approve all tool calls:", error);
15307
15279
  }
15308
15280
  }, [sessionId, sessionPendingApprovals, removePendingApproval]);
15309
- useEffect23(() => {
15281
+ useEffect22(() => {
15310
15282
  if (!sessionId || sessionPendingApprovals.length === 0)
15311
15283
  return;
15312
15284
  const handleKeyDown = (e) => {
@@ -15337,13 +15309,13 @@ function useToolApprovalShortcuts(sessionId) {
15337
15309
  }
15338
15310
 
15339
15311
  // src/components/settings/SetuTopupModal.tsx
15340
- import { memo as memo14, useState as useState29, useEffect as useEffect24, useCallback as useCallback17, useRef as useRef15 } from "react";
15312
+ import { memo as memo14, useState as useState29, useEffect as useEffect23, useCallback as useCallback16, useRef as useRef15 } from "react";
15341
15313
  import {
15342
15314
  CreditCard as CreditCard4,
15343
15315
  Wallet as Wallet2,
15344
15316
  Loader2 as Loader26,
15345
15317
  ExternalLink as ExternalLink6,
15346
- RefreshCw as RefreshCw6
15318
+ RefreshCw as RefreshCw5
15347
15319
  } from "lucide-react";
15348
15320
 
15349
15321
  // src/components/common/StatusIndicator.tsx
@@ -15558,7 +15530,7 @@ var SetuTopupModal = memo14(function SetuTopupModal2() {
15558
15530
  const effectiveAmount = isCustom ? parseFloat(customAmount) || 0 : amount;
15559
15531
  const hasGoPlan = !!subscription?.active;
15560
15532
  const minAmount = gateway === "razorpay" ? MIN_AMOUNT_RAZORPAY : MIN_AMOUNT;
15561
- const fetchEstimate = useCallback17(async (amt) => {
15533
+ const fetchEstimate = useCallback16(async (amt) => {
15562
15534
  if (amt < minAmount || amt > MAX_AMOUNT) {
15563
15535
  setEstimate(null);
15564
15536
  setRazorpayEstimate(null);
@@ -15582,20 +15554,20 @@ var SetuTopupModal = memo14(function SetuTopupModal2() {
15582
15554
  setIsLoadingEstimate(false);
15583
15555
  }
15584
15556
  }, [gateway, minAmount]);
15585
- useEffect24(() => {
15557
+ useEffect23(() => {
15586
15558
  if (isOpen && effectiveAmount >= minAmount && view === "amount") {
15587
15559
  const timeout = setTimeout(() => fetchEstimate(effectiveAmount), 300);
15588
15560
  return () => clearTimeout(timeout);
15589
15561
  }
15590
15562
  }, [isOpen, effectiveAmount, fetchEstimate, view, minAmount]);
15591
- const stopPolling = useCallback17(() => {
15563
+ const stopPolling = useCallback16(() => {
15592
15564
  if (pollRef.current) {
15593
15565
  clearInterval(pollRef.current);
15594
15566
  pollRef.current = null;
15595
15567
  }
15596
15568
  setIsPolling(false);
15597
15569
  }, []);
15598
- useEffect24(() => {
15570
+ useEffect23(() => {
15599
15571
  if (!isOpen) {
15600
15572
  stopPolling();
15601
15573
  setView("amount");
@@ -15604,10 +15576,10 @@ var SetuTopupModal = memo14(function SetuTopupModal2() {
15604
15576
  setPollCount(0);
15605
15577
  }
15606
15578
  }, [isOpen, stopPolling]);
15607
- useEffect24(() => {
15579
+ useEffect23(() => {
15608
15580
  return () => stopPolling();
15609
15581
  }, [stopPolling]);
15610
- const startPolling = useCallback17((checkoutId) => {
15582
+ const startPolling = useCallback16((checkoutId) => {
15611
15583
  if (pollRef.current)
15612
15584
  return;
15613
15585
  setIsPolling(true);
@@ -15642,7 +15614,7 @@ var SetuTopupModal = memo14(function SetuTopupModal2() {
15642
15614
  setCustomAmount(value);
15643
15615
  setIsCustom(true);
15644
15616
  };
15645
- const openCheckoutUrl = useCallback17((url) => {
15617
+ const openCheckoutUrl = useCallback16((url) => {
15646
15618
  if (window.self !== window.top) {
15647
15619
  window.parent.postMessage({ type: "otto-open-url", url }, "*");
15648
15620
  } else {
@@ -15840,7 +15812,7 @@ var SetuTopupModal = memo14(function SetuTopupModal2() {
15840
15812
  children: [
15841
15813
  isManualChecking ? /* @__PURE__ */ jsx67(Loader26, {
15842
15814
  className: "w-4 h-4 animate-spin"
15843
- }) : /* @__PURE__ */ jsx67(RefreshCw6, {
15815
+ }) : /* @__PURE__ */ jsx67(RefreshCw5, {
15844
15816
  className: "w-4 h-4"
15845
15817
  }),
15846
15818
  isManualChecking ? "Checking..." : "Check Now"
@@ -16306,7 +16278,7 @@ var SessionItem = memo16(function SessionItem2({
16306
16278
  });
16307
16279
  });
16308
16280
  // src/components/sessions/SessionListContainer.tsx
16309
- import { memo as memo17, useMemo as useMemo16, useCallback as useCallback18, useEffect as useEffect25, useRef as useRef16 } from "react";
16281
+ import { memo as memo17, useMemo as useMemo16, useCallback as useCallback17, useEffect as useEffect24, useRef as useRef16 } from "react";
16310
16282
 
16311
16283
  // src/stores/focusStore.ts
16312
16284
  import { create as create18 } from "zustand";
@@ -16339,7 +16311,7 @@ var SessionListContainer = memo17(function SessionListContainer2({
16339
16311
  const itemRefs = useRef16(new Map);
16340
16312
  const scrollContainerRef = useRef16(null);
16341
16313
  const lastScrolledSessionId = useRef16(undefined);
16342
- const handleSessionClick = useCallback18((sessionId) => {
16314
+ const handleSessionClick = useCallback17((sessionId) => {
16343
16315
  lastScrolledSessionId.current = sessionId;
16344
16316
  onSelectSession(sessionId);
16345
16317
  }, [onSelectSession]);
@@ -16368,7 +16340,7 @@ var SessionListContainer = memo17(function SessionListContainer2({
16368
16340
  sessions: groupedSessions
16369
16341
  }));
16370
16342
  }, [sessionSnapshot]);
16371
- useEffect25(() => {
16343
+ useEffect24(() => {
16372
16344
  if (currentFocus === "sessions") {
16373
16345
  const session = sessionSnapshot[sessionIndex];
16374
16346
  if (session) {
@@ -16377,7 +16349,7 @@ var SessionListContainer = memo17(function SessionListContainer2({
16377
16349
  }
16378
16350
  }
16379
16351
  }, [currentFocus, sessionIndex, sessionSnapshot]);
16380
- useEffect25(() => {
16352
+ useEffect24(() => {
16381
16353
  if (!activeSessionId || lastScrolledSessionId.current === activeSessionId || sessions.length === 0)
16382
16354
  return;
16383
16355
  const activeIndex = sessions.findIndex((s) => s.id === activeSessionId);
@@ -16393,7 +16365,7 @@ var SessionListContainer = memo17(function SessionListContainer2({
16393
16365
  });
16394
16366
  }
16395
16367
  }, [activeSessionId, sessions, hasNextPage, fetchNextPage]);
16396
- useEffect25(() => {
16368
+ useEffect24(() => {
16397
16369
  const container = scrollContainerRef.current;
16398
16370
  if (!container)
16399
16371
  return;
@@ -17110,7 +17082,7 @@ ${file.absPath}`,
17110
17082
  }
17111
17083
 
17112
17084
  // src/components/git/GitFileList.tsx
17113
- import { useEffect as useEffect26, useRef as useRef17, useMemo as useMemo17 } from "react";
17085
+ import { useEffect as useEffect25, useRef as useRef17, useMemo as useMemo17 } from "react";
17114
17086
  import { jsx as jsx73, jsxs as jsxs65 } from "react/jsx-runtime";
17115
17087
  function GitFileList({ status }) {
17116
17088
  const { openCommitModal, openDiff } = useGitStore();
@@ -17145,7 +17117,7 @@ function GitFileList({ status }) {
17145
17117
  }
17146
17118
  };
17147
17119
  const conflictedLength = status.conflicted?.length ?? 0;
17148
- useEffect26(() => {
17120
+ useEffect25(() => {
17149
17121
  if (currentFocus === "git" && gitFileIndex >= 0) {
17150
17122
  const element = itemRefs.current.get(gitFileIndex);
17151
17123
  element?.scrollIntoView({ block: "nearest", behavior: "smooth" });
@@ -17349,7 +17321,7 @@ function GitFileList({ status }) {
17349
17321
  });
17350
17322
  }
17351
17323
  // src/components/git/GitSidebar.tsx
17352
- import { memo as memo18, useCallback as useCallback19, useEffect as useEffect27, useState as useState31 } from "react";
17324
+ import { memo as memo18, useCallback as useCallback18, useEffect as useEffect26, useState as useState31 } from "react";
17353
17325
  import {
17354
17326
  FolderGit2,
17355
17327
  ChevronRight as ChevronRight10,
@@ -17358,7 +17330,7 @@ import {
17358
17330
  GitBranch as GitBranch8,
17359
17331
  Globe as Globe2,
17360
17332
  Plus as Plus3,
17361
- RefreshCw as RefreshCw7,
17333
+ RefreshCw as RefreshCw6,
17362
17334
  Sparkles as Sparkles4,
17363
17335
  Trash2 as Trash24,
17364
17336
  Upload,
@@ -17390,7 +17362,7 @@ var GitSidebar = memo18(function GitSidebar2({
17390
17362
  const [remoteName, setRemoteName] = useState31("origin");
17391
17363
  const [remoteUrl, setRemoteUrl] = useState31("");
17392
17364
  const [confirmRemoveRemote, setConfirmRemoveRemote] = useState31(null);
17393
- useEffect27(() => {
17365
+ useEffect26(() => {
17394
17366
  if (isExpanded) {
17395
17367
  queryClient.invalidateQueries({ queryKey: ["git", "status"] });
17396
17368
  }
@@ -17398,11 +17370,11 @@ var GitSidebar = memo18(function GitSidebar2({
17398
17370
  const handleRefresh = () => {
17399
17371
  refetch();
17400
17372
  };
17401
- const addError = useCallback19((message, context) => {
17373
+ const addError = useCallback18((message, context) => {
17402
17374
  const id = `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
17403
17375
  setErrors((prev) => [...prev, { id, message, context }]);
17404
17376
  }, []);
17405
- const dismissError = useCallback19((id) => {
17377
+ const dismissError = useCallback18((id) => {
17406
17378
  setErrors((prev) => prev.filter((e) => e.id !== id));
17407
17379
  }, []);
17408
17380
  const handlePush = async () => {
@@ -17446,7 +17418,7 @@ var GitSidebar = memo18(function GitSidebar2({
17446
17418
  addError(err instanceof Error ? err.message : "Failed to remove remote", "git remote remove");
17447
17419
  }
17448
17420
  };
17449
- const handleFixWithAI = useCallback19((gitError) => {
17421
+ const handleFixWithAI = useCallback18((gitError) => {
17450
17422
  const prompt = gitError.context ? `I got a git error during ${gitError.context}:
17451
17423
 
17452
17424
  ${gitError.message}
@@ -17819,7 +17791,7 @@ Please help me fix this.`;
17819
17791
  title: "Refresh git status",
17820
17792
  className: "h-6 w-6 flex-shrink-0",
17821
17793
  disabled: isLoading,
17822
- children: /* @__PURE__ */ jsx74(RefreshCw7, {
17794
+ children: /* @__PURE__ */ jsx74(RefreshCw6, {
17823
17795
  className: `w-3 h-3 ${isLoading ? "animate-spin" : ""}`
17824
17796
  })
17825
17797
  })
@@ -17856,7 +17828,7 @@ var GitSidebarToggle = memo19(function GitSidebarToggle2() {
17856
17828
  });
17857
17829
  });
17858
17830
  // src/components/git/GitDiffPanel.tsx
17859
- import { useEffect as useEffect28, useRef as useRef18, memo as memo20, useState as useState32 } from "react";
17831
+ import { useEffect as useEffect27, useRef as useRef18, memo as memo20, useState as useState32 } from "react";
17860
17832
  import { X as X11, Maximize2, Minimize2 as Minimize22 } from "lucide-react";
17861
17833
 
17862
17834
  // src/stores/sidebarStore.ts
@@ -17915,7 +17887,7 @@ var GitDiffPanel = memo20(function GitDiffPanel2() {
17915
17887
  const { data: fullFileDiff, isLoading: fullFileLoading } = useGitDiffFullFile(selectedFile, selectedFileStaged, showFullFile);
17916
17888
  const activeDiff = showFullFile && fullFileDiff ? fullFileDiff : diff;
17917
17889
  const activeLoading = showFullFile ? fullFileLoading : isLoading;
17918
- useEffect28(() => {
17890
+ useEffect27(() => {
17919
17891
  if (!isDiffOpen)
17920
17892
  setShowFullFile(false);
17921
17893
  if (isDiffOpen && !prevDiffOpenRef.current) {
@@ -17930,17 +17902,20 @@ var GitDiffPanel = memo20(function GitDiffPanel2() {
17930
17902
  }
17931
17903
  prevDiffOpenRef.current = isDiffOpen;
17932
17904
  }, [isDiffOpen, setCollapsed]);
17933
- useEffect28(() => {
17905
+ useEffect27(() => {
17934
17906
  const handleEscape = (e) => {
17935
17907
  const target = e.target;
17936
17908
  const isInInput = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable;
17937
17909
  if ((e.key === "Escape" || e.key === "q" && !isInInput) && isDiffOpen) {
17938
17910
  closeDiff();
17939
17911
  }
17912
+ if (e.key === "f" && !isInInput && isDiffOpen) {
17913
+ setShowFullFile((v) => !v);
17914
+ }
17940
17915
  };
17941
17916
  document.addEventListener("keydown", handleEscape);
17942
17917
  return () => document.removeEventListener("keydown", handleEscape);
17943
- }, [isDiffOpen, closeDiff]);
17918
+ }, [isDiffOpen, closeDiff, setShowFullFile]);
17944
17919
  if (!isDiffOpen || !selectedFile)
17945
17920
  return null;
17946
17921
  return /* @__PURE__ */ jsxs68("div", {
@@ -17977,7 +17952,7 @@ ${activeDiff?.absPath || ""}`,
17977
17952
  variant: showFullFile ? "secondary" : "ghost",
17978
17953
  size: "sm",
17979
17954
  onClick: () => setShowFullFile((v) => !v),
17980
- title: showFullFile ? "Show diff only" : "Show full file with diff",
17955
+ title: showFullFile ? "Show diff only (f)" : "Show full file with diff (f)",
17981
17956
  className: "flex items-center gap-1.5 text-xs h-7",
17982
17957
  children: [
17983
17958
  showFullFile ? /* @__PURE__ */ jsx76(Minimize22, {
@@ -18006,7 +17981,7 @@ ${activeDiff?.absPath || ""}`,
18006
17981
  });
18007
17982
  });
18008
17983
  // src/components/git/GitCommitModal.tsx
18009
- import { useState as useState33, useId as useId2, useEffect as useEffect29, useCallback as useCallback20 } from "react";
17984
+ import { useState as useState33, useId as useId2, useEffect as useEffect28, useCallback as useCallback19 } from "react";
18010
17985
  import { GitCommit as GitCommit4, Sparkles as Sparkles5, Loader2 as Loader28 } from "lucide-react";
18011
17986
  import { jsx as jsx77, jsxs as jsxs69, Fragment as Fragment32 } from "react/jsx-runtime";
18012
17987
  function GitCommitModal() {
@@ -18016,7 +17991,7 @@ function GitCommitModal() {
18016
17991
  const generateMessage = useGenerateCommitMessage(commitSessionId);
18017
17992
  const [message, setMessage] = useState33("");
18018
17993
  const messageId = useId2();
18019
- const handleCommit = useCallback20(async () => {
17994
+ const handleCommit = useCallback19(async () => {
18020
17995
  if (!message.trim())
18021
17996
  return;
18022
17997
  try {
@@ -18031,7 +18006,7 @@ function GitCommitModal() {
18031
18006
  setMessage("");
18032
18007
  closeCommitModal();
18033
18008
  };
18034
- const handleGenerateMessage = useCallback20(async () => {
18009
+ const handleGenerateMessage = useCallback19(async () => {
18035
18010
  try {
18036
18011
  const result = await generateMessage.mutateAsync();
18037
18012
  setMessage(result.message);
@@ -18039,7 +18014,7 @@ function GitCommitModal() {
18039
18014
  console.error("Failed to generate commit message:", error);
18040
18015
  }
18041
18016
  }, [generateMessage]);
18042
- useEffect29(() => {
18017
+ useEffect28(() => {
18043
18018
  if (!isCommitModalOpen)
18044
18019
  return;
18045
18020
  const handleKeyDown = (e) => {
@@ -18177,7 +18152,7 @@ function GitCommitModal() {
18177
18152
  });
18178
18153
  }
18179
18154
  // src/components/terminals/TerminalsPanel.tsx
18180
- import { memo as memo22, useCallback as useCallback22, useRef as useRef20, useEffect as useEffect31 } from "react";
18155
+ import { memo as memo22, useCallback as useCallback21, useRef as useRef20, useEffect as useEffect30 } from "react";
18181
18156
  import {
18182
18157
  Terminal as TerminalIcon,
18183
18158
  Maximize2 as Maximize22,
@@ -18347,7 +18322,7 @@ var TerminalTabBar = memo21(function TerminalTabBar2({
18347
18322
  });
18348
18323
 
18349
18324
  // src/components/terminals/TerminalViewer.tsx
18350
- import { useEffect as useEffect30, useRef as useRef19, useState as useState34, useCallback as useCallback21 } from "react";
18325
+ import { useEffect as useEffect29, useRef as useRef19, useState as useState34, useCallback as useCallback20 } from "react";
18351
18326
  import { init, Terminal as Terminal7, FitAddon } from "ghostty-web";
18352
18327
  import { client as client2 } from "@ottocode/api";
18353
18328
  import { jsx as jsx79, jsxs as jsxs71 } from "react/jsx-runtime";
@@ -18430,7 +18405,7 @@ function TerminalViewer({
18430
18405
  const containerRef = useRef19(null);
18431
18406
  const termRef = useRef19(null);
18432
18407
  const fitAddonRef = useRef19(null);
18433
- const eventSourceRef = useRef19(null);
18408
+ const sseAbortRef = useRef19(null);
18434
18409
  const retryCountRef = useRef19(0);
18435
18410
  const retryTimerRef = useRef19(null);
18436
18411
  const hasReceivedDataRef = useRef19(false);
@@ -18441,25 +18416,26 @@ function TerminalViewer({
18441
18416
  const userScrolledRef = useRef19(false);
18442
18417
  const bgColorRef = useRef19("#121216");
18443
18418
  const focusHandlersRef = useRef19(null);
18444
- const fitTerminal = useCallback21(() => {
18419
+ const fitTerminal = useCallback20(() => {
18445
18420
  if (fitAddonRef.current) {
18446
18421
  try {
18447
18422
  fitAddonRef.current.fit();
18448
18423
  } catch {}
18449
18424
  }
18450
18425
  }, []);
18451
- const connectSSE = useCallback21((term, baseUrl, skipHistory) => {
18452
- if (eventSourceRef.current) {
18453
- eventSourceRef.current.close();
18454
- eventSourceRef.current = null;
18426
+ const connectSSE = useCallback20((term, baseUrl, skipHistory) => {
18427
+ if (sseAbortRef.current) {
18428
+ sseAbortRef.current.abort();
18429
+ sseAbortRef.current = null;
18455
18430
  }
18456
18431
  const url = `${baseUrl}/v1/terminals/${terminalId}/output${skipHistory ? "?skipHistory=true" : ""}`;
18457
- const eventSource = new EventSource(url);
18458
- eventSourceRef.current = eventSource;
18432
+ const isTunnel = !baseUrl.includes("localhost") && !baseUrl.includes("127.0.0.1");
18433
+ const controller = new AbortController;
18434
+ sseAbortRef.current = controller;
18459
18435
  let gotFirstData = false;
18460
- eventSource.onmessage = (event) => {
18436
+ const handleMessage = (raw) => {
18461
18437
  try {
18462
- const data = JSON.parse(event.data);
18438
+ const data = JSON.parse(raw);
18463
18439
  if (data.type === "data") {
18464
18440
  const savedY = userScrolledRef.current ? term.getViewportY() : 0;
18465
18441
  term.write(data.line);
@@ -18481,12 +18457,49 @@ function TerminalViewer({
18481
18457
  }
18482
18458
  } catch {}
18483
18459
  };
18484
- eventSource.onerror = () => {
18485
- eventSource.close();
18486
- if (eventSourceRef.current === eventSource) {
18487
- eventSourceRef.current = null;
18460
+ const run = async () => {
18461
+ try {
18462
+ const response = await fetch(url, {
18463
+ method: isTunnel ? "POST" : "GET",
18464
+ headers: { Accept: "text/event-stream" },
18465
+ signal: controller.signal
18466
+ });
18467
+ if (!response.ok || !response.body)
18468
+ return;
18469
+ retryCountRef.current = 0;
18470
+ const reader = response.body.getReader();
18471
+ const decoder = new TextDecoder;
18472
+ let buffer = "";
18473
+ while (true) {
18474
+ const { done, value } = await reader.read();
18475
+ if (done)
18476
+ break;
18477
+ buffer += decoder.decode(value, { stream: true });
18478
+ let idx = buffer.indexOf(`
18479
+
18480
+ `);
18481
+ while (idx !== -1) {
18482
+ const raw = buffer.slice(0, idx);
18483
+ buffer = buffer.slice(idx + 2);
18484
+ for (const line of raw.split(`
18485
+ `)) {
18486
+ if (line.startsWith("data: ")) {
18487
+ handleMessage(line.slice(6));
18488
+ }
18489
+ }
18490
+ idx = buffer.indexOf(`
18491
+
18492
+ `);
18493
+ }
18494
+ }
18495
+ } catch (error) {
18496
+ if (error instanceof Error && error.name === "AbortError")
18497
+ return;
18498
+ }
18499
+ if (sseAbortRef.current === controller) {
18500
+ sseAbortRef.current = null;
18488
18501
  }
18489
- if (retryCountRef.current < SSE_MAX_RETRIES) {
18502
+ if (!controller.signal.aborted && retryCountRef.current < SSE_MAX_RETRIES) {
18490
18503
  retryCountRef.current++;
18491
18504
  retryTimerRef.current = setTimeout(() => {
18492
18505
  if (termRef.current) {
@@ -18495,11 +18508,9 @@ function TerminalViewer({
18495
18508
  }, SSE_RECONNECT_DELAY);
18496
18509
  }
18497
18510
  };
18498
- eventSource.onopen = () => {
18499
- retryCountRef.current = 0;
18500
- };
18511
+ run();
18501
18512
  }, [terminalId]);
18502
- useEffect30(() => {
18513
+ useEffect29(() => {
18503
18514
  if (!containerRef.current || !terminalId)
18504
18515
  return;
18505
18516
  let disposed = false;
@@ -18509,9 +18520,9 @@ function TerminalViewer({
18509
18520
  setReady(false);
18510
18521
  retryCountRef.current = 0;
18511
18522
  hasReceivedDataRef.current = false;
18512
- if (eventSourceRef.current) {
18513
- eventSourceRef.current.close();
18514
- eventSourceRef.current = null;
18523
+ if (sseAbortRef.current) {
18524
+ sseAbortRef.current.abort();
18525
+ sseAbortRef.current = null;
18515
18526
  }
18516
18527
  if (retryTimerRef.current) {
18517
18528
  clearTimeout(retryTimerRef.current);
@@ -18664,9 +18675,9 @@ function TerminalViewer({
18664
18675
  clearTimeout(retryTimerRef.current);
18665
18676
  retryTimerRef.current = null;
18666
18677
  }
18667
- if (eventSourceRef.current) {
18668
- eventSourceRef.current.close();
18669
- eventSourceRef.current = null;
18678
+ if (sseAbortRef.current) {
18679
+ sseAbortRef.current.abort();
18680
+ sseAbortRef.current = null;
18670
18681
  }
18671
18682
  if (resizeObserver) {
18672
18683
  resizeObserver.disconnect();
@@ -18678,7 +18689,7 @@ function TerminalViewer({
18678
18689
  fitAddonRef.current = null;
18679
18690
  };
18680
18691
  }, [terminalId, connectSSE]);
18681
- useEffect30(() => {
18692
+ useEffect29(() => {
18682
18693
  const term = termRef.current;
18683
18694
  if (!term)
18684
18695
  return;
@@ -18696,7 +18707,7 @@ function TerminalViewer({
18696
18707
  }
18697
18708
  }
18698
18709
  }, [isActive, fitTerminal]);
18699
- useEffect30(() => {
18710
+ useEffect29(() => {
18700
18711
  fitTerminal();
18701
18712
  }, [fitTerminal]);
18702
18713
  return /* @__PURE__ */ jsx79("div", {
@@ -18771,12 +18782,12 @@ var TerminalsPanel = memo22(function TerminalsPanel2() {
18771
18782
  const autoCreatingRef = useRef20(false);
18772
18783
  const terminalsListRef = useRef20(terminalsList);
18773
18784
  terminalsListRef.current = terminalsList;
18774
- useEffect31(() => {
18785
+ useEffect30(() => {
18775
18786
  if (isOpen && terminalsListRef.current.length > 0 && (!activeTabId || !terminalsListRef.current.find((t) => t.id === activeTabId))) {
18776
18787
  selectTab(terminalsListRef.current[0].id);
18777
18788
  }
18778
18789
  }, [isOpen, terminalsList.length, activeTabId, selectTab]);
18779
- useEffect31(() => {
18790
+ useEffect30(() => {
18780
18791
  if (isOpen && terminals && terminalsList.length === 0 && !autoCreatingRef.current && !createTerminal.isPending) {
18781
18792
  autoCreatingRef.current = true;
18782
18793
  createTerminal.mutateAsync({
@@ -18789,7 +18800,7 @@ var TerminalsPanel = memo22(function TerminalsPanel2() {
18789
18800
  });
18790
18801
  }
18791
18802
  }, [isOpen, terminals, terminalsList.length, selectTab]);
18792
- const handleNewTerminal = useCallback22(async () => {
18803
+ const handleNewTerminal = useCallback21(async () => {
18793
18804
  try {
18794
18805
  const result = await createTerminal.mutateAsync({
18795
18806
  command: "bash",
@@ -18798,7 +18809,7 @@ var TerminalsPanel = memo22(function TerminalsPanel2() {
18798
18809
  selectTab(result.terminalId);
18799
18810
  } catch {}
18800
18811
  }, [createTerminal, selectTab]);
18801
- const handleKillTerminal = useCallback22(async (id) => {
18812
+ const handleKillTerminal = useCallback21(async (id) => {
18802
18813
  try {
18803
18814
  await killTerminal.mutateAsync(id);
18804
18815
  if (activeTabId === id) {
@@ -18812,7 +18823,7 @@ var TerminalsPanel = memo22(function TerminalsPanel2() {
18812
18823
  }
18813
18824
  } catch {}
18814
18825
  }, [killTerminal, activeTabId, selectTab, closePanel]);
18815
- useEffect31(() => {
18826
+ useEffect30(() => {
18816
18827
  const handleKeyDown = (e) => {
18817
18828
  if (e.key === "`" && e.ctrlKey) {
18818
18829
  e.preventDefault();
@@ -18822,7 +18833,7 @@ var TerminalsPanel = memo22(function TerminalsPanel2() {
18822
18833
  window.addEventListener("keydown", handleKeyDown);
18823
18834
  return () => window.removeEventListener("keydown", handleKeyDown);
18824
18835
  }, [togglePanel]);
18825
- const handleResizeStart = useCallback22((e) => {
18836
+ const handleResizeStart = useCallback21((e) => {
18826
18837
  e.preventDefault();
18827
18838
  dragRef.current = {
18828
18839
  startY: e.clientY,
@@ -18973,7 +18984,7 @@ import {
18973
18984
  FileCode as FileCode2,
18974
18985
  FilePlus as FilePlus2,
18975
18986
  FileEdit as FileEdit4,
18976
- RefreshCw as RefreshCw8
18987
+ RefreshCw as RefreshCw7
18977
18988
  } from "lucide-react";
18978
18989
 
18979
18990
  // src/hooks/useSessionFiles.ts
@@ -19223,7 +19234,7 @@ var SessionFilesSidebar = memo24(function SessionFilesSidebar2({
19223
19234
  title: "Refresh session files",
19224
19235
  className: "h-6 w-6 transition-transform duration-200 hover:scale-110",
19225
19236
  disabled: isLoading,
19226
- children: /* @__PURE__ */ jsx82(RefreshCw8, {
19237
+ children: /* @__PURE__ */ jsx82(RefreshCw7, {
19227
19238
  className: `w-3 h-3 ${isLoading ? "animate-spin" : ""}`
19228
19239
  })
19229
19240
  })
@@ -19263,7 +19274,7 @@ var SessionFilesSidebarToggle = memo25(function SessionFilesSidebarToggle2({
19263
19274
  });
19264
19275
  });
19265
19276
  // src/components/session-files/SessionFilesDiffPanel.tsx
19266
- import { useEffect as useEffect32, useMemo as useMemo19, memo as memo26, useRef as useRef21 } from "react";
19277
+ import { useEffect as useEffect31, useMemo as useMemo19, memo as memo26, useRef as useRef21 } from "react";
19267
19278
  import { X as X13, ChevronLeft, ChevronRight as ChevronRight12 } from "lucide-react";
19268
19279
  import { Prism as SyntaxHighlighter10 } from "react-syntax-highlighter";
19269
19280
  import {
@@ -19595,7 +19606,7 @@ ${contentLines.map((line) => `+${line}`).join(`
19595
19606
  }
19596
19607
  return rawPatch;
19597
19608
  }, [selectedOperation, selectedFile]);
19598
- useEffect32(() => {
19609
+ useEffect31(() => {
19599
19610
  if (isDiffOpen && !prevDiffOpenRef.current) {
19600
19611
  const { isCollapsed } = useSidebarStore.getState();
19601
19612
  wasCollapsedRef.current = isCollapsed;
@@ -19608,7 +19619,7 @@ ${contentLines.map((line) => `+${line}`).join(`
19608
19619
  }
19609
19620
  prevDiffOpenRef.current = isDiffOpen;
19610
19621
  }, [isDiffOpen, setCollapsed]);
19611
- useEffect32(() => {
19622
+ useEffect31(() => {
19612
19623
  const handleKeyDown = (e) => {
19613
19624
  const target = e.target;
19614
19625
  const isInInput = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable;
@@ -19760,7 +19771,7 @@ ${contentLines.map((line) => `+${line}`).join(`
19760
19771
  });
19761
19772
  });
19762
19773
  // src/components/research/ResearchSidebar.tsx
19763
- import { memo as memo27, useState as useState35, useEffect as useEffect33, useCallback as useCallback23, useRef as useRef22, useMemo as useMemo20 } from "react";
19774
+ import { memo as memo27, useState as useState35, useEffect as useEffect32, useCallback as useCallback22, useRef as useRef22, useMemo as useMemo20 } from "react";
19764
19775
  import {
19765
19776
  ChevronRight as ChevronRight13,
19766
19777
  FlaskConical as FlaskConical3,
@@ -19955,12 +19966,12 @@ var ResearchSidebar = memo27(function ResearchSidebar2({
19955
19966
  queryClient.invalidateQueries({ queryKey: ["messages", sessionId] });
19956
19967
  }
19957
19968
  });
19958
- useEffect33(() => {
19969
+ useEffect32(() => {
19959
19970
  if (parentSessionId) {
19960
19971
  useResearchStore.getState().setParentSessionId(parentSessionId);
19961
19972
  }
19962
19973
  }, [parentSessionId]);
19963
- useEffect33(() => {
19974
+ useEffect32(() => {
19964
19975
  if (researchData?.sessions?.length) {
19965
19976
  const currentIsValid = researchData.sessions.some((s) => s.id === activeResearchSessionId);
19966
19977
  if (!currentIsValid) {
@@ -19970,20 +19981,20 @@ var ResearchSidebar = memo27(function ResearchSidebar2({
19970
19981
  selectResearchSession(null);
19971
19982
  }
19972
19983
  }, [researchData, activeResearchSessionId, selectResearchSession]);
19973
- useEffect33(() => {
19984
+ useEffect32(() => {
19974
19985
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
19975
19986
  }, []);
19976
- const adjustTextareaHeight = useCallback23(() => {
19987
+ const adjustTextareaHeight = useCallback22(() => {
19977
19988
  const textarea = textareaRef.current;
19978
19989
  if (!textarea)
19979
19990
  return;
19980
19991
  textarea.style.height = "auto";
19981
19992
  textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;
19982
19993
  }, []);
19983
- useEffect33(() => {
19994
+ useEffect32(() => {
19984
19995
  adjustTextareaHeight();
19985
19996
  }, [adjustTextareaHeight]);
19986
- const handleCreateNew = useCallback23(async () => {
19997
+ const handleCreateNew = useCallback22(async () => {
19987
19998
  if (!parentSessionId)
19988
19999
  return;
19989
20000
  try {
@@ -19998,11 +20009,11 @@ var ResearchSidebar = memo27(function ResearchSidebar2({
19998
20009
  console.error("Failed to create research session:", err);
19999
20010
  }
20000
20011
  }, [parentSessionId, createMutation, selectResearchSession, refetch]);
20001
- const handleSelectSession = useCallback23((session) => {
20012
+ const handleSelectSession = useCallback22((session) => {
20002
20013
  selectResearchSession(session.id);
20003
20014
  setShowHistory(false);
20004
20015
  }, [selectResearchSession]);
20005
- const handleInject = useCallback23(async () => {
20016
+ const handleInject = useCallback22(async () => {
20006
20017
  if (!parentSessionId || !activeResearchSessionId)
20007
20018
  return;
20008
20019
  const alreadyInjected = parentMessagesData?.some((m) => m.role === "system" && m.parts?.some((p) => typeof p.content === "string" && p.content.includes(`from="${activeResearchSessionId}"`)));
@@ -20040,7 +20051,7 @@ var ResearchSidebar = memo27(function ResearchSidebar2({
20040
20051
  parentMessagesData,
20041
20052
  queryClient
20042
20053
  ]);
20043
- const handleExport = useCallback23(async () => {
20054
+ const handleExport = useCallback22(async () => {
20044
20055
  if (!activeResearchSessionId)
20045
20056
  return;
20046
20057
  try {
@@ -20054,7 +20065,7 @@ var ResearchSidebar = memo27(function ResearchSidebar2({
20054
20065
  console.error("Failed to export to session:", err);
20055
20066
  }
20056
20067
  }, [activeResearchSessionId, exportMutation, onNavigateToSession]);
20057
- const handleSendMessage = useCallback23(async () => {
20068
+ const handleSendMessage = useCallback22(async () => {
20058
20069
  if (!inputValue.trim() || !parentSessionId)
20059
20070
  return;
20060
20071
  try {
@@ -20086,7 +20097,7 @@ var ResearchSidebar = memo27(function ResearchSidebar2({
20086
20097
  selectResearchSession,
20087
20098
  sendMessage
20088
20099
  ]);
20089
- const handleKeyDown = useCallback23((e) => {
20100
+ const handleKeyDown = useCallback22((e) => {
20090
20101
  if (e.key === "Enter" && !e.shiftKey) {
20091
20102
  e.preventDefault();
20092
20103
  handleSendMessage();
@@ -20098,7 +20109,7 @@ var ResearchSidebar = memo27(function ResearchSidebar2({
20098
20109
  return false;
20099
20110
  return parentMessagesData.some((m) => m.role === "system" && m.parts?.some((p) => typeof p.content === "string" && p.content.includes(`from="${activeResearchSessionId}"`)));
20100
20111
  }, [activeResearchSessionId, parentMessagesData]);
20101
- const handleModelChange = useCallback23(async (newProvider, newModel) => {
20112
+ const handleModelChange = useCallback22(async (newProvider, newModel) => {
20102
20113
  if (!activeResearchSessionId) {
20103
20114
  setShowModelSelector(false);
20104
20115
  return;
@@ -20504,7 +20515,7 @@ import {
20504
20515
  Zap,
20505
20516
  User as User3,
20506
20517
  ChevronDown as ChevronDown9,
20507
- RefreshCw as RefreshCw9,
20518
+ RefreshCw as RefreshCw8,
20508
20519
  Plus as Plus6,
20509
20520
  Pencil as Pencil3,
20510
20521
  Copy as Copy3,
@@ -20554,7 +20565,7 @@ var useOnboardingStore = create21((set, get) => ({
20554
20565
  }));
20555
20566
 
20556
20567
  // src/hooks/useAuthStatus.ts
20557
- import { useEffect as useEffect34, useCallback as useCallback24, useState as useState36, useRef as useRef23 } from "react";
20568
+ import { useEffect as useEffect33, useCallback as useCallback23, useState as useState36, useRef as useRef23 } from "react";
20558
20569
  import { useQueryClient as useQueryClient14 } from "@tanstack/react-query";
20559
20570
  var isInIframe = typeof window !== "undefined" && window.self !== window.top;
20560
20571
  function useAuthStatus() {
@@ -20569,7 +20580,7 @@ function useAuthStatus() {
20569
20580
  const [oauthPolling, setOauthPolling] = useState36(false);
20570
20581
  const oauthPollingRef = useRef23(null);
20571
20582
  const preOauthProvidersRef = useRef23(new Set);
20572
- const fetchAuthStatus = useCallback24(async () => {
20583
+ const fetchAuthStatus = useCallback23(async () => {
20573
20584
  setLoading(true);
20574
20585
  setError(null);
20575
20586
  try {
@@ -20586,7 +20597,7 @@ function useAuthStatus() {
20586
20597
  setLoading(false);
20587
20598
  }
20588
20599
  }, [setAuthStatus, setLoading, setError, queryClient]);
20589
- const checkOnboarding = useCallback24(async () => {
20600
+ const checkOnboarding = useCallback23(async () => {
20590
20601
  const status = await fetchAuthStatus();
20591
20602
  if (status) {
20592
20603
  const hasAnyProvider = Object.values(status.providers).some((p) => p.configured);
@@ -20597,7 +20608,7 @@ function useAuthStatus() {
20597
20608
  }
20598
20609
  setInitialized(true);
20599
20610
  }, [fetchAuthStatus, setOpen]);
20600
- const setupWallet = useCallback24(async () => {
20611
+ const setupWallet = useCallback23(async () => {
20601
20612
  setLoading(true);
20602
20613
  setError(null);
20603
20614
  try {
@@ -20612,7 +20623,7 @@ function useAuthStatus() {
20612
20623
  setLoading(false);
20613
20624
  }
20614
20625
  }, [fetchAuthStatus, setLoading, setError]);
20615
- const importWallet = useCallback24(async (privateKey) => {
20626
+ const importWallet = useCallback23(async (privateKey) => {
20616
20627
  setLoading(true);
20617
20628
  setError(null);
20618
20629
  try {
@@ -20627,7 +20638,7 @@ function useAuthStatus() {
20627
20638
  setLoading(false);
20628
20639
  }
20629
20640
  }, [fetchAuthStatus, setLoading, setError]);
20630
- const addProvider = useCallback24(async (provider, apiKey) => {
20641
+ const addProvider = useCallback23(async (provider, apiKey) => {
20631
20642
  setLoading(true);
20632
20643
  setError(null);
20633
20644
  try {
@@ -20642,7 +20653,7 @@ function useAuthStatus() {
20642
20653
  setLoading(false);
20643
20654
  }
20644
20655
  }, [fetchAuthStatus, setLoading, setError]);
20645
- const removeProvider = useCallback24(async (provider) => {
20656
+ const removeProvider = useCallback23(async (provider) => {
20646
20657
  setLoading(true);
20647
20658
  setError(null);
20648
20659
  try {
@@ -20657,7 +20668,7 @@ function useAuthStatus() {
20657
20668
  setLoading(false);
20658
20669
  }
20659
20670
  }, [fetchAuthStatus, setLoading, setError]);
20660
- const completeOnboarding = useCallback24(async () => {
20671
+ const completeOnboarding = useCallback23(async () => {
20661
20672
  setLoading(true);
20662
20673
  setError(null);
20663
20674
  try {
@@ -20672,13 +20683,13 @@ function useAuthStatus() {
20672
20683
  setLoading(false);
20673
20684
  }
20674
20685
  }, [fetchAuthStatus, setLoading, setError, setOpen]);
20675
- const snapshotConfiguredProviders = useCallback24(() => {
20686
+ const snapshotConfiguredProviders = useCallback23(() => {
20676
20687
  const status = useOnboardingStore.getState().authStatus;
20677
20688
  if (status) {
20678
20689
  preOauthProvidersRef.current = new Set(Object.entries(status.providers).filter(([, p]) => p.configured).map(([id]) => id));
20679
20690
  }
20680
20691
  }, []);
20681
- const startOAuth = useCallback24((provider, mode) => {
20692
+ const startOAuth = useCallback23((provider, mode) => {
20682
20693
  const url = apiClient.getOAuthStartUrl(provider, mode);
20683
20694
  if (isInIframe) {
20684
20695
  snapshotConfiguredProviders();
@@ -20693,7 +20704,7 @@ function useAuthStatus() {
20693
20704
  const popup = window.open(url, "oauth_popup", `width=${width},height=${height},left=${left},top=${top},toolbar=no,menubar=no`);
20694
20705
  return popup;
20695
20706
  }, [snapshotConfiguredProviders]);
20696
- const startOAuthManual = useCallback24(async (provider, mode) => {
20707
+ const startOAuthManual = useCallback23(async (provider, mode) => {
20697
20708
  const { url, sessionId } = await apiClient.getOAuthUrl(provider, mode);
20698
20709
  if (isInIframe) {
20699
20710
  snapshotConfiguredProviders();
@@ -20708,7 +20719,7 @@ function useAuthStatus() {
20708
20719
  const popup = window.open(url, "oauth_popup", `width=${width},height=${height},left=${left},top=${top},toolbar=no,menubar=no`);
20709
20720
  return { popup, sessionId };
20710
20721
  }, [snapshotConfiguredProviders]);
20711
- const exchangeOAuthCode = useCallback24(async (provider, code, sessionId) => {
20722
+ const exchangeOAuthCode = useCallback23(async (provider, code, sessionId) => {
20712
20723
  setLoading(true);
20713
20724
  setError(null);
20714
20725
  try {
@@ -20723,7 +20734,7 @@ function useAuthStatus() {
20723
20734
  setLoading(false);
20724
20735
  }
20725
20736
  }, [fetchAuthStatus, setLoading, setError]);
20726
- useEffect34(() => {
20737
+ useEffect33(() => {
20727
20738
  if (!oauthPolling || !isInIframe)
20728
20739
  return;
20729
20740
  oauthPollingRef.current = setInterval(() => {
@@ -20737,7 +20748,7 @@ function useAuthStatus() {
20737
20748
  clearTimeout(timeout);
20738
20749
  };
20739
20750
  }, [oauthPolling, fetchAuthStatus]);
20740
- useEffect34(() => {
20751
+ useEffect33(() => {
20741
20752
  if (!oauthPolling || !authStatus)
20742
20753
  return;
20743
20754
  const currentConfigured = Object.entries(authStatus.providers).filter(([, p]) => p.configured);
@@ -20746,7 +20757,7 @@ function useAuthStatus() {
20746
20757
  setOauthPolling(false);
20747
20758
  }
20748
20759
  }, [authStatus, oauthPolling]);
20749
- useEffect34(() => {
20760
+ useEffect33(() => {
20750
20761
  const handleOAuthMessage = (event) => {
20751
20762
  if (event.data?.type === "oauth-success") {
20752
20763
  fetchAuthStatus();
@@ -20755,14 +20766,14 @@ function useAuthStatus() {
20755
20766
  window.addEventListener("message", handleOAuthMessage);
20756
20767
  return () => window.removeEventListener("message", handleOAuthMessage);
20757
20768
  }, [fetchAuthStatus]);
20758
- const pollCopilotDeviceFlow = useCallback24(async (sessionId) => {
20769
+ const pollCopilotDeviceFlow = useCallback23(async (sessionId) => {
20759
20770
  const result = await apiClient.pollCopilotDeviceFlow(sessionId);
20760
20771
  if (result.status === "complete") {
20761
20772
  await fetchAuthStatus();
20762
20773
  }
20763
20774
  return result;
20764
20775
  }, [fetchAuthStatus]);
20765
- const saveCopilotToken = useCallback24(async (token) => {
20776
+ const saveCopilotToken = useCallback23(async (token) => {
20766
20777
  setLoading(true);
20767
20778
  setError(null);
20768
20779
  try {
@@ -20777,7 +20788,7 @@ function useAuthStatus() {
20777
20788
  setLoading(false);
20778
20789
  }
20779
20790
  }, [fetchAuthStatus, setLoading, setError]);
20780
- const importCopilotTokenFromGh = useCallback24(async () => {
20791
+ const importCopilotTokenFromGh = useCallback23(async () => {
20781
20792
  setLoading(true);
20782
20793
  setError(null);
20783
20794
  try {
@@ -20815,6 +20826,72 @@ function useAuthStatus() {
20815
20826
  };
20816
20827
  }
20817
20828
 
20829
+ // src/hooks/useSetuBalance.ts
20830
+ import { useEffect as useEffect34, useCallback as useCallback24 } from "react";
20831
+ function useSetuBalance(providerName) {
20832
+ const setBalance = useSetuStore((s) => s.setBalance);
20833
+ const setUsdcBalance = useSetuStore((s) => s.setUsdcBalance);
20834
+ const setWalletAddress = useSetuStore((s) => s.setWalletAddress);
20835
+ const setLoading = useSetuStore((s) => s.setLoading);
20836
+ const setScope = useSetuStore((s) => s.setScope);
20837
+ const setPayg = useSetuStore((s) => s.setPayg);
20838
+ const setSubscription = useSetuStore((s) => s.setSubscription);
20839
+ const setLimits = useSetuStore((s) => s.setLimits);
20840
+ const balance = useSetuStore((s) => s.balance);
20841
+ const usdcBalance = useSetuStore((s) => s.usdcBalance);
20842
+ const network = useSetuStore((s) => s.network);
20843
+ const fetchBalance = useCallback24(async () => {
20844
+ if (providerName !== "setu") {
20845
+ return;
20846
+ }
20847
+ setLoading(true);
20848
+ try {
20849
+ const [setuData, usdcData, walletData] = await Promise.all([
20850
+ apiClient.getSetuBalance(),
20851
+ apiClient.getSetuUsdcBalance(network),
20852
+ apiClient.getSetuWallet()
20853
+ ]);
20854
+ if (setuData) {
20855
+ setBalance(setuData.balance);
20856
+ setWalletAddress(setuData.walletAddress);
20857
+ setScope(setuData.scope ?? null);
20858
+ setPayg(setuData.payg ?? null);
20859
+ setSubscription(setuData.subscription ?? null);
20860
+ setLimits(setuData.limits ?? null);
20861
+ } else if (walletData?.configured && walletData.publicKey) {
20862
+ setWalletAddress(walletData.publicKey);
20863
+ }
20864
+ if (usdcData) {
20865
+ setUsdcBalance(usdcData.usdcBalance);
20866
+ if (!setuData && usdcData.walletAddress) {
20867
+ setWalletAddress(usdcData.walletAddress);
20868
+ }
20869
+ }
20870
+ } catch {} finally {
20871
+ setLoading(false);
20872
+ }
20873
+ }, [
20874
+ providerName,
20875
+ network,
20876
+ setBalance,
20877
+ setUsdcBalance,
20878
+ setWalletAddress,
20879
+ setLoading,
20880
+ setScope,
20881
+ setPayg,
20882
+ setSubscription,
20883
+ setLimits
20884
+ ]);
20885
+ useEffect34(() => {
20886
+ if (providerName === "setu" && (balance === null || usdcBalance === null)) {
20887
+ fetchBalance();
20888
+ }
20889
+ }, [providerName, balance, usdcBalance, fetchBalance]);
20890
+ return {
20891
+ fetchBalance
20892
+ };
20893
+ }
20894
+
20818
20895
  // src/hooks/useTopupCallback.ts
20819
20896
  import { useEffect as useEffect35, useRef as useRef24 } from "react";
20820
20897
  var STORAGE_KEY2 = "pendingPolarCheckout";
@@ -21398,7 +21475,7 @@ var SetuWalletSection = memo29(function SetuWalletSection2({
21398
21475
  disabled: setuLoading,
21399
21476
  className: "p-1 hover:bg-muted rounded transition-colors disabled:opacity-50",
21400
21477
  title: "Refresh balances",
21401
- children: /* @__PURE__ */ jsx87(RefreshCw9, {
21478
+ children: /* @__PURE__ */ jsx87(RefreshCw8, {
21402
21479
  className: `w-3.5 h-3.5 text-muted-foreground ${setuLoading ? "animate-spin" : ""}`
21403
21480
  })
21404
21481
  }),
@@ -23708,7 +23785,7 @@ import {
23708
23785
  Folder as Folder2,
23709
23786
  FileCode as FileCode4,
23710
23787
  FolderTree as FolderTree3,
23711
- RefreshCw as RefreshCw10
23788
+ RefreshCw as RefreshCw9
23712
23789
  } from "lucide-react";
23713
23790
  import { jsx as jsx97, jsxs as jsxs87, Fragment as Fragment38 } from "react/jsx-runtime";
23714
23791
  var PANEL_KEY4 = "file-browser";
@@ -23881,7 +23958,7 @@ var FileBrowserSidebar = memo39(function FileBrowserSidebar2() {
23881
23958
  title: "Refresh file tree",
23882
23959
  className: "h-6 w-6 flex-shrink-0",
23883
23960
  disabled: isLoading,
23884
- children: /* @__PURE__ */ jsx97(RefreshCw10, {
23961
+ children: /* @__PURE__ */ jsx97(RefreshCw9, {
23885
23962
  className: `w-3 h-3 ${isLoading ? "animate-spin" : ""}`
23886
23963
  })
23887
23964
  })
@@ -24286,7 +24363,7 @@ import {
24286
24363
  Key as Key2,
24287
24364
  ExternalLink as ExternalLink10,
24288
24365
  ArrowRight as ArrowRight2,
24289
- RefreshCw as RefreshCw11
24366
+ RefreshCw as RefreshCw10
24290
24367
  } from "lucide-react";
24291
24368
  import { QRCodeSVG as QRCodeSVG3 } from "qrcode.react";
24292
24369
  import { jsx as jsx101, jsxs as jsxs90, Fragment as Fragment39 } from "react/jsx-runtime";
@@ -24739,7 +24816,7 @@ var ProviderSetupStep = memo43(function ProviderSetupStep2({
24739
24816
  onClick: fetchBalance,
24740
24817
  disabled: isBalanceLoading,
24741
24818
  className: "p-0.5 text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50",
24742
- children: /* @__PURE__ */ jsx101(RefreshCw11, {
24819
+ children: /* @__PURE__ */ jsx101(RefreshCw10, {
24743
24820
  className: `w-3 h-3 ${isBalanceLoading ? "animate-spin" : ""}`
24744
24821
  })
24745
24822
  })
@@ -25464,6 +25541,7 @@ var DefaultsStep = memo44(function DefaultsStep2({
25464
25541
  agent: selectedAgent,
25465
25542
  toolApproval: selectedApproval,
25466
25543
  guidedMode,
25544
+ fullWidthContent: config2?.defaults?.fullWidthContent ?? true,
25467
25545
  scope: "global"
25468
25546
  });
25469
25547
  await onComplete();
@@ -26642,4 +26720,4 @@ export {
26642
26720
  API_BASE_URL
26643
26721
  };
26644
26722
 
26645
- //# debugId=4BFF84A166AA818064756E2164756E21
26723
+ //# debugId=F20879653477A04464756E2164756E21