@ottocode/web-sdk 0.1.270 → 0.1.271

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/components/chat/ChatInput.d.ts.map +1 -1
  2. package/dist/components/chat/InputQueueBar.d.ts +6 -0
  3. package/dist/components/chat/InputQueueBar.d.ts.map +1 -0
  4. package/dist/components/chat/InputTodosBar.d.ts +6 -0
  5. package/dist/components/chat/InputTodosBar.d.ts.map +1 -0
  6. package/dist/components/chat/ShortcutsModal.d.ts.map +1 -1
  7. package/dist/components/file-browser/FileBrowserSidebar.d.ts.map +1 -1
  8. package/dist/components/file-browser/FileBrowserSidebarToggle.d.ts.map +1 -1
  9. package/dist/components/file-browser/FileViewerPanel.d.ts +3 -0
  10. package/dist/components/file-browser/FileViewerPanel.d.ts.map +1 -1
  11. package/dist/components/file-browser/QuickFilePicker.d.ts.map +1 -1
  12. package/dist/components/git/GitDiffPanel.d.ts +4 -0
  13. package/dist/components/git/GitDiffPanel.d.ts.map +1 -1
  14. package/dist/components/git/GitDiffViewer.d.ts.map +1 -1
  15. package/dist/components/git/GitFileItem.d.ts.map +1 -1
  16. package/dist/components/git/GitSidebarToggle.d.ts.map +1 -1
  17. package/dist/components/index.d.ts +3 -0
  18. package/dist/components/index.d.ts.map +1 -1
  19. package/dist/components/index.js +4941 -3722
  20. package/dist/components/index.js.map +55 -49
  21. package/dist/components/mcp/MCPSidebarToggle.d.ts.map +1 -1
  22. package/dist/components/messages/ActionToolBox.d.ts +2 -1
  23. package/dist/components/messages/ActionToolBox.d.ts.map +1 -1
  24. package/dist/components/messages/AssistantMessageGroup.d.ts.map +1 -1
  25. package/dist/components/messages/CompactActivityGroup.d.ts +2 -1
  26. package/dist/components/messages/CompactActivityGroup.d.ts.map +1 -1
  27. package/dist/components/messages/MessagePartItem.d.ts.map +1 -1
  28. package/dist/components/messages/MessageThread.d.ts.map +1 -1
  29. package/dist/components/messages/UserMessageGroup.d.ts.map +1 -1
  30. package/dist/components/messages/renderers/ProgressUpdateRenderer.d.ts.map +1 -1
  31. package/dist/components/messages/renderers/index.d.ts.map +1 -1
  32. package/dist/components/session-files/SessionFilesDiffPanel.d.ts +7 -0
  33. package/dist/components/session-files/SessionFilesDiffPanel.d.ts.map +1 -1
  34. package/dist/components/session-files/SessionFilesSidebar.d.ts.map +1 -1
  35. package/dist/components/session-files/SessionFilesSidebarToggle.d.ts.map +1 -1
  36. package/dist/components/sessions/SessionItem.d.ts.map +1 -1
  37. package/dist/components/sessions/SessionListContainer.d.ts.map +1 -1
  38. package/dist/components/sessions/session-time.d.ts.map +1 -1
  39. package/dist/components/settings/SettingsSidebarToggle.d.ts.map +1 -1
  40. package/dist/components/sidebar/SidebarShortcutBadge.d.ts +6 -0
  41. package/dist/components/sidebar/SidebarShortcutBadge.d.ts.map +1 -0
  42. package/dist/components/skills/SkillViewerPanel.d.ts +4 -0
  43. package/dist/components/skills/SkillViewerPanel.d.ts.map +1 -1
  44. package/dist/components/skills/SkillsSidebarToggle.d.ts.map +1 -1
  45. package/dist/components/tunnel/TunnelSidebarToggle.d.ts.map +1 -1
  46. package/dist/components/workspace/ViewerTabs.d.ts +2 -0
  47. package/dist/components/workspace/ViewerTabs.d.ts.map +1 -0
  48. package/dist/hooks/index.js +314 -60
  49. package/dist/hooks/index.js.map +16 -14
  50. package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -1
  51. package/dist/hooks/useMessages.d.ts.map +1 -1
  52. package/dist/hooks/useQueueState.d.ts.map +1 -1
  53. package/dist/hooks/useSessions.d.ts +1 -0
  54. package/dist/hooks/useSessions.d.ts.map +1 -1
  55. package/dist/hooks/useShortcutHintsVisible.d.ts +5 -0
  56. package/dist/hooks/useShortcutHintsVisible.d.ts.map +1 -0
  57. package/dist/index.js +5043 -3762
  58. package/dist/index.js.map +56 -50
  59. package/dist/lib/api-client/index.d.ts +1 -0
  60. package/dist/lib/api-client/index.d.ts.map +1 -1
  61. package/dist/lib/api-client/sessions.d.ts +1 -0
  62. package/dist/lib/api-client/sessions.d.ts.map +1 -1
  63. package/dist/lib/api-client/utils.d.ts.map +1 -1
  64. package/dist/lib/index.js +11 -2
  65. package/dist/lib/index.js.map +5 -5
  66. package/dist/stores/fileBrowserStore.d.ts +1 -0
  67. package/dist/stores/fileBrowserStore.d.ts.map +1 -1
  68. package/dist/stores/gitStore.d.ts.map +1 -1
  69. package/dist/stores/index.d.ts +2 -0
  70. package/dist/stores/index.d.ts.map +1 -1
  71. package/dist/stores/index.js +201 -60
  72. package/dist/stores/index.js.map +9 -7
  73. package/dist/stores/sessionFilesStore.d.ts.map +1 -1
  74. package/dist/stores/skillsStore.d.ts.map +1 -1
  75. package/dist/stores/todoStore.d.ts +18 -0
  76. package/dist/stores/todoStore.d.ts.map +1 -0
  77. package/dist/stores/viewerTabsStore.d.ts +41 -0
  78. package/dist/stores/viewerTabsStore.d.ts.map +1 -0
  79. package/dist/types/api.d.ts +7 -0
  80. package/dist/types/api.d.ts.map +1 -1
  81. package/package.json +3 -3
