@ottocode/web-sdk 0.1.275 → 0.1.277

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 (40) hide show
  1. package/dist/components/chat/ChatInputContainer.d.ts.map +1 -1
  2. package/dist/components/chat/InputQueueBar.d.ts.map +1 -1
  3. package/dist/components/file-browser/FileViewerPanel.d.ts +2 -1
  4. package/dist/components/file-browser/FileViewerPanel.d.ts.map +1 -1
  5. package/dist/components/git/GitDiffViewer.d.ts.map +1 -1
  6. package/dist/components/index.js +1078 -433
  7. package/dist/components/index.js.map +23 -23
  8. package/dist/components/messages/MessagePartItem.d.ts.map +1 -1
  9. package/dist/components/messages/MessageThread.d.ts.map +1 -1
  10. package/dist/components/messages/MessageThreadContainer.d.ts.map +1 -1
  11. package/dist/components/messages/renderers/DiffView.d.ts.map +1 -1
  12. package/dist/components/session-files/SessionFilesDiffPanel.d.ts.map +1 -1
  13. package/dist/components/ui/CodeMirrorViewer.d.ts +2 -1
  14. package/dist/components/ui/CodeMirrorViewer.d.ts.map +1 -1
  15. package/dist/components/ui/Toaster.d.ts.map +1 -1
  16. package/dist/components/workspace/ToolPreviewPanel.d.ts.map +1 -1
  17. package/dist/components/workspace/ViewerTabs.d.ts.map +1 -1
  18. package/dist/hooks/index.js +309 -60
  19. package/dist/hooks/index.js.map +8 -8
  20. package/dist/hooks/useProviderUsage.d.ts +1 -1
  21. package/dist/hooks/useProviderUsage.d.ts.map +1 -1
  22. package/dist/hooks/useQueueState.d.ts +9 -0
  23. package/dist/hooks/useQueueState.d.ts.map +1 -1
  24. package/dist/hooks/useSessionStream.d.ts.map +1 -1
  25. package/dist/index.js +1096 -450
  26. package/dist/index.js.map +23 -23
  27. package/dist/lib/api-client/index.d.ts +13 -0
  28. package/dist/lib/api-client/index.d.ts.map +1 -1
  29. package/dist/lib/api-client/sessions.d.ts +13 -0
  30. package/dist/lib/api-client/sessions.d.ts.map +1 -1
  31. package/dist/lib/commands.d.ts.map +1 -1
  32. package/dist/lib/index.js +25 -1
  33. package/dist/lib/index.js.map +4 -4
  34. package/dist/stores/index.js +77 -16
  35. package/dist/stores/index.js.map +3 -3
  36. package/dist/stores/viewerTabsStore.d.ts +9 -0
  37. package/dist/stores/viewerTabsStore.d.ts.map +1 -1
  38. package/dist/types/api.d.ts +1 -1
  39. package/dist/types/api.d.ts.map +1 -1
  40. package/package.json +5 -3