@@ -9,6 +9,7 @@ import {
9
9
  createMessage as apiCreateMessage,
10
10
  abortSession as apiAbortSession,
11
11
  deleteSession as apiDeleteSession,
12
+ markSessionViewed as apiMarkSessionViewed,
12
13
  updateSession as apiUpdateSession,
13
14
  getSessionQueue as apiGetSessionQueue,
14
15
  removeFromQueue as apiRemoveFromQueue,
@@ -95,7 +96,8 @@ function convertSession(apiSession) {
95
96
  ...apiSession,
96
97
  title: apiSession.title ?? null,
97
98
  createdAt: typeof apiSession.createdAt === "string" ? new Date(apiSession.createdAt).getTime() : apiSession.createdAt,
98
- lastActiveAt: typeof apiSession.lastActiveAt === "string" ? new Date(apiSession.lastActiveAt).getTime() : apiSession.lastActiveAt
99
+ lastActiveAt: typeof apiSession.lastActiveAt === "string" ? new Date(apiSession.lastActiveAt).getTime() : apiSession.lastActiveAt,
100
+ lastViewedAt: typeof apiSession.lastViewedAt === "string" ? new Date(apiSession.lastViewedAt).getTime() : apiSession.lastViewedAt
99
101
  };
100
102
  }
101
103
  function convertMessage(apiMessage) {
@@ -145,6 +147,12 @@ var sessionsMixin = {
145
147
  throw new Error(extractErrorMessage(response.error));
146
148
  return convertSession(response.data);
147
149
  },
150
+ async markSessionViewed(sessionId) {
151
+ const response = await apiMarkSessionViewed({ path: { sessionId } });
152
+ if (response.error)
153
+ throw new Error(extractErrorMessage(response.error));
154
+ return convertSession(response.data);
155
+ },
148
156
  async deleteSession(sessionId) {
149
157
  const response = await apiDeleteSession({ path: { sessionId } });
150
158
  if (response.error)
@@ -872,6 +880,7 @@ class ApiClient {
872
880
  getSessionsPage = sessionsMixin.getSessionsPage;
873
881
  createSession = sessionsMixin.createSession;
874
882
  updateSession = sessionsMixin.updateSession;
883
+ markSessionViewed = sessionsMixin.markSessionViewed;
875
884
  deleteSession = sessionsMixin.deleteSession;
876
885
  abortSession = sessionsMixin.abortSession;
877
886
  abortMessage = sessionsMixin.abortMessage;
@@ -1184,29 +1193,117 @@ function useFiles(options = {}) {
1184
1193
  import { useQuery as useQuery3, useMutation as useMutation2, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
1185
1194
 
1186
1195
  // src/stores/gitStore.ts
1187
- import { create as create8 } from "zustand";
1196
+ import { create as create9 } from "zustand";
1188
1197
 
1189
1198
  // src/stores/sessionFilesStore.ts
1190
- import { create as create7 } from "zustand";
1199
+ import { create as create8 } from "zustand";
1191
1200
 
1192
1201
  // src/stores/researchStore.ts
1193
- import { create as create6 } from "zustand";
1202
+ import { create as create7 } from "zustand";
1194
1203
 
1195
1204
  // src/stores/settingsStore.ts
1196
- import { create as create5 } from "zustand";
1205
+ import { create as create6 } from "zustand";
1197
1206
 
1198
1207
  // src/stores/tunnelStore.ts
1199
- import { create as create4 } from "zustand";
1208
+ import { create as create5 } from "zustand";
1200
1209
 
1201
1210
  // src/stores/fileBrowserStore.ts
1202
- import { create as create3 } from "zustand";
1211
+ import { create as create4 } from "zustand";
1203
1212
 
1204
1213
  // src/stores/mcpStore.ts
1205
- import { create as create2 } from "zustand";
1214
+ import { create as create3 } from "zustand";
1206
1215
 
1207
1216
  // src/stores/skillsStore.ts
1217
+ import { create as create2 } from "zustand";
1218
+
1219
+ // src/stores/viewerTabsStore.ts
1208
1220
  import { create } from "zustand";
1209
- var useSkillsStore = create((set) => ({
1221
+ function titleFromPath(path) {
1222
+ return path.split("/").pop() || path;
1223
+ }
1224
+ function upsertTab(tabs, tab) {
1225
+ const existingIndex = tabs.findIndex((item) => item.id === tab.id);
1226
+ if (existingIndex === -1) {
1227
+ return [...tabs, tab];
1228
+ }
1229
+ const next = [...tabs];
1230
+ next[existingIndex] = tab;
1231
+ return next;
1232
+ }
1233
+ var useViewerTabsStore = create((set) => ({
1234
+ tabs: [],
1235
+ activeTabId: null,
1236
+ openGitDiffTab: (path, staged) => {
1237
+ const id = `git-diff:${staged ? "staged" : "unstaged"}:${path}`;
1238
+ set((state) => ({
1239
+ tabs: upsertTab(state.tabs, {
1240
+ id,
1241
+ type: "git-diff",
1242
+ title: titleFromPath(path),
1243
+ path,
1244
+ staged
1245
+ }),
1246
+ activeTabId: id
1247
+ }));
1248
+ },
1249
+ openSessionFileDiffTab: (path, operations) => {
1250
+ const id = `session-file-diff:${path}`;
1251
+ set((state) => ({
1252
+ tabs: upsertTab(state.tabs, {
1253
+ id,
1254
+ type: "session-file-diff",
1255
+ title: titleFromPath(path),
1256
+ path,
1257
+ operations,
1258
+ selectedOperationIndex: Math.max(0, operations.length - 1)
1259
+ }),
1260
+ activeTabId: id
1261
+ }));
1262
+ },
1263
+ openFileTab: (path) => {
1264
+ const id = `file:${path}`;
1265
+ set((state) => ({
1266
+ tabs: upsertTab(state.tabs, {
1267
+ id,
1268
+ type: "file",
1269
+ title: titleFromPath(path),
1270
+ path
1271
+ }),
1272
+ activeTabId: id
1273
+ }));
1274
+ },
1275
+ openSkillFileTab: (skill, file) => {
1276
+ const displayFile = file ?? "SKILL.md";
1277
+ const id = `skill-file:${skill}:${displayFile}`;
1278
+ set((state) => ({
1279
+ tabs: upsertTab(state.tabs, {
1280
+ id,
1281
+ type: "skill-file",
1282
+ title: titleFromPath(displayFile),
1283
+ skill,
1284
+ file
1285
+ }),
1286
+ activeTabId: id
1287
+ }));
1288
+ },
1289
+ setActiveTab: (id) => set({ activeTabId: id }),
1290
+ closeTab: (id) => set((state) => {
1291
+ const closingIndex = state.tabs.findIndex((tab) => tab.id === id);
1292
+ const tabs = state.tabs.filter((tab) => tab.id !== id);
1293
+ let activeTabId = state.activeTabId;
1294
+ if (state.activeTabId === id) {
1295
+ activeTabId = tabs[closingIndex]?.id ?? tabs[closingIndex - 1]?.id ?? null;
1296
+ }
1297
+ return { tabs, activeTabId };
1298
+ }),
1299
+ updateSessionFileOperationIndex: (id, index) => set((state) => ({
1300
+ tabs: state.tabs.map((tab) => tab.id === id && tab.type === "session-file-diff" ? { ...tab, selectedOperationIndex: index } : tab)
1301
+ })),
1302
+ closeAllTabs: () => set({ tabs: [], activeTabId: null })
1303
+ }));
1304
+
1305
+ // src/stores/skillsStore.ts
1306
+ var useSkillsStore = create2((set, get) => ({
1210
1307
  isExpanded: false,
1211
1308
  skills: [],
1212
1309
  globalEnabled: true,
@@ -1244,12 +1341,18 @@ var useSkillsStore = create((set) => ({
1244
1341
  setSkills: (skills) => set({ skills }),
1245
1342
  setSkillsConfig: ({ skills, globalEnabled, totalCount, enabledCount }) => set({ skills, globalEnabled, totalCount, enabledCount }),
1246
1343
  selectSkill: (name) => set({ selectedSkill: name, isViewerOpen: false, viewingFile: null }),
1247
- openViewer: (file) => set({ isViewerOpen: true, viewingFile: file }),
1344
+ openViewer: (file) => {
1345
+ const selectedSkill = get().selectedSkill;
1346
+ if (selectedSkill) {
1347
+ useViewerTabsStore.getState().openSkillFileTab(selectedSkill, file);
1348
+ }
1349
+ set({ isViewerOpen: true, viewingFile: file });
1350
+ },
1248
1351
  closeViewer: () => set({ isViewerOpen: false, viewingFile: null })
1249
1352
  }));
1250
1353
 
1251
1354
  // src/stores/mcpStore.ts
1252
- var useMCPStore = create2((set) => ({
1355
+ var useMCPStore = create3((set) => ({
1253
1356
  isExpanded: false,
1254
1357
  servers: [],
1255
1358
  loading: new Set,
@@ -1305,7 +1408,22 @@ var useMCPStore = create2((set) => ({
1305
1408
  }));
1306
1409
 
1307
1410
  // src/stores/fileBrowserStore.ts
1308
- var useFileBrowserStore = create3((set) => ({
1411
+ function getAncestorDirs(path) {
1412
+ const normalizedPath = path.replace(/\\/g, "/").replace(/^\.\//, "");
1413
+ const parts = normalizedPath.split("/").filter(Boolean);
1414
+ return parts.slice(0, -1).map((_, index) => parts.slice(0, index + 1).join("/"));
1415
+ }
1416
+ function revealFileState(state, path) {
1417
+ const expandedDirs = new Set(state.expandedDirs);
1418
+ for (const dir of getAncestorDirs(path)) {
1419
+ expandedDirs.add(dir);
1420
+ }
1421
+ return {
1422
+ selectedFile: path,
1423
+ expandedDirs
1424
+ };
1425
+ }
1426
+ var useFileBrowserStore = create4((set) => ({
1309
1427
  isExpanded: false,
1310
1428
  selectedFile: null,
1311
1429
  isViewerOpen: false,
@@ -1340,10 +1458,14 @@ var useFileBrowserStore = create3((set) => ({
1340
1458
  isViewerOpen: false,
1341
1459
  selectedFile: null
1342
1460
  }),
1343
- openFile: (path) => set({
1344
- selectedFile: path,
1345
- isViewerOpen: true
1346
- }),
1461
+ openFile: (path) => {
1462
+ useViewerTabsStore.getState().openFileTab(path);
1463
+ set((state) => ({
1464
+ ...revealFileState(state, path),
1465
+ isViewerOpen: true
1466
+ }));
1467
+ },
1468
+ revealFile: (path) => set((state) => revealFileState(state, path)),
1347
1469
  closeViewer: () => set({
1348
1470
  isViewerOpen: false,
1349
1471
  selectedFile: null
@@ -1360,7 +1482,7 @@ var useFileBrowserStore = create3((set) => ({
1360
1482
  }));
1361
1483
 
1362
1484
  // src/stores/tunnelStore.ts
1363
- var useTunnelStore = create4((set) => ({
1485
+ var useTunnelStore = create5((set) => ({
1364
1486
  isExpanded: false,
1365
1487
  status: "idle",
1366
1488
  url: null,
@@ -1408,7 +1530,7 @@ var useTunnelStore = create4((set) => ({
1408
1530
  }));
1409
1531
 
1410
1532
  // src/stores/settingsStore.ts
1411
- var useSettingsStore = create5((set) => ({
1533
+ var useSettingsStore = create6((set) => ({
1412
1534
  isExpanded: false,
1413
1535
  toggleSidebar: () => {
1414
1536
  set((state) => {
@@ -1430,7 +1552,7 @@ var useSettingsStore = create5((set) => ({
1430
1552
  }));
1431
1553
 
1432
1554
  // src/stores/researchStore.ts
1433
- var useResearchStore = create6((set, get) => ({
1555
+ var useResearchStore = create7((set, get) => ({
1434
1556
  isExpanded: false,
1435
1557
  activeResearchSessionId: null,
1436
1558
  parentSessionId: null,
@@ -1477,7 +1599,7 @@ var useResearchStore = create6((set, get) => ({
1477
1599
  }));
1478
1600
 
1479
1601
  // src/stores/sessionFilesStore.ts
1480
- var useSessionFilesStore = create7((set) => ({
1602
+ var useSessionFilesStore = create8((set) => ({
1481
1603
  isExpanded: false,
1482
1604
  selectedFile: null,
1483
1605
  allOperations: [],
@@ -1515,13 +1637,16 @@ var useSessionFilesStore = create7((set) => ({
1515
1637
  allOperations: [],
1516
1638
  selectedOperationIndex: 0
1517
1639
  }),
1518
- openDiff: (file, operations) => set({
1519
- selectedFile: file,
1520
- allOperations: operations,
1521
- selectedOperationIndex: operations.length - 1,
1522
- isDiffOpen: true,
1523
- isExpanded: true
1524
- }),
1640
+ openDiff: (file, operations) => {
1641
+ useViewerTabsStore.getState().openSessionFileDiffTab(file, operations);
1642
+ set({
1643
+ selectedFile: file,
1644
+ allOperations: operations,
1645
+ selectedOperationIndex: operations.length - 1,
1646
+ isDiffOpen: true,
1647
+ isExpanded: true
1648
+ });
1649
+ },
1525
1650
  selectOperation: (index) => set({ selectedOperationIndex: index }),
1526
1651
  closeDiff: () => set({
1527
1652
  isDiffOpen: false,
@@ -1532,7 +1657,7 @@ var useSessionFilesStore = create7((set) => ({
1532
1657
  }));
1533
1658
 
1534
1659
  // src/stores/gitStore.ts
1535
- var useGitStore = create8((set) => ({
1660
+ var useGitStore = create9((set) => ({
1536
1661
  isExpanded: false,
1537
1662
  activeSessionId: null,
1538
1663
  selectedFile: null,
@@ -1558,12 +1683,15 @@ var useGitStore = create8((set) => ({
1558
1683
  },
1559
1684
  expandSidebar: () => set({ isExpanded: true }),
1560
1685
  collapseSidebar: () => set({ isExpanded: false, isDiffOpen: false, selectedFile: null }),
1561
- openDiff: (file, staged) => set({
1562
- selectedFile: file,
1563
- selectedFileStaged: staged,
1564
- isDiffOpen: true,
1565
- isExpanded: true
1566
- }),
1686
+ openDiff: (file, staged) => {
1687
+ useViewerTabsStore.getState().openGitDiffTab(file, staged);
1688
+ set({
1689
+ selectedFile: file,
1690
+ selectedFileStaged: staged,
1691
+ isDiffOpen: true,
1692
+ isExpanded: true
1693
+ });
1694
+ },
1567
1695
  closeDiff: () => set({
1568
1696
  isDiffOpen: false,
1569
1697
  selectedFile: null
@@ -1803,6 +1931,25 @@ function useUpdateSession(sessionId) {
1803
1931
  }
1804
1932
  });
1805
1933
  }
1934
+ function useMarkSessionViewed() {
1935
+ const queryClient = useQueryClient3();
1936
+ return useMutation3({
1937
+ mutationFn: (sessionId) => apiClient.markSessionViewed(sessionId),
1938
+ onSuccess: (updatedSession) => {
1939
+ queryClient.setQueryData(sessionsQueryKey, (old) => {
1940
+ if (!old)
1941
+ return old;
1942
+ return {
1943
+ ...old,
1944
+ pages: old.pages.map((page) => ({
1945
+ ...page,
1946
+ items: page.items.map((session) => session.id === updatedSession.id ? { ...session, ...updatedSession } : session)
1947
+ }))
1948
+ };
1949
+ });
1950
+ }
1951
+ });
1952
+ }
1806
1953
  function useDeleteSession() {
1807
1954
  const queryClient = useQueryClient3();
1808
1955
  return useMutation3({
@@ -1832,7 +1979,12 @@ function useMessages(sessionId, options = {}) {
1832
1979
  function useSendMessage(sessionId) {
1833
1980
  const queryClient = useQueryClient4();
1834
1981
  return useMutation4({
1835
- mutationFn: (data) => apiClient.sendMessage(sessionId, data),
1982
+ mutationFn: async (data) => {
1983
+ await apiClient.markSessionViewed(sessionId).catch(() => {
1984
+ return;
1985
+ });
1986
+ return apiClient.sendMessage(sessionId, data);
1987
+ },
1836
1988
  onSuccess: () => {
1837
1989
  queryClient.invalidateQueries({ queryKey: ["messages", sessionId] });
1838
1990
  queryClient.invalidateQueries({ queryKey: sessionsQueryKey });
@@ -1956,8 +2108,8 @@ class SSEClient {
1956
2108
  }
1957
2109
 
1958
2110
  // src/stores/toolApprovalStore.ts
1959
- import { create as create9 } from "zustand";
1960
- var useToolApprovalStore = create9((set) => ({
2111
+ import { create as create10 } from "zustand";
2112
+ var useToolApprovalStore = create10((set) => ({
1961
2113
  pendingApprovals: [],
1962
2114
  addPendingApproval: (approval) => set((state) => ({
1963
2115
  pendingApprovals: [...state.pendingApprovals, approval]
@@ -2717,9 +2869,9 @@ import {
2717
2869
  } from "@ottocode/api";
2718
2870
 
2719
2871
  // src/stores/toastStore.ts
2720
- import { create as create10 } from "zustand";
2872
+ import { create as create11 } from "zustand";
2721
2873
  var toastId = 0;
2722
- var useToastStore = create10((set) => ({
2874
+ var useToastStore = create11((set) => ({
2723
2875
  toasts: [],
2724
2876
  addToast: (toast) => {
2725
2877
  const id = `toast-${++toastId}`;
@@ -3115,8 +3267,8 @@ function useWorkingDirectory() {
3115
3267
  import { useEffect as useEffect5, useCallback as useCallback3 } from "react";
3116
3268
 
3117
3269
  // src/stores/focusStore.ts
3118
- import { create as create11 } from "zustand";
3119
- var useFocusStore = create11((set) => ({
3270
+ import { create as create12 } from "zustand";
3271
+ var useFocusStore = create12((set) => ({
3120
3272
  currentFocus: null,
3121
3273
  sessionIndex: 0,
3122
3274
  gitFileIndex: 0,
@@ -3128,9 +3280,9 @@ var useFocusStore = create11((set) => ({
3128
3280
  }));
3129
3281
 
3130
3282
  // src/stores/sidebarStore.ts
3131
- import { create as create12 } from "zustand";
3283
+ import { create as create13 } from "zustand";
3132
3284
  import { persist } from "zustand/middleware";
3133
- var useSidebarStore = create12()(persist((set) => ({
3285
+ var useSidebarStore = create13()(persist((set) => ({
3134
3286
  isCollapsed: false,
3135
3287
  toggleCollapse: () => set((state) => ({ isCollapsed: !state.isCollapsed })),
3136
3288
  setCollapsed: (collapsed) => set({ isCollapsed: collapsed })
@@ -3139,14 +3291,47 @@ var useSidebarStore = create12()(persist((set) => ({
3139
3291
  }));
3140
3292
 
3141
3293
  // src/stores/filePickerStore.ts
3142
- import { create as create13 } from "zustand";
3143
- var useFilePickerStore = create13((set) => ({
3294
+ import { create as create14 } from "zustand";
3295
+ var useFilePickerStore = create14((set) => ({
3144
3296
  isOpen: false,
3145
3297
  open: () => set({ isOpen: true }),
3146
3298
  close: () => set({ isOpen: false }),
3147
3299
  toggle: () => set((state) => ({ isOpen: !state.isOpen }))
3148
3300
  }));
3149
3301
 
3302
+ // src/stores/terminalStore.ts
3303
+ import { create as create15 } from "zustand";
3304
+ var DEFAULT_HEIGHT = 300;
3305
+ var MIN_HEIGHT = 150;
3306
+ var useTerminalStore = create15((set) => ({
3307
+ isOpen: false,
3308
+ panelHeight: DEFAULT_HEIGHT,
3309
+ activeTabId: null,
3310
+ isMaximized: false,
3311
+ get isExpanded() {
3312
+ return this.isOpen;
3313
+ },
3314
+ get selectedTerminalId() {
3315
+ return this.activeTabId;
3316
+ },
3317
+ openPanel: () => set({ isOpen: true }),
3318
+ closePanel: () => set({ isOpen: false, isMaximized: false }),
3319
+ togglePanel: () => set((s) => ({
3320
+ isOpen: !s.isOpen,
3321
+ isMaximized: !s.isOpen ? s.isMaximized : false
3322
+ })),
3323
+ setPanelHeight: (height) => set({ panelHeight: Math.max(MIN_HEIGHT, height) }),
3324
+ selectTab: (id) => set({ activeTabId: id, isOpen: true }),
3325
+ toggleMaximize: () => set((s) => ({ isMaximized: !s.isMaximized })),
3326
+ expandSidebar: () => set({ isOpen: true }),
3327
+ collapseSidebar: () => set({ isOpen: false, activeTabId: null, isMaximized: false }),
3328
+ toggleSidebar: () => set((s) => ({
3329
+ isOpen: !s.isOpen,
3330
+ isMaximized: !s.isOpen ? s.isMaximized : false
3331
+ })),
3332
+ selectTerminal: (id) => set({ activeTabId: id, isOpen: true })
3333
+ }));
3334
+
3150
3335
  // src/hooks/useKeyboardShortcuts.ts
3151
3336
  function useKeyboardShortcuts({
3152
3337
  sessionIds,
@@ -3179,12 +3364,59 @@ function useKeyboardShortcuts({
3179
3364
  } = useSidebarStore();
3180
3365
  const { isExpanded: isGitExpanded, toggleSidebar: toggleGit } = useGitStore();
3181
3366
  const closeDiff = useGitStore((state) => state.closeDiff);
3367
+ const toggleSessionFiles = useSessionFilesStore((state) => state.toggleSidebar);
3368
+ const toggleFileBrowser = useFileBrowserStore((state) => state.toggleSidebar);
3369
+ const toggleTunnel = useTunnelStore((state) => state.toggleSidebar);
3370
+ const toggleMCP = useMCPStore((state) => state.toggleSidebar);
3371
+ const toggleSkills = useSkillsStore((state) => state.toggleSidebar);
3372
+ const toggleSettings = useSettingsStore((state) => state.toggleSidebar);
3182
3373
  const toggleResearch = useResearchStore((state) => state.toggleSidebar);
3374
+ const toggleTerminalPanel = useTerminalStore((state) => state.togglePanel);
3183
3375
  const currentSessionIndex = sessionIds.indexOf(activeSessionId || "");
3184
3376
  const handleKeyDown = useCallback3((e) => {
3185
3377
  const target = e.target;
3186
3378
  const isInInput = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable;
3187
3379
  const isInTerminal = !!target.closest("[data-terminal-viewer]");
3380
+ const isShortcutModifierPressed = e.ctrlKey || e.metaKey;
3381
+ if (isShortcutModifierPressed && !e.shiftKey && !e.altKey && e.key >= "1" && e.key <= "7") {
3382
+ e.preventDefault();
3383
+ switch (e.key) {
3384
+ case "1":
3385
+ toggleGit();
3386
+ if (isGitExpanded && currentFocus === "git") {
3387
+ setFocus("input");
3388
+ } else {
3389
+ setFocus("git");
3390
+ resetGitFileIndex();
3391
+ }
3392
+ break;
3393
+ case "2":
3394
+ toggleSessionFiles();
3395
+ setFocus("input");
3396
+ break;
3397
+ case "3":
3398
+ toggleFileBrowser();
3399
+ setFocus("input");
3400
+ break;
3401
+ case "4":
3402
+ toggleTunnel();
3403
+ setFocus("input");
3404
+ break;
3405
+ case "5":
3406
+ toggleMCP();
3407
+ setFocus("input");
3408
+ break;
3409
+ case "6":
3410
+ toggleSkills();
3411
+ setFocus("input");
3412
+ break;
3413
+ case "7":
3414
+ toggleSettings();
3415
+ setFocus("input");
3416
+ break;
3417
+ }
3418
+ return;
3419
+ }
3188
3420
  if ((e.ctrlKey || e.metaKey) && e.key === "h") {
3189
3421
  e.preventDefault();
3190
3422
  if (currentFocus === "sessions") {
@@ -3241,6 +3473,11 @@ function useKeyboardShortcuts({
3241
3473
  toggleGit();
3242
3474
  return;
3243
3475
  }
3476
+ if ((e.ctrlKey || e.metaKey) && e.key === "j") {
3477
+ e.preventDefault();
3478
+ toggleTerminalPanel();
3479
+ return;
3480
+ }
3244
3481
  if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === "r") {
3245
3482
  e.preventDefault();
3246
3483
  toggleResearch();
@@ -3364,6 +3601,13 @@ function useKeyboardShortcuts({
3364
3601
  resetGitFileIndex,
3365
3602
  setSessionListCollapsed,
3366
3603
  toggleGit,
3604
+ toggleSessionFiles,
3605
+ toggleFileBrowser,
3606
+ toggleTunnel,
3607
+ toggleMCP,
3608
+ toggleSkills,
3609
+ toggleSettings,
3610
+ toggleTerminalPanel,
3367
3611
  toggleResearch,
3368
3612
  toggleSessionList,
3369
3613
  onSelectSession,
@@ -3380,8 +3624,8 @@ function useKeyboardShortcuts({
3380
3624
  closeDiff
3381
3625
  ]);
3382
3626
  useEffect5(() => {
3383
- window.addEventListener("keydown", handleKeyDown);
3384
- return () => window.removeEventListener("keydown", handleKeyDown);
3627
+ window.addEventListener("keydown", handleKeyDown, true);
3628
+ return () => window.removeEventListener("keydown", handleKeyDown, true);
3385
3629
  }, [handleKeyDown]);
3386
3630
  return {
3387
3631
  currentFocus,
@@ -3934,9 +4178,18 @@ var defaultQueueState = {
3934
4178
  function useQueueState(sessionId) {
3935
4179
  const { data } = useQuery6({
3936
4180
  queryKey: ["queueState", sessionId],
3937
- queryFn: () => defaultQueueState,
4181
+ queryFn: async () => {
4182
+ if (!sessionId)
4183
+ return defaultQueueState;
4184
+ const queueState = await apiClient.getQueueState(sessionId);
4185
+ return {
4186
+ currentMessageId: queueState.currentMessageId,
4187
+ queuedMessages: queueState.queuedMessages,
4188
+ queueLength: queueState.queuedMessages.length
4189
+ };
4190
+ },
3938
4191
  enabled: !!sessionId,
3939
- initialData: defaultQueueState,
4192
+ placeholderData: defaultQueueState,
3940
4193
  staleTime: Infinity
3941
4194
  });
3942
4195
  return data ?? defaultQueueState;
@@ -4008,8 +4261,8 @@ import {
4008
4261
  } from "@ottocode/api";
4009
4262
 
4010
4263
  // src/stores/pendingResearchStore.ts
4011
- import { create as create14 } from "zustand";
4012
- var usePendingResearchStore = create14((set, get) => ({
4264
+ import { create as create16 } from "zustand";
4265
+ var usePendingResearchStore = create16((set, get) => ({
4013
4266
  pendingContexts: new Map,
4014
4267
  addContext: (parentSessionId, context) => {
4015
4268
  set((state) => {
@@ -4158,8 +4411,8 @@ function useExportToSession() {
4158
4411
  import { useEffect as useEffect8, useRef as useRef3 } from "react";
4159
4412
 
4160
4413
  // src/stores/ottorouterStore.ts
4161
- import { create as create15 } from "zustand";
4162
- var useOttoRouterStore = create15((set) => ({
4414
+ import { create as create17 } from "zustand";
4415
+ var useOttoRouterStore = create17((set) => ({
4163
4416
  balance: null,
4164
4417
  usdcBalance: null,
4165
4418
  network: "mainnet",
@@ -4188,8 +4441,8 @@ var useOttoRouterStore = create15((set) => ({
4188
4441
  }));
4189
4442
 
4190
4443
  // src/stores/topupApprovalStore.ts
4191
- import { create as create16 } from "zustand";
4192
- var useTopupApprovalStore = create16((set) => ({
4444
+ import { create as create18 } from "zustand";
4445
+ var useTopupApprovalStore = create18((set) => ({
4193
4446
  pendingTopup: null,
4194
4447
  isProcessing: false,
4195
4448
  selectedMethod: null,
@@ -4342,8 +4595,8 @@ function useSetuPayments(sessionId) {
4342
4595
  import { useEffect as useEffect9, useCallback as useCallback6 } from "react";
4343
4596
 
4344
4597
  // src/stores/usageStore.ts
4345
- import { create as create17 } from "zustand";
4346
- var useUsageStore = create17((set) => ({
4598
+ import { create as create19 } from "zustand";
4599
+ var useUsageStore = create19((set) => ({
4347
4600
  usage: {},
4348
4601
  isLoading: {},
4349
4602
  lastFetched: {},
@@ -4592,9 +4845,9 @@ import { useEffect as useEffect12, useCallback as useCallback8, useState as useS
4592
4845
  import { useQueryClient as useQueryClient9 } from "@tanstack/react-query";
4593
4846
 
4594
4847
  // src/stores/onboardingStore.ts
4595
- import { create as create18 } from "zustand";
4848
+ import { create as create20 } from "zustand";
4596
4849
  var STEPS = ["wallet", "defaults"];
4597
- var useOnboardingStore = create18((set, get) => ({
4850
+ var useOnboardingStore = create20((set, get) => ({
4598
4851
  isOpen: false,
4599
4852
  currentStep: "wallet",
4600
4853
  manageMode: false,
@@ -5500,6 +5753,7 @@ export {
5500
5753
  useModels,
5501
5754
  useMessages,
5502
5755
  useMessageQueuePosition,
5756
+ useMarkSessionViewed,
5503
5757
  useMCPServers,
5504
5758
  useMCPAuthStatus,
5505
5759
  useKeyboardShortcuts,
@@ -5537,4 +5791,4 @@ export {
5537
5791
  sessionsQueryKey
5538
5792
  };
5539
5793
 
5540
- //# debugId=8234074EBB3B7D1264756E2164756E21
5794
+ //# debugId=26C8EA5B27C5271C64756E2164756E21