@@ -1 +1 @@
1
- {"version":3,"file":"MessagePartItem.d.ts","sourceRoot":"","sources":["../../../src/components/messages/MessagePartItem.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAI1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAwInD,UAAU,oBAAoB;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC7C,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,eAAO,MAAM,eAAe,4DAigB3B,CAAC"}
1
+ {"version":3,"file":"MessagePartItem.d.ts","sourceRoot":"","sources":["../../../src/components/messages/MessagePartItem.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAI1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAwInD,UAAU,oBAAoB;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC7C,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,eAAO,MAAM,eAAe,4DAif3B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MessageThread.d.ts","sourceRoot":"","sources":["../../../src/components/messages/MessageThread.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAe,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAmBrE,UAAU,kBAAkB;IAC3B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AA2HD,eAAO,MAAM,aAAa,0DAocxB,CAAC"}
1
+ {"version":3,"file":"MessageThread.d.ts","sourceRoot":"","sources":["../../../src/components/messages/MessageThread.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAe,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAmBrE,UAAU,kBAAkB;IAC3B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AA2HD,eAAO,MAAM,aAAa,0DA0cxB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MessageThreadContainer.d.ts","sourceRoot":"","sources":["../../../src/components/messages/MessageThreadContainer.tsx"],"names":[],"mappings":"AASA,UAAU,2BAA2B;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,eAAO,MAAM,sBAAsB,mEA6CjC,CAAC"}
1
+ {"version":3,"file":"MessageThreadContainer.d.ts","sourceRoot":"","sources":["../../../src/components/messages/MessageThreadContainer.tsx"],"names":[],"mappings":"AAUA,UAAU,2BAA2B;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,eAAO,MAAM,sBAAsB,mEAoDjC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"DiffView.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/renderers/DiffView.tsx"],"names":[],"mappings":"AAMA,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;CACd;AAgKD,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,aAAa,2CAyHhD"}
1
+ {"version":3,"file":"DiffView.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/renderers/DiffView.tsx"],"names":[],"mappings":"AAMA,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;CACd;AA0KD,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,aAAa,2CAyHhD"}
@@ -1 +1 @@
1
- {"version":3,"file":"SessionFilesDiffPanel.d.ts","sourceRoot":"","sources":["../../../src/components/session-files/SessionFilesDiffPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAiH5D,UAAU,0BAA0B;IACnC,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,qBAAqB,kEAsNhC,CAAC"}
1
+ {"version":3,"file":"SessionFilesDiffPanel.d.ts","sourceRoot":"","sources":["../../../src/components/session-files/SessionFilesDiffPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAwH5D,UAAU,0BAA0B;IACnC,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,qBAAqB,kEAsNhC,CAAC"}
@@ -8,7 +8,8 @@ interface CodeMirrorViewerProps {
8
8
  lineTones?: Map<number, CodeMirrorLineTone>;
9
9
  scrollToLine?: number;
10
10
  scrollToEndSignal?: string | number;
11
+ disableMarkdownSyntax?: boolean;
11
12
  }
12
- export declare function CodeMirrorViewer({ content, path, className, highlightedLines, highlightTone, lineTones, scrollToLine, scrollToEndSignal, }: CodeMirrorViewerProps): import("react/jsx-runtime").JSX.Element;
13
+ export declare function CodeMirrorViewer({ content, path, className, highlightedLines, highlightTone, lineTones, scrollToLine, scrollToEndSignal, disableMarkdownSyntax, }: CodeMirrorViewerProps): import("react/jsx-runtime").JSX.Element;
13
14
  export {};
14
15
  //# sourceMappingURL=CodeMirrorViewer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodeMirrorViewer.d.ts","sourceRoot":"","sources":["../../../src/components/ui/CodeMirrorViewer.tsx"],"names":[],"mappings":"AAmCA,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9D,UAAU,qBAAqB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACpC;AAgPD,wBAAgB,gBAAgB,CAAC,EAChC,OAAO,EACP,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,aAAyB,EACzB,SAAS,EACT,YAAY,EACZ,iBAAiB,GACjB,EAAE,qBAAqB,2CAsIvB"}
1
+ {"version":3,"file":"CodeMirrorViewer.d.ts","sourceRoot":"","sources":["../../../src/components/ui/CodeMirrorViewer.tsx"],"names":[],"mappings":"AAmCA,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9D,UAAU,qBAAqB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC;AAoPD,wBAAgB,gBAAgB,CAAC,EAChC,OAAO,EACP,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,aAAyB,EACzB,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,qBAA6B,GAC7B,EAAE,qBAAqB,2CAyIvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Toaster.tsx"],"names":[],"mappings":"AAmKA,wBAAgB,OAAO,4CAYtB"}
1
+ {"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Toaster.tsx"],"names":[],"mappings":"AAsKA,wBAAgB,OAAO,4CAYtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ToolPreviewPanel.d.ts","sourceRoot":"","sources":["../../../src/components/workspace/ToolPreviewPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,SAAS,EAEd,MAAM,8BAA8B,CAAC;AAGtC,UAAU,qBAAqB;IAC9B,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;CAClD;AAOD,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAsVD,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,UAAU,EAAE,MAAM,GAChB,gBAAgB,GAAG,IAAI,CA+FzB;AAmFD,wBAAgB,gBAAgB,CAAC,EAAE,GAAG,EAAE,EAAE,qBAAqB,2CA0P9D"}
1
+ {"version":3,"file":"ToolPreviewPanel.d.ts","sourceRoot":"","sources":["../../../src/components/workspace/ToolPreviewPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,SAAS,EAEd,MAAM,8BAA8B,CAAC;AAGtC,UAAU,qBAAqB;IAC9B,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;CAClD;AAOD,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAujBD,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,UAAU,EAAE,MAAM,GAChB,gBAAgB,GAAG,IAAI,CAsGzB;AAoFD,wBAAgB,gBAAgB,CAAC,EAAE,GAAG,EAAE,EAAE,qBAAqB,2CA0P9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"ViewerTabs.d.ts","sourceRoot":"","sources":["../../../src/components/workspace/ViewerTabs.tsx"],"names":[],"mappings":"AAkOA,eAAO,MAAM,UAAU,8CAkFrB,CAAC"}
1
+ {"version":3,"file":"ViewerTabs.d.ts","sourceRoot":"","sources":["../../../src/components/workspace/ViewerTabs.tsx"],"names":[],"mappings":"AAyVA,eAAO,MAAM,UAAU,8CAkFrB,CAAC"}
@@ -159,6 +159,21 @@ var sessionsMixin = {
159
159
  throw new Error(extractErrorMessage(response.error));
160
160
  return response.data;
161
161
  },
162
+ async createHandoff(sessionId) {
163
+ const response = await fetch(`${getBaseUrl()}/v1/sessions/${encodeURIComponent(sessionId)}/handoff`, { method: "POST" });
164
+ const data = await response.json().catch(() => null);
165
+ if (!response.ok)
166
+ throw new Error(extractErrorMessage(data));
167
+ if (!data?.session || !data?.sessionId) {
168
+ throw new Error("No data returned from handoff");
169
+ }
170
+ return {
171
+ session: convertSession(data.session),
172
+ sessionId: String(data.sessionId),
173
+ sourceSessionId: String(data.sourceSessionId),
174
+ message: String(data.message ?? "")
175
+ };
176
+ },
162
177
  async abortSession(sessionId) {
163
178
  const response = await apiAbortSession({ path: { sessionId } });
164
179
  if (response.error)
@@ -187,6 +202,13 @@ var sessionsMixin = {
187
202
  throw new Error("Failed to remove from queue");
188
203
  return response.data;
189
204
  },
205
+ async sendQueuedMessageNow(sessionId, messageId) {
206
+ const response = await fetch(`${getBaseUrl()}/v1/sessions/${encodeURIComponent(sessionId)}/queue/${encodeURIComponent(messageId)}/send-now`, { method: "POST" });
207
+ const data = await response.json().catch(() => null);
208
+ if (!response.ok)
209
+ throw new Error(extractErrorMessage(data));
210
+ return data;
211
+ },
190
212
  async getMessages(sessionId) {
191
213
  const response = await apiListMessages({ path: { id: sessionId } });
192
214
  if (response.error)
@@ -893,10 +915,12 @@ class ApiClient {
893
915
  updateSession = sessionsMixin.updateSession;
894
916
  markSessionViewed = sessionsMixin.markSessionViewed;
895
917
  deleteSession = sessionsMixin.deleteSession;
918
+ createHandoff = sessionsMixin.createHandoff;
896
919
  abortSession = sessionsMixin.abortSession;
897
920
  abortMessage = sessionsMixin.abortMessage;
898
921
  getQueueState = sessionsMixin.getQueueState;
899
922
  removeFromQueue = sessionsMixin.removeFromQueue;
923
+ sendQueuedMessageNow = sessionsMixin.sendQueuedMessageNow;
900
924
  getMessages = sessionsMixin.getMessages;
901
925
  sendMessage = sessionsMixin.sendMessage;
902
926
  getStreamUrl = sessionsMixin.getStreamUrl;
@@ -1279,6 +1303,53 @@ function mergeChangedLines(existing, incoming) {
1279
1303
  return existing;
1280
1304
  return [...new Set([...existing, ...incoming])].sort((a, b) => a - b);
1281
1305
  }
1306
+ function countContentLines(content) {
1307
+ return content.length === 0 ? 1 : content.split(`
1308
+ `).length;
1309
+ }
1310
+ function annotationId(preview, targetPath) {
1311
+ return `${preview.toolName}:${preview.callId ?? `${normalizeViewerPath(targetPath)}:${preview.patch ?? preview.content ?? ""}`}`;
1312
+ }
1313
+ function buildAnnotation(preview, targetPath, existing) {
1314
+ if (preview.status === "error")
1315
+ return existing;
1316
+ const id = annotationId(preview, targetPath);
1317
+ if (preview.toolName === "write") {
1318
+ const content = preview.content;
1319
+ if (content === undefined)
1320
+ return existing;
1321
+ return {
1322
+ id,
1323
+ reason: "write",
1324
+ callId: preview.callId,
1325
+ status: preview.status,
1326
+ lineTones: Array.from({ length: countContentLines(content) }, (_, index) => [index + 1, "add"]),
1327
+ createdAt: existing?.createdAt ?? Date.now()
1328
+ };
1329
+ }
1330
+ const lineTones = preview.previewLineTones?.length ? preview.previewLineTones : preview.changedLines?.length ? preview.changedLines.map((line) => [line, "add"]) : existing?.lineTones;
1331
+ if (!lineTones?.length)
1332
+ return existing;
1333
+ return {
1334
+ id,
1335
+ reason: "apply_patch",
1336
+ callId: preview.callId,
1337
+ status: preview.status,
1338
+ lineTones,
1339
+ createdAt: existing?.createdAt ?? Date.now()
1340
+ };
1341
+ }
1342
+ function upsertAnnotation(annotations, annotation) {
1343
+ if (!annotation)
1344
+ return annotations;
1345
+ const existing = annotations ?? [];
1346
+ const index = existing.findIndex((item) => item.id === annotation.id);
1347
+ if (index === -1)
1348
+ return [...existing, annotation];
1349
+ const next = [...existing];
1350
+ next[index] = annotation;
1351
+ return next;
1352
+ }
1282
1353
  var useViewerTabsStore = create((set) => ({
1283
1354
  tabs: [],
1284
1355
  activeTabId: null,
@@ -1325,7 +1396,11 @@ var useViewerTabsStore = create((set) => ({
1325
1396
  id: targetId,
1326
1397
  type: "file",
1327
1398
  title: existingFile?.title ?? titleFromPath(targetPath),
1328
- path: targetPath
1399
+ path: targetPath,
1400
+ highlight: existingFile?.highlight,
1401
+ annotations: existingFile?.annotations,
1402
+ patchPreview: existingFile?.patchPreview,
1403
+ writePreview: existingFile?.writePreview
1329
1404
  }),
1330
1405
  activeTabId: targetId
1331
1406
  };
@@ -1346,6 +1421,7 @@ var useViewerTabsStore = create((set) => ({
1346
1421
  title: existingFile?.title ?? titleFromPath(targetPath),
1347
1422
  path: targetPath,
1348
1423
  highlight,
1424
+ annotations: existingFile?.annotations,
1349
1425
  patchPreview: undefined,
1350
1426
  writePreview: undefined
1351
1427
  }),
@@ -1367,6 +1443,12 @@ var useViewerTabsStore = create((set) => ({
1367
1443
  const samePatchCall = isSamePatchCall(existingPatchPreview, preview);
1368
1444
  const baseContent = preview.baseContent ?? (samePatchCall ? existingPatchPreview?.baseContent : existingPatchPreview?.resultContent ?? existingPatchPreview?.baseContent);
1369
1445
  const changedLines = samePatchCall ? preview.changedLines ?? existingPatchPreview?.changedLines : mergeChangedLines(existingPatchPreview?.changedLines, preview.changedLines);
1446
+ const annotationPreview = {
1447
+ ...preview,
1448
+ changedLines: preview.changedLines
1449
+ };
1450
+ const existingAnnotation = existingFile?.annotations?.find((annotation2) => annotation2.id === annotationId(annotationPreview, targetPath));
1451
+ const annotations = upsertAnnotation(existingFile?.annotations, buildAnnotation(annotationPreview, targetPath, existingAnnotation));
1370
1452
  return {
1371
1453
  tabs: upsertTab(tabs, {
1372
1454
  id: targetId,
@@ -1374,6 +1456,7 @@ var useViewerTabsStore = create((set) => ({
1374
1456
  title: existingFile?.title ?? titleFromPath(targetPath),
1375
1457
  path: targetPath,
1376
1458
  highlight: undefined,
1459
+ annotations,
1377
1460
  writePreview: undefined,
1378
1461
  patchPreview: {
1379
1462
  path: targetPath,
@@ -1396,10 +1479,13 @@ var useViewerTabsStore = create((set) => ({
1396
1479
  }
1397
1480
  if (existingFile) {
1398
1481
  const existingWritePreview = existingFile.writePreview;
1482
+ const existingAnnotation = existingFile.annotations?.find((annotation2) => annotation2.id === annotationId(preview, targetPath));
1483
+ const annotations = upsertAnnotation(existingFile.annotations, buildAnnotation(preview, targetPath, existingAnnotation));
1399
1484
  return {
1400
1485
  tabs: upsertTab(tabs, {
1401
1486
  ...existingFile,
1402
1487
  highlight: undefined,
1488
+ annotations,
1403
1489
  patchPreview: undefined,
1404
1490
  writePreview: {
1405
1491
  path: targetPath,
@@ -1414,25 +1500,24 @@ var useViewerTabsStore = create((set) => ({
1414
1500
  };
1415
1501
  }
1416
1502
  const existingWrite = existing?.toolName === "write" ? existing : undefined;
1503
+ const annotation = buildAnnotation(preview, preview.path);
1417
1504
  return {
1418
1505
  tabs: upsertTab(tabs, {
1419
1506
  id,
1420
- type: "tool-preview",
1507
+ type: "file",
1421
1508
  title: titleFromPath(preview.path),
1422
1509
  path: preview.path,
1423
- toolName: preview.toolName,
1424
- callId: preview.callId,
1425
- content: preview.content ?? existingWrite?.content,
1426
- baseContent: undefined,
1427
- patch: undefined,
1428
- changedLines: undefined,
1429
- previewContent: undefined,
1430
- resultContent: undefined,
1431
- previewLineTones: undefined,
1432
- previewFirstLine: undefined,
1433
- previewLatestLine: undefined,
1434
- status: preview.status,
1435
- error: preview.error ?? existingWrite?.error
1510
+ highlight: undefined,
1511
+ annotations: annotation ? [annotation] : undefined,
1512
+ patchPreview: undefined,
1513
+ writePreview: {
1514
+ path: preview.path,
1515
+ toolName: "write",
1516
+ callId: preview.callId,
1517
+ content: preview.content ?? existingWrite?.content,
1518
+ status: preview.status,
1519
+ error: preview.error ?? existingWrite?.error
1520
+ }
1436
1521
  }),
1437
1522
  activeTabId: id
1438
1523
  };
@@ -2035,14 +2120,26 @@ import { useQuery as useQuery4 } from "@tanstack/react-query";
2035
2120
  var defaultQueueState = {
2036
2121
  currentMessageId: null,
2037
2122
  queuedMessages: [],
2038
- queueLength: 0
2123
+ queueLength: 0,
2124
+ isRunning: false
2039
2125
  };
2126
+ function normalizeQueueState(state) {
2127
+ const isRunning = state.isRunning ?? Boolean(state.currentMessageId);
2128
+ const currentMessageId = isRunning ? state.currentMessageId : null;
2129
+ const hasActiveTurn = Boolean(currentMessageId);
2130
+ const queuedMessages = hasActiveTurn ? state.queuedMessages : [];
2131
+ return {
2132
+ currentMessageId,
2133
+ queuedMessages,
2134
+ queueLength: queuedMessages.length,
2135
+ isRunning: hasActiveTurn
2136
+ };
2137
+ }
2040
2138
  function optimisticallyQueueMessage(queryClient, sessionId, messageId) {
2041
2139
  queryClient.setQueryData(["queueState", sessionId], (current) => {
2042
2140
  if (!current)
2043
2141
  return current;
2044
- const isBusy = Boolean(current.currentMessageId) || current.queuedMessages.length > 0 || current.queueLength > 0;
2045
- if (!isBusy)
2142
+ if (!current.isRunning || !current.currentMessageId)
2046
2143
  return current;
2047
2144
  if (current.currentMessageId === messageId)
2048
2145
  return current;
@@ -2067,11 +2164,7 @@ function useQueueState(sessionId) {
2067
2164
  if (!sessionId)
2068
2165
  return defaultQueueState;
2069
2166
  const queueState = await apiClient.getQueueState(sessionId);
2070
- return {
2071
- currentMessageId: queueState.currentMessageId,
2072
- queuedMessages: queueState.queuedMessages,
2073
- queueLength: queueState.queuedMessages.length
2074
- };
2167
+ return normalizeQueueState(queueState);
2075
2168
  },
2076
2169
  enabled: !!sessionId,
2077
2170
  placeholderData: defaultQueueState,
@@ -2654,22 +2747,30 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2654
2747
  return;
2655
2748
  let changeLines = 0;
2656
2749
  let stableChangeLength = 0;
2750
+ let lineDirectiveCount = 0;
2657
2751
  for (const line of stablePatch.split(`
2658
2752
  `)) {
2659
2753
  if (line.startsWith("+") && !line.startsWith("+++") || line.startsWith("-") && !line.startsWith("---")) {
2660
2754
  changeLines += 1;
2661
2755
  stableChangeLength += line.length;
2756
+ } else if (/^\*\*\* (?:Delete Lines in|Replace Lines in|Insert Before in|Insert After in): /.test(line) || line.startsWith("*** Lines:") || line.startsWith("*** Line:") || line.startsWith("*** With:")) {
2757
+ lineDirectiveCount += 1;
2662
2758
  }
2663
2759
  }
2664
- return changeLines > 0 ? `${changeLines}:${stableChangeLength}` : undefined;
2760
+ if (changeLines > 0)
2761
+ return `${changeLines}:${stableChangeLength}`;
2762
+ return lineDirectiveCount > 0 ? `lines:${lineDirectiveCount}:${stablePatch.length}` : undefined;
2665
2763
  };
2666
2764
  const extractPathsFromPatch = (patch) => {
2667
2765
  const paths = new Set;
2668
2766
  for (const line of patch.split(`
2669
2767
  `)) {
2670
2768
  const directive = line.match(/^\*\*\* (?:Update|Add|Delete) File: (.+)$/);
2671
- if (directive?.[1]) {
2672
- paths.add(directive[1].trim());
2769
+ const replaceDirective = line.match(/^\*\*\* Replace in: (.+)$/);
2770
+ const lineDirective = line.match(/^\*\*\* (?:Delete Lines in|Replace Lines in|Insert Before in|Insert After in): (.+)$/);
2771
+ const path = directive?.[1] ?? replaceDirective?.[1] ?? lineDirective?.[1];
2772
+ if (path) {
2773
+ paths.add(path.trim());
2673
2774
  continue;
2674
2775
  }
2675
2776
  const unified = line.match(/^\+\+\+ (?:b\/)?(.+)$/);
@@ -2679,6 +2780,47 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2679
2780
  }
2680
2781
  return [...paths];
2681
2782
  };
2783
+ const getExtension = (path) => path.split(".").pop()?.toLowerCase() ?? "";
2784
+ const updateFileContentCache = (path, content) => {
2785
+ queryClient.setQueryData(["files", "read", path], {
2786
+ content,
2787
+ path,
2788
+ extension: getExtension(path),
2789
+ lineCount: content.split(`
2790
+ `).length
2791
+ });
2792
+ };
2793
+ const mergeReadResultIntoFileCache = (path, result, startLine, endLine) => {
2794
+ if (typeof result?.content !== "string")
2795
+ return;
2796
+ const readContent = result.content;
2797
+ if (!startLine || !endLine) {
2798
+ updateFileContentCache(path, readContent);
2799
+ return;
2800
+ }
2801
+ queryClient.setQueryData(["files", "read", path], (current) => {
2802
+ if (!current?.content)
2803
+ return current;
2804
+ const lines = current.content.split(`
2805
+ `);
2806
+ if (lines.at(-1) === "")
2807
+ lines.pop();
2808
+ const readLines = readContent.split(`
2809
+ `);
2810
+ lines.splice(startLine - 1, endLine - startLine + 1, ...readLines);
2811
+ const content = `${lines.join(`
2812
+ `)}
2813
+ `;
2814
+ return {
2815
+ ...current,
2816
+ content,
2817
+ lineCount: typeof result.totalLines === "number" ? result.totalLines : lines.length
2818
+ };
2819
+ });
2820
+ };
2821
+ const invalidateFileContentCache = (path) => {
2822
+ queryClient.invalidateQueries({ queryKey: ["files", "read", path] });
2823
+ };
2682
2824
  const getChangedLinesForPath = (result, path) => {
2683
2825
  const changes = Array.isArray(result?.changes) ? result.changes : [];
2684
2826
  const lines = new Set;
@@ -2708,9 +2850,6 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2708
2850
  return lines.size > 0 ? [...lines] : undefined;
2709
2851
  };
2710
2852
  const handleReadToolActivity = (eventType, payload, delta) => {
2711
- const viewerStore = useViewerTabsStore.getState();
2712
- if (!viewerStore.followToolActivity)
2713
- return;
2714
2853
  const name = getToolEventName(payload);
2715
2854
  if (name !== "read")
2716
2855
  return;
@@ -2723,6 +2862,12 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2723
2862
  const startLine = normalizeLineNumber(args.startLine) ?? normalizeLineNumber(args.start_line) ?? rangeFromResult.startLine;
2724
2863
  const endLine = normalizeLineNumber(args.endLine) ?? normalizeLineNumber(args.end_line) ?? rangeFromResult.endLine ?? startLine;
2725
2864
  const failed = result?.ok === false || eventType === "error";
2865
+ if (eventType === "tool.result" && !failed) {
2866
+ mergeReadResultIntoFileCache(path, result, startLine, endLine);
2867
+ }
2868
+ const viewerStore = useViewerTabsStore.getState();
2869
+ if (!viewerStore.followToolActivity)
2870
+ return;
2726
2871
  viewerStore.openToolReadTab(path, {
2727
2872
  startLine,
2728
2873
  endLine,
@@ -2732,9 +2877,6 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2732
2877
  });
2733
2878
  };
2734
2879
  const handleWriteToolActivity = (eventType, payload, delta) => {
2735
- const viewerStore = useViewerTabsStore.getState();
2736
- if (!viewerStore.followToolActivity)
2737
- return;
2738
2880
  const name = getToolEventName(payload);
2739
2881
  if (name !== "write")
2740
2882
  return;
@@ -2748,6 +2890,15 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2748
2890
  const callId = getToolEventCallId(payload) ?? undefined;
2749
2891
  const status = failed ? "error" : eventType === "tool.result" ? "success" : "streaming";
2750
2892
  const content = status === "streaming" ? getStreamingWritePreviewContent(args, buffer) : getStringArg(args, buffer, "content");
2893
+ if (status === "success") {
2894
+ if (content !== undefined)
2895
+ updateFileContentCache(path, content);
2896
+ else
2897
+ invalidateFileContentCache(path);
2898
+ }
2899
+ const viewerStore = useViewerTabsStore.getState();
2900
+ if (!viewerStore.followToolActivity)
2901
+ return;
2751
2902
  if (status === "streaming" && content !== undefined && content.length >= TOOL_PREVIEW_THROTTLE_MIN_CHARS) {
2752
2903
  const previewKey = callId ?? path;
2753
2904
  const now = Date.now();
@@ -2771,9 +2922,6 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2771
2922
  });
2772
2923
  };
2773
2924
  const handleApplyPatchToolActivity = (eventType, payload, delta) => {
2774
- const viewerStore = useViewerTabsStore.getState();
2775
- if (!viewerStore.followToolActivity)
2776
- return;
2777
2925
  const name = getToolEventName(payload);
2778
2926
  if (name !== "apply_patch")
2779
2927
  return;
@@ -2797,6 +2945,13 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2797
2945
  const patchPaths = extractPathsFromPatch(patch);
2798
2946
  if (patchPaths.length === 0)
2799
2947
  return;
2948
+ if (status === "success") {
2949
+ for (const path of patchPaths)
2950
+ invalidateFileContentCache(path);
2951
+ }
2952
+ const viewerStore = useViewerTabsStore.getState();
2953
+ if (!viewerStore.followToolActivity)
2954
+ return;
2800
2955
  const matchingFileTabs = viewerStore.tabs.filter((tab) => tab.type === "file" && patchPaths.some((path) => patchPathMayReferToTarget(path, tab.path)));
2801
2956
  const activeMatchingFileTab = matchingFileTabs.find((tab) => tab.id === viewerStore.activeTabId);
2802
2957
  const fallbackPath = patchPaths.find(isLikelyCompletePatchPath);
@@ -2902,6 +3057,11 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2902
3057
  const applyMessageDelta = (payload) => {
2903
3058
  const messageId = typeof payload?.messageId === "string" ? payload.messageId : null;
2904
3059
  const partId = typeof payload?.partId === "string" ? payload.partId : null;
3060
+ const payloadType = typeof payload?.type === "string" ? payload.type : undefined;
3061
+ if (payloadType === "error") {
3062
+ upsertErrorPart(payload);
3063
+ return;
3064
+ }
2905
3065
  const delta = typeof payload?.delta === "string" ? payload.delta : null;
2906
3066
  if (!messageId || !partId || delta === null)
2907
3067
  return;
@@ -2952,6 +3112,90 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
2952
3112
  return nextMessages;
2953
3113
  });
2954
3114
  };
3115
+ const toRecord = (value) => {
3116
+ if (value && typeof value === "object" && !Array.isArray(value)) {
3117
+ return value;
3118
+ }
3119
+ return null;
3120
+ };
3121
+ const parseErrorContent = (payload) => {
3122
+ const contentRecord = toRecord(payload.content);
3123
+ if (contentRecord)
3124
+ return contentRecord;
3125
+ if (typeof payload.content === "string") {
3126
+ try {
3127
+ const parsed = JSON.parse(payload.content);
3128
+ const parsedRecord = toRecord(parsed);
3129
+ if (parsedRecord)
3130
+ return parsedRecord;
3131
+ } catch {}
3132
+ }
3133
+ const message = typeof payload.error === "string" ? payload.error : typeof payload.message === "string" ? payload.message : "Assistant run failed";
3134
+ return {
3135
+ message,
3136
+ type: typeof payload.errorType === "string" ? payload.errorType : "error",
3137
+ details: toRecord(payload.details) ?? undefined,
3138
+ isAborted: payload.isAborted === true,
3139
+ autoCompacted: payload.autoCompacted === true
3140
+ };
3141
+ };
3142
+ const upsertErrorPart = (payload) => {
3143
+ const messageId = typeof payload?.messageId === "string" ? payload.messageId : null;
3144
+ if (!payload || !messageId)
3145
+ return;
3146
+ const contentJson = parseErrorContent(payload);
3147
+ const content = JSON.stringify(contentJson);
3148
+ const errorMessage = typeof contentJson.message === "string" ? contentJson.message : typeof payload.error === "string" ? payload.error : "Assistant run failed";
3149
+ const stepIndex = typeof payload.stepIndex === "number" ? payload.stepIndex : null;
3150
+ const partId = typeof payload.partId === "string" ? payload.partId : `error-${messageId}`;
3151
+ queryClient.setQueryData(["messages", sessionId], (oldMessages) => {
3152
+ if (!oldMessages)
3153
+ return oldMessages;
3154
+ const nextMessages = [...oldMessages];
3155
+ const messageIndex = nextMessages.findIndex((message) => message.id === messageId);
3156
+ if (messageIndex === -1)
3157
+ return oldMessages;
3158
+ const targetMessage = nextMessages[messageIndex];
3159
+ const parts = targetMessage.parts ? [...targetMessage.parts] : [];
3160
+ const partIndex = parts.findIndex((part) => part.id === partId);
3161
+ if (partIndex === -1) {
3162
+ const newPart = {
3163
+ id: partId,
3164
+ messageId,
3165
+ index: getOptimisticPartIndex(parts, stepIndex),
3166
+ stepIndex,
3167
+ type: "error",
3168
+ content,
3169
+ contentJson,
3170
+ agent: targetMessage.agent,
3171
+ provider: targetMessage.provider,
3172
+ model: targetMessage.model,
3173
+ startedAt: Date.now(),
3174
+ completedAt: Date.now(),
3175
+ toolName: null,
3176
+ toolCallId: null,
3177
+ toolDurationMs: null
3178
+ };
3179
+ parts.push(newPart);
3180
+ } else {
3181
+ parts[partIndex] = {
3182
+ ...parts[partIndex],
3183
+ content,
3184
+ contentJson,
3185
+ stepIndex: stepIndex ?? parts[partIndex].stepIndex ?? null,
3186
+ completedAt: Date.now()
3187
+ };
3188
+ }
3189
+ nextMessages[messageIndex] = {
3190
+ ...targetMessage,
3191
+ status: "error",
3192
+ completedAt: targetMessage.completedAt ?? Date.now(),
3193
+ error: errorMessage,
3194
+ parts
3195
+ };
3196
+ return nextMessages;
3197
+ });
3198
+ };
2955
3199
  const upsertEphemeralToolCall = (payload) => {
2956
3200
  if (!payload)
2957
3201
  return;
@@ -3381,6 +3625,17 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
3381
3625
  }
3382
3626
  markMessageCompleted(payload);
3383
3627
  clearEphemeralForMessage(id);
3628
+ if (id) {
3629
+ queryClient.setQueryData(["queueState", sessionId], (current) => {
3630
+ if (!current || current.currentMessageId !== id)
3631
+ return current;
3632
+ return normalizeQueueState({
3633
+ currentMessageId: null,
3634
+ queuedMessages: [],
3635
+ isRunning: false
3636
+ });
3637
+ });
3638
+ }
3384
3639
  queryClient.invalidateQueries({ queryKey: ["messages", sessionId] });
3385
3640
  queryClient.invalidateQueries({ queryKey: sessionsQueryKey });
3386
3641
  break;
@@ -3454,22 +3709,7 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
3454
3709
  assistantMessageIdRef.current = null;
3455
3710
  }
3456
3711
  clearEphemeralForMessage(messageId);
3457
- const errorMessage = typeof payload?.error === "string" ? payload.error : typeof payload?.message === "string" ? payload.message : "Assistant run failed";
3458
- queryClient.setQueryData(["messages", sessionId], (oldMessages) => {
3459
- if (!oldMessages)
3460
- return oldMessages;
3461
- const idx = oldMessages.findIndex((m) => m.id === messageId);
3462
- if (idx === -1)
3463
- return oldMessages;
3464
- const next = [...oldMessages];
3465
- next[idx] = {
3466
- ...next[idx],
3467
- status: "error",
3468
- completedAt: next[idx].completedAt ?? Date.now(),
3469
- error: errorMessage
3470
- };
3471
- return next;
3472
- });
3712
+ upsertErrorPart(payload);
3473
3713
  }
3474
3714
  queryClient.invalidateQueries({ queryKey: ["messages", sessionId] });
3475
3715
  break;
@@ -3504,11 +3744,11 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
3504
3744
  break;
3505
3745
  }
3506
3746
  case "queue.updated": {
3507
- const queueState = {
3747
+ const queueState = normalizeQueueState({
3508
3748
  currentMessageId: payload?.currentMessageId,
3509
3749
  queuedMessages: payload?.queuedMessages ?? [],
3510
- queueLength: payload?.queueLength ?? 0
3511
- };
3750
+ isRunning: typeof payload?.isRunning === "boolean" ? payload.isRunning : undefined
3751
+ });
3512
3752
  queryClient.setQueryData(["queueState", sessionId], queueState);
3513
3753
  break;
3514
3754
  }
@@ -5986,21 +6226,23 @@ function useTunnelStream() {
5986
6226
  // src/hooks/useProviderUsage.ts
5987
6227
  import { useEffect as useEffect14, useCallback as useCallback10, useRef as useRef7 } from "react";
5988
6228
  var POLL_INTERVAL = 60000;
5989
- var STALE_THRESHOLD = 30000;
6229
+ var STALE_THRESHOLD = 60000;
5990
6230
  var inflight = new Set;
5991
6231
  function useProviderUsage(provider, authType) {
5992
6232
  const setUsage = useUsageStore((s) => s.setUsage);
5993
6233
  const setLoading = useUsageStore((s) => s.setLoading);
5994
6234
  const setLastFetched = useUsageStore((s) => s.setLastFetched);
6235
+ const isModalOpen = useUsageStore((s) => s.isModalOpen);
6236
+ const modalProvider = useUsageStore((s) => s.modalProvider);
5995
6237
  const usage = useUsageStore((s) => provider ? s.usage[provider] : undefined);
5996
6238
  const isOAuthProvider = authType === "oauth" && (provider === "anthropic" || provider === "openai");
5997
- const fetchUsage = useCallback10(async () => {
6239
+ const fetchUsage = useCallback10(async (force = false) => {
5998
6240
  if (!provider || !isOAuthProvider)
5999
6241
  return;
6000
6242
  if (inflight.has(provider))
6001
6243
  return;
6002
6244
  const last = useUsageStore.getState().lastFetched[provider] ?? 0;
6003
- if (last && Date.now() - last < STALE_THRESHOLD)
6245
+ if (!force && last && Date.now() - last < STALE_THRESHOLD)
6004
6246
  return;
6005
6247
  inflight.add(provider);
6006
6248
  setLoading(provider, true);
@@ -6019,9 +6261,15 @@ function useProviderUsage(provider, authType) {
6019
6261
  if (!provider || !isOAuthProvider)
6020
6262
  return;
6021
6263
  fetchRef.current();
6264
+ }, [isOAuthProvider, provider]);
6265
+ useEffect14(() => {
6266
+ if (!provider || !isOAuthProvider || !isModalOpen || modalProvider !== provider) {
6267
+ return;
6268
+ }
6269
+ fetchRef.current(true);
6022
6270
  const interval = setInterval(() => fetchRef.current(), POLL_INTERVAL);
6023
6271
  return () => clearInterval(interval);
6024
- }, [isOAuthProvider, provider]);
6272
+ }, [isModalOpen, isOAuthProvider, modalProvider, provider]);
6025
6273
  return {
6026
6274
  usage,
6027
6275
  fetchUsage,
@@ -6436,7 +6684,8 @@ export {
6436
6684
  useAddRemote,
6437
6685
  useAddMCPServer,
6438
6686
  sessionsQueryKey,
6439
- optimisticallyQueueMessage
6687
+ optimisticallyQueueMessage,
6688
+ normalizeQueueState
6440
6689
  };
6441
6690
 
6442
- //# debugId=90296322954CBDC864756E2164756E21
6691
+ //# debugId=E601ECB09FFF57FC64756E2164756E21