@openchambery/web 1.19.7-beta.2 → 1.19.7-beta.21

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 (187) hide show
  1. package/dist/assets/AgentAvatar-DI2zs2WH.js +1 -0
  2. package/dist/assets/AssistantView-sV1PVQiM.js +2 -0
  3. package/dist/assets/DiagramView-D2hqP5VV.js +1 -0
  4. package/dist/assets/FadeInOnReveal-BWJcUp5P.js +1 -0
  5. package/dist/assets/Icon-4My8YZwt.js +1 -0
  6. package/dist/assets/MarkdownLoadingSkeleton-Vezjvk9B.js +3 -0
  7. package/dist/assets/MarkdownRenderer-x091Z--3.js +2 -0
  8. package/dist/assets/MarkdownRendererImpl-DML8BSro.js +7 -0
  9. package/dist/assets/MarkstreamRendererImpl-BK-HM2k3.js +1 -0
  10. package/dist/assets/{MarkstreamRendererImpl-CR0fBG5w.css → MarkstreamRendererImpl-Ca7RATbs.css} +1 -1
  11. package/dist/assets/MobileDetailNavigation-DcxkWiks.js +1 -0
  12. package/dist/assets/MobileShareBridge-TAGcOiyb.js +4 -0
  13. package/dist/assets/MobileSurface-zqlZzEFQ.js +2 -0
  14. package/dist/assets/{MultiRunWindow-khpnWyZO.js → MultiRunWindow-iH1d9S14.js} +1 -1
  15. package/dist/assets/OnboardingScreen-BNEtPmvw.js +1 -0
  16. package/dist/assets/OverlayScrollbar-BZB21Yp_.js +2 -0
  17. package/dist/assets/SettingsView-CzW23DZA.js +25 -0
  18. package/dist/assets/{SettingsWindow-Dx5rU9v5.js → SettingsWindow-DZXCWZid.js} +1 -1
  19. package/dist/assets/TerminalView-pU0wpD8s.js +8 -0
  20. package/dist/assets/ToolOutputDialog-Bt7JChFG.js +10 -0
  21. package/dist/assets/appThemeRegistry-BI7WR2Wo.js +1 -0
  22. package/dist/assets/{button-z0GOBtWi.js → button-Or0daT9o.js} +1 -1
  23. package/dist/assets/clipboard-BXxLshVq.js +1 -0
  24. package/dist/assets/{collapsible-D9zJRpeB.js → collapsible-C-kzSGkq.js} +1 -1
  25. package/dist/assets/context-menu-Dpjla5p4.js +1 -0
  26. package/dist/assets/desktopHosts-BzSE0sK7.js +1 -0
  27. package/dist/assets/desktopRelayRestore-BaKjk1kQ.js +1 -0
  28. package/dist/assets/{diagram-CoEqmReY.js → diagram-D0mT3mo1.js} +1 -1
  29. package/dist/assets/{dialog-HCE4eLUW.js → dialog-BkhHBTd4.js} +1 -1
  30. package/dist/assets/dropdown-menu.styles-Bzo6L3FH.js +1 -0
  31. package/dist/assets/{es-D9KcV5TX.js → es-BHqnSjoZ.js} +1 -1
  32. package/dist/assets/fileQueries-DFY6Kiy1.js +1 -0
  33. package/dist/assets/fileReferenceActions-Di_DoDex.js +1 -0
  34. package/dist/assets/{fr-DPA9qUl3.js → fr-BfrlJY9i.js} +1 -1
  35. package/dist/assets/{gitApi-DNTMAa3F.js → gitApi-CeFszLvk.js} +3 -3
  36. package/dist/assets/{input-BG3VWTIF.js → input-BUsGnzwe.js} +1 -1
  37. package/dist/assets/insertionBoundaries-DDJNusn2.js +4 -0
  38. package/dist/assets/{ja-Dsif3NoD.js → ja-DP-7qt-x.js} +1 -1
  39. package/dist/assets/{ko-Dixx4Ctg.js → ko-E2B5vGQP.js} +1 -1
  40. package/dist/assets/main-CjnOsKDL.js +169 -0
  41. package/dist/assets/main-j-Ij13jc.js +2 -0
  42. package/dist/assets/markdown-worker-BuveaH3O.js +1 -0
  43. package/dist/assets/markdownTheme-CVS01wHf.js +2 -0
  44. package/dist/assets/miniChat-DgxavREE.js +2 -0
  45. package/dist/assets/mobile-C0rwPMPM.js +2 -0
  46. package/dist/assets/multirun-ot7-bKg7.js +4 -0
  47. package/dist/assets/outsideFileGrants-BB4GPvCq.js +1 -0
  48. package/dist/assets/path-utils-jGozTg9d.js +1 -0
  49. package/dist/assets/persistence-CSZp1CNB.js +3 -0
  50. package/dist/assets/{pl-Bj78ZGgf.js → pl-r8X5gRM5.js} +1 -1
  51. package/dist/assets/platform-CenlWqxu.js +2 -0
  52. package/dist/assets/projectMeta-3yOEc0oI.js +3 -0
  53. package/dist/assets/{pt-BR-CFL3xSAf.js → pt-BR-DcpdXCf5.js} +1 -1
  54. package/dist/assets/renderElectronMiniChatApp-BPNvFA_N.js +2 -0
  55. package/dist/assets/renderMobileApp-CNog29Xy.js +28 -0
  56. package/dist/assets/runtimeConfig-D28kNEYO.js +2 -0
  57. package/dist/assets/runtimeEndpointReset-CorvFIRk.js +147 -0
  58. package/dist/assets/sessionChangeSummary-CX2MJIkc.js +1 -0
  59. package/dist/assets/sessionLookup-CbatbQf7.js +1 -0
  60. package/dist/assets/sortable-tabs-strip-C5gGnikj.js +1 -0
  61. package/dist/assets/src-Af9cMFKF.css +2 -0
  62. package/dist/assets/{store-DzpbXWX1.js → store-BDFdnk6l.js} +2 -2
  63. package/dist/assets/terminalApi-CIIs9vFx.js +1 -0
  64. package/dist/assets/textarea-CIO34TZz.js +1 -0
  65. package/dist/assets/toolHelpers-DEvVP9U0.js +2 -0
  66. package/dist/assets/{tooltip-CtH61mQh.js → tooltip-BSrJYYYc.js} +1 -1
  67. package/dist/assets/{uk-BY60Ub3Z.js → uk-Di0vl9V-.js} +1 -1
  68. package/dist/assets/url-CE_gAfNa.js +1 -0
  69. package/dist/assets/{ChatContainer-CnOrdAgs.js → useAppFontEffects-CDpeZWK4.js} +44 -39
  70. package/dist/assets/useAssistantUIStore-BHacrxe_.js +1 -0
  71. package/dist/assets/useDesktopWindowControlsLayout-D-xPByG0.js +1 -0
  72. package/dist/assets/useEffectiveDirectory-Dp-tez_r.js +1 -0
  73. package/dist/assets/useFontPreferences-BxOHKuVw.js +1 -0
  74. package/dist/assets/useMobileNavigationStore-DE1Pe9A9.js +412 -0
  75. package/dist/assets/useSessionAutoCleanup-jNJ_WC38.js +1 -0
  76. package/dist/assets/useUIStore-CqqO11ZI.js +1 -0
  77. package/dist/assets/useWorkerHighlightedLines-MDnGj3yv.js +7 -0
  78. package/dist/assets/utils-B0mQXN9L.js +1 -0
  79. package/dist/assets/{vendor-markstream-react-CwvbEg9R.js → vendor-markstream-react-C3K8YH0d.js} +4 -4
  80. package/dist/assets/{zh-CN-Cox1LaOW.js → zh-CN-coFCfeQE.js} +1 -1
  81. package/dist/assets/{zh-TW-B6RU0mxa.js → zh-TW-oDRZ1-yb.js} +1 -1
  82. package/dist/index.html +9 -11
  83. package/dist/mini-chat.html +9 -11
  84. package/dist/mobile.html +15 -17
  85. package/package.json +2 -1
  86. package/server/index.js +2 -0
  87. package/server/lib/assistant-delivery-parts.js +3 -1
  88. package/server/lib/assistant-delivery-parts.test.js +11 -0
  89. package/server/lib/assistants/DOCUMENTATION.md +76 -3
  90. package/server/lib/assistants/assign.js +225 -0
  91. package/server/lib/assistants/assign.test.js +118 -0
  92. package/server/lib/assistants/bubbles.js +45 -0
  93. package/server/lib/assistants/bubbles.test.js +36 -0
  94. package/server/lib/assistants/cards.js +148 -0
  95. package/server/lib/assistants/cards.test.js +116 -0
  96. package/server/lib/assistants/contact-store.js +284 -0
  97. package/server/lib/assistants/contact-store.test.js +131 -0
  98. package/server/lib/assistants/contact-tools.js +761 -0
  99. package/server/lib/assistants/contact-tools.test.js +328 -0
  100. package/server/lib/assistants/contracts.js +20 -1
  101. package/server/lib/assistants/harness.js +551 -0
  102. package/server/lib/assistants/harness.test.js +607 -0
  103. package/server/lib/assistants/routes.js +44 -4
  104. package/server/lib/assistants/service.js +930 -17
  105. package/server/lib/assistants/service.test.js +1163 -45
  106. package/server/lib/llm/DOCUMENTATION.md +84 -0
  107. package/server/lib/llm/catalog.js +100 -0
  108. package/server/lib/llm/catalog.test.js +78 -0
  109. package/server/lib/llm/completions.js +151 -0
  110. package/server/lib/llm/completions.test.js +127 -0
  111. package/server/lib/llm/generate.js +570 -0
  112. package/server/lib/llm/generate.test.js +459 -0
  113. package/server/lib/llm/routes.js +47 -0
  114. package/server/lib/llm/temp-directory.js +37 -0
  115. package/server/lib/notifications/APNS.md +23 -17
  116. package/server/lib/notifications/DOCUMENTATION.md +5 -4
  117. package/server/lib/notifications/apns-runtime.js +139 -20
  118. package/server/lib/notifications/apns-runtime.test.js +66 -7
  119. package/server/lib/notifications/apns-titles.js +62 -62
  120. package/server/lib/notifications/apns-titles.test.js +3 -1
  121. package/server/lib/notifications/routes.js +1 -1
  122. package/server/lib/notifications/runtime.js +177 -86
  123. package/server/lib/notifications/runtime.test.js +122 -0
  124. package/server/lib/opencode/feature-routes-runtime.js +30 -0
  125. package/server/lib/opencode/feature-routes-runtime.test.js +20 -0
  126. package/server/lib/opencode/settings-runtime.js +18 -2
  127. package/server/lib/session-goal/DOCUMENTATION.md +8 -1
  128. package/server/lib/session-goal/runtime.js +20 -0
  129. package/server/lib/session-index/DOCUMENTATION.md +3 -1
  130. package/server/lib/session-index/service.js +10 -4
  131. package/server/lib/session-index/service.test.js +37 -0
  132. package/server/lib/session-title/runtime.js +1 -0
  133. package/server/lib/session-title/runtime.test.js +11 -0
  134. package/dist/assets/AgentAvatar-ziUs4sw3.js +0 -1
  135. package/dist/assets/AssistantView-DF4yXFgS.js +0 -1
  136. package/dist/assets/ContextPanel-Cg_uCHzJ.js +0 -285
  137. package/dist/assets/DiagramView-DYh3Zn2y.js +0 -1
  138. package/dist/assets/FadeInOnReveal-BAlsRFJH.js +0 -1
  139. package/dist/assets/Icon-CLpn1mIz.js +0 -1
  140. package/dist/assets/MarkdownRendererImpl-QzUEpBEm.js +0 -7
  141. package/dist/assets/MarkstreamRendererImpl-CXrfeUia.js +0 -1
  142. package/dist/assets/MobileDetailNavigation-DJXEYfq4.js +0 -1
  143. package/dist/assets/MobileShareBridge-CliVo1YH.js +0 -4
  144. package/dist/assets/MobileSurface-9Xh6WQkY.js +0 -2
  145. package/dist/assets/OnboardingScreen-CJYyR54B.js +0 -1
  146. package/dist/assets/OverlayScrollbar-C-jZ8ITG.js +0 -2
  147. package/dist/assets/SettingsView-DyCZehFG.js +0 -25
  148. package/dist/assets/TerminalView-XSALfUaH.js +0 -8
  149. package/dist/assets/ToolOutputDialog-BfuXazW9.js +0 -10
  150. package/dist/assets/appThemeRegistry-DDWrniMM.js +0 -2
  151. package/dist/assets/clipboard-Bz0Zm9VJ.js +0 -1
  152. package/dist/assets/desktop-CfLlmafK.js +0 -1
  153. package/dist/assets/desktopHosts-C1Ns3DUu.js +0 -1
  154. package/dist/assets/desktopRelayRestore-LBt0CBOj.js +0 -1
  155. package/dist/assets/fileQueries-Dnn15WsA.js +0 -1
  156. package/dist/assets/insertionBoundaries-DMxuUnL_.js +0 -4
  157. package/dist/assets/main-B9HVtgXE.js +0 -2
  158. package/dist/assets/main-ZNyIs3Sn.js +0 -29
  159. package/dist/assets/markdown-worker-y3ewaqAK.js +0 -4
  160. package/dist/assets/markdownTheme-TdhQOZSN.js +0 -2
  161. package/dist/assets/miniChat-q0T0WGkZ.js +0 -2
  162. package/dist/assets/mobile-DEduvLJj.js +0 -2
  163. package/dist/assets/multirun-DU-wrxlG.js +0 -4
  164. package/dist/assets/persistence-CmjKImz2.js +0 -3
  165. package/dist/assets/platform-skqcMARt.js +0 -2
  166. package/dist/assets/projectMeta-DNWx6Uva.js +0 -3
  167. package/dist/assets/radio-BEonIX1k.js +0 -1
  168. package/dist/assets/renderElectronMiniChatApp--JYWY41L.js +0 -2
  169. package/dist/assets/renderMobileApp-B0Ix_uNo.js +0 -25
  170. package/dist/assets/runtime-switch-BkpTTbEi.js +0 -1
  171. package/dist/assets/runtimeConfig-BTDIG7mX.js +0 -2
  172. package/dist/assets/runtimeEndpointReset-CZQCYtVI.js +0 -4
  173. package/dist/assets/shikiHighlight-C9Cx56Qg.js +0 -1
  174. package/dist/assets/sortable-tabs-strip-Bj8N0VWf.js +0 -1
  175. package/dist/assets/src-2eFAiBLq.css +0 -2
  176. package/dist/assets/terminalApi-CNqqwjfG.js +0 -1
  177. package/dist/assets/url-KeihbE0d.js +0 -1
  178. package/dist/assets/useAppFontEffects-CKLSamae.js +0 -7
  179. package/dist/assets/useAssistantUIStore-DaplPyb0.js +0 -1
  180. package/dist/assets/useDesktopWindowControlsLayout-DJSkFfhT.js +0 -1
  181. package/dist/assets/useEffectiveDirectory-B3rbY1Kv.js +0 -1
  182. package/dist/assets/useFontPreferences-D8emhcNv.js +0 -1
  183. package/dist/assets/useMobileNavigationStore-CAvVUItx.js +0 -412
  184. package/dist/assets/useSessionAutoCleanup-DxNgqJ8s.js +0 -1
  185. package/dist/assets/useUIStore-B7KJS5G7.js +0 -1
  186. package/dist/assets/useWorkerHighlightedLines-DiDF68LR.js +0 -7
  187. package/dist/assets/utils-CTL16t2f.js +0 -1
@@ -1,6 +1,13 @@
1
1
  import { createProjectIdFromPath } from '../projects/project-id.js';
2
2
 
3
3
  const DEFAULT_NOTIFICATION_TEMPLATES = {
4
+ completion: { title: 'Task completed', message: '{session_name}' },
5
+ error: { title: 'Something went wrong', message: '{session_name}' },
6
+ question: { title: 'Needs your answer', message: '{session_name}' },
7
+ subtask: { title: 'Task completed', message: '{session_name}' },
8
+ };
9
+
10
+ const LEGACY_NOTIFICATION_TEMPLATES = {
4
11
  completion: { title: '{agent_name} is ready', message: '{model_name} completed the task' },
5
12
  error: { title: 'Tool error', message: '{last_message}' },
6
13
  question: { title: 'Input needed', message: '{last_message}' },
@@ -20,6 +27,15 @@ const ensureNotificationTemplateShape = (templates) => {
20
27
  if (!currentEntry || typeof currentEntry.title !== 'string' || typeof currentEntry.message !== 'string') {
21
28
  changed = true;
22
29
  }
30
+ const legacy = LEGACY_NOTIFICATION_TEMPLATES[event];
31
+ const isLegacyDefault = legacy
32
+ && currentTitle === legacy.title
33
+ && currentMessage === legacy.message;
34
+ if (isLegacyDefault) {
35
+ changed = true;
36
+ next[event] = { title: base.title, message: base.message };
37
+ continue;
38
+ }
23
39
  next[event] = { title: currentTitle, message: currentMessage };
24
40
  }
25
41
 
@@ -650,8 +666,8 @@ export const createSettingsRuntime = (deps) => {
650
666
  return { settings, changed: false };
651
667
  }
652
668
 
653
- const defaultLight = 'flexoki-light';
654
- const defaultDark = 'flexoki-dark';
669
+ const defaultLight = 'carbonfox-light';
670
+ const defaultDark = 'vitesse-dark-dark';
655
671
 
656
672
  let nextLightThemeId = hasLight ? settings.lightThemeId : undefined;
657
673
  let nextDarkThemeId = hasDark ? settings.darkThemeId : undefined;
@@ -135,7 +135,10 @@ before touching the filesystem). Rationale: metadata rides every
135
135
  continuation prompt using the last assistant message's
136
136
  provider/model/agent — the goal spends the session's own subscription.
137
137
  4. Settling (`complete`/`blocked`/`budgetLimited`) fires the injected
138
- `emitGoalNotification` so the user hears about it even with the UI closed:
138
+ `emitGoalNotification` so the user hears about it even with the UI closed.
139
+ The same settle also notifies a registered Assistant contact reporter
140
+ (`setAssignedSessionSettleHandler`) so an assigned/watched session updates
141
+ its contact card — read-only, no second scheduler:
139
142
  desktop + UI broadcast + the standard push fanout (web-push with full
140
143
  text; APNs with a generic per-type title and the session name as body).
141
144
  It obeys the notify-on-completion setting. Conversely, while a goal is
@@ -180,6 +183,10 @@ The loop here picks it up from session events like any other goal.
180
183
 
181
184
  ## Limitations
182
185
 
186
+ - TODO(watch): Assistant contact assign skipped a watch tool this slice.
187
+ Goal settle already notifies. Do not invent a second scheduler. A later
188
+ thin contact tool can post a read-only session status card when
189
+ `metadata.openchamber.goal` settles.
183
190
  - Web-server feature: VS Code (extension-only) renders goal state via
184
191
  `session.updated` but does not run the loop.
185
192
  - A goal on a session with no assistant reply yet starts after the first
@@ -286,6 +286,18 @@ export const accountGoalTokenSpend = ({ messages, goal }) => {
286
286
  return { tokensUsed, lastAccountedMessageID };
287
287
  };
288
288
 
289
+ let assignedSessionSettle = null;
290
+
291
+ export const setAssignedSessionSettleHandler = (handler) => {
292
+ assignedSessionSettle = typeof handler === 'function' ? handler : null;
293
+ };
294
+
295
+ const contactStatusFromGoal = (status) => {
296
+ if (status === 'complete' || status === 'budgetLimited') return 'complete';
297
+ if (status === 'blocked') return 'error';
298
+ return null;
299
+ };
300
+
289
301
  export const createSessionGoalRuntime = ({
290
302
  buildOpenCodeUrl,
291
303
  getOpenCodeAuthHeaders,
@@ -401,6 +413,14 @@ export const createSessionGoalRuntime = ({
401
413
  console.warn('[session-goal] notification failed:', error?.message || error);
402
414
  }
403
415
  }
416
+ const contactStatus = contactStatusFromGoal(status);
417
+ if (contactStatus && typeof assignedSessionSettle === 'function') {
418
+ try {
419
+ assignedSessionSettle({ sessionId, directory, status: contactStatus });
420
+ } catch (error) {
421
+ console.warn('[session-goal] assigned session settle failed:', error?.message || error);
422
+ }
423
+ }
404
424
  };
405
425
 
406
426
  const runAudit = async ({ goal, assistantText, directory, lastAssistantInfo }) => {
@@ -15,7 +15,9 @@ Sessions titled `smartfetch-secondary` are temporary SmartFetch model calls;
15
15
  the index excludes them from every snapshot and clears prior summaries when a
16
16
  matching session update arrives. System-owned sessions are excluded by
17
17
  authoritative metadata only: a non-empty
18
- `metadata.openchamber.assistant.assistantID`,
18
+ `metadata.openchamber.assistant.assistantID` (unless
19
+ `metadata.openchamber.assigned.from === 'contact'` — those are visible
20
+ coding workers the Assistant subscribed to),
19
21
  `metadata.openchamber.scheduledTask.taskID`, or
20
22
  `metadata.openchamber.smallModel.purpose`. Title prefixes are human labels and
21
23
  never participate in this filter. Metadata is the ownership/isolation signal;
@@ -10,10 +10,14 @@ const HIDDEN_SESSION_TITLES = new Set(['smartfetch-secondary']);
10
10
  const nonEmptySystemID = (value) => typeof value === 'string' && value.length > 0;
11
11
 
12
12
  /** System sessions are isolated by authoritative metadata only — never by title prefix. */
13
+ const isContactAssignedSession = (openchamber) => openchamber?.assigned?.from === 'contact';
14
+
13
15
  const isSystemSession = (session) => {
14
16
  const openchamber = session?.metadata?.openchamber;
15
17
  if (!openchamber || typeof openchamber !== 'object') return false;
16
- if (nonEmptySystemID(openchamber.assistant?.assistantID)) return true;
18
+ // Contact-assigned workers stay visible in Chat. Only archived Assistant
19
+ // bindings use `openchamber.assistant` as a hide marker.
20
+ if (nonEmptySystemID(openchamber.assistant?.assistantID) && !isContactAssignedSession(openchamber)) return true;
17
21
  if (nonEmptySystemID(openchamber.scheduledTask?.taskID)) return true;
18
22
  if (nonEmptySystemID(openchamber.smallModel?.purpose)) return true;
19
23
  return false;
@@ -52,7 +56,9 @@ const toSummary = (session, fallbackDirectory) => {
52
56
  if (!session || !isVisibleSession(session) || typeof session.id !== 'string' || !session.id) return null;
53
57
  const directory = normalizeDirectory(session.directory ?? session.project?.worktree ?? fallbackDirectory);
54
58
  if (!directory) return null;
55
- const assistant = session.metadata?.openchamber?.assistant;
59
+ const openchamber = session.metadata?.openchamber;
60
+ const assistant = openchamber?.assistant;
61
+ const hideAssistantMarker = isContactAssignedSession(openchamber);
56
62
  return {
57
63
  id: session.id,
58
64
  directory,
@@ -63,8 +69,8 @@ const toSummary = (session, fallbackDirectory) => {
63
69
  archivedAt: toTimestamp(session.time?.archived),
64
70
  parentID: typeof session.parentID === 'string' ? session.parentID : null,
65
71
  hasChildren: typeof session.hasChildren === 'boolean' ? session.hasChildren : null,
66
- assistantID: typeof assistant?.assistantID === 'string' ? assistant.assistantID : null,
67
- assistantName: typeof assistant?.name === 'string' ? assistant.name : null,
72
+ assistantID: hideAssistantMarker || typeof assistant?.assistantID !== 'string' ? null : assistant.assistantID,
73
+ assistantName: hideAssistantMarker || typeof assistant?.name !== 'string' ? null : assistant.name,
68
74
  };
69
75
  };
70
76
 
@@ -100,6 +100,43 @@ describe('Electron session index', () => {
100
100
  service.close();
101
101
  });
102
102
 
103
+ it('keeps contact-assigned worker sessions visible in ordinary sidebar summaries', () => {
104
+ const runtimeRef = { value: 'http://runtime-a.test' };
105
+ const service = createService(runtimeRef);
106
+ const worker = {
107
+ ...session('ses_worker', 100),
108
+ metadata: {
109
+ openchamber: {
110
+ assigned: { from: 'contact', assistantID: 'assistant_1', name: 'A' },
111
+ },
112
+ },
113
+ };
114
+ const legacyWorker = {
115
+ ...session('ses_legacy_worker', 99),
116
+ metadata: {
117
+ openchamber: {
118
+ assistant: { assistantID: 'assistant_1', name: 'A' },
119
+ assigned: { from: 'contact' },
120
+ },
121
+ },
122
+ };
123
+ const hiddenBinding = {
124
+ ...session('ses_binding', 98),
125
+ metadata: { openchamber: { assistant: { assistantID: 'assistant_1', name: 'A' } } },
126
+ };
127
+ service.replaceDirectory({
128
+ directory: '/repo',
129
+ sessions: [worker, legacyWorker, hiddenBinding],
130
+ cursor: null,
131
+ hasMore: false,
132
+ });
133
+ expect(service.snapshot().directories[0].sessions.map((item) => item.id)).toEqual([
134
+ 'ses_worker',
135
+ 'ses_legacy_worker',
136
+ ]);
137
+ service.close();
138
+ });
139
+
103
140
  it('keeps runtime targets isolated in one Electron database', () => {
104
141
  const runtimeRef = { value: 'http://runtime-a.test' };
105
142
  const service = createService(runtimeRef);
@@ -163,6 +163,7 @@ const extractSessionStatus = (payload) => {
163
163
  export const isSystemOwnedSession = (sessionOrInfo) => {
164
164
  const openchamber = sessionOrInfo?.metadata?.openchamber;
165
165
  if (!openchamber || typeof openchamber !== 'object') return false;
166
+ if (openchamber.assigned?.from === 'contact') return false;
166
167
  if (typeof openchamber.assistant?.assistantID === 'string' && openchamber.assistant.assistantID) return true;
167
168
  if (typeof openchamber.scheduledTask?.taskID === 'string' && openchamber.scheduledTask.taskID) return true;
168
169
  if (typeof openchamber.smallModel?.purpose === 'string' && openchamber.smallModel.purpose) return true;
@@ -243,6 +243,17 @@ describe('session-title helpers', () => {
243
243
  metadata: { openchamber: { smallModel: { purpose: '' } } },
244
244
  })).toBe(false);
245
245
  expect(isSystemOwnedSession({ title: 'Ordinary' })).toBe(false);
246
+ expect(isSystemOwnedSession({
247
+ metadata: { openchamber: { assigned: { from: 'contact', assistantID: 'assistant_1' } } },
248
+ })).toBe(false);
249
+ expect(isSystemOwnedSession({
250
+ metadata: {
251
+ openchamber: {
252
+ assistant: { assistantID: 'assistant_1' },
253
+ assigned: { from: 'contact' },
254
+ },
255
+ },
256
+ })).toBe(false);
246
257
  });
247
258
 
248
259
  it('skips title generation and patch for system-owned sessions', async () => {
@@ -1 +0,0 @@
1
- import"./rolldown-runtime-C0FnF6B9.js";import{nt as e,rt as t}from"./vendor-base-ui-CnHfUmDN.js";import{n}from"./vendor-react-DLPElpoQ.js";import{c as r,l as i}from"./dialog-HCE4eLUW.js";import{t as a}from"./utils-CTL16t2f.js";var o=n();t();var s=e(),c=e=>{let t=(0,o.c)(27),{name:n,emoji:c,size:u,className:d,label:f}=e,p=u===void 0?16:u,m,h,g;if(t[0]!==d||t[1]!==c||t[2]!==n){m=i(n);let e;t[6]===n?e=t[7]:(e=r(n),t[6]=n,t[7]=e),h=e,g=a(`inline-flex aspect-square shrink-0 overflow-hidden rounded-sm`,c&&`items-center justify-center select-none`,m.class,d),t[0]=d,t[1]=c,t[2]=n,t[3]=m,t[4]=h,t[5]=g}else m=t[3],h=t[4],g=t[5];let _=`calc(${p}px * var(--dpt-n, 1))`,v=`calc(${p}px * var(--dpt-n, 1))`,y=`calc(${p}px * var(--dpt-n, 1))`,b=`calc(${p}px * var(--dpt-n, 1))`,x=`calc(${p}px * var(--dpt-n, 1))`,S=`calc(${p}px * var(--dpt-n, 1))`,C=`var(${m.var})`,w;t[8]!==_||t[9]!==v||t[10]!==y||t[11]!==b||t[12]!==x||t[13]!==S||t[14]!==C?(w={width:_,minWidth:v,maxWidth:y,height:b,minHeight:x,maxHeight:S,color:C},t[8]=_,t[9]=v,t[10]=y,t[11]=b,t[12]=x,t[13]=S,t[14]=C,t[15]=w):w=t[15];let T=f?`img`:void 0,E=!f||void 0,D;t[16]!==c||t[17]!==h||t[18]!==p?(D=c?(0,s.jsx)(`span`,{"aria-hidden":`true`,style:{fontSize:`calc(${p*.75}px * var(--dpt-n, 1))`,lineHeight:1},children:c}):(0,s.jsxs)(`svg`,{width:p,height:p,viewBox:`0 0 5 5`,shapeRendering:`crispEdges`,className:`oc-agent-avatar block h-full w-full`,"aria-hidden":`true`,children:[(0,s.jsx)(`rect`,{width:`5`,height:`5`,fill:`currentColor`,opacity:.14}),h.map(l)]}),t[16]=c,t[17]=h,t[18]=p,t[19]=D):D=t[19];let O;return t[20]!==f||t[21]!==w||t[22]!==T||t[23]!==E||t[24]!==D||t[25]!==g?(O=(0,s.jsx)(`span`,{className:g,style:w,role:T,"aria-label":f,"aria-hidden":E,children:D}),t[20]=f,t[21]=w,t[22]=T,t[23]=E,t[24]=D,t[25]=g,t[26]=O):O=t[26],O};function l(e,t){return e.map((e,n)=>e?(0,s.jsx)(`rect`,{x:n,y:t,width:`1`,height:`1`,fill:`currentColor`},`${n}-${t}`):null)}export{c as t};
@@ -1 +0,0 @@
1
- import{o as e,r as t}from"./rolldown-runtime-C0FnF6B9.js";import{c as n,i as r,n as i}from"./runtime-switch-BkpTTbEi.js";import{Ot as a,et as o,rt as s,yt as c}from"./persistence-CmjKImz2.js";import{y as l}from"./desktop-CfLlmafK.js";import{nt as u,rt as d}from"./vendor-base-ui-CnHfUmDN.js";import{r as f}from"./platform-skqcMARt.js";import{t as p}from"./useUIStore-B7KJS5G7.js";import{n as m}from"./vendor-react-DLPElpoQ.js";import{r as h}from"./vendor-sonner-DVzioF3d.js";import{n as g}from"./vendor-reactuses-core-DDoDDyM9.js";import{n as ee}from"./clipboard-Bz0Zm9VJ.js";import{a as _,n as v,s as y}from"./MobileShareBridge-CliVo1YH.js";import{Ga as b,Ha as x,Pi as S,Ur as te,_n as C,aa as w,an as T,hi as E,ho as D,ko as O,mo as k,o as A,qr as j,un as M,vn as N,yn as P}from"./useMobileNavigationStore-CAvVUItx.js";import{_ as F,a as I,c as L,d as R,f as z,g as ne,l as re,n as ie,o as ae,p as B,r as oe,t as V,v as H,x as U,y as se}from"./MobileDetailNavigation-DJXEYfq4.js";import{i as ce,r as le}from"./useAssistantUIStore-DaplPyb0.js";import{a as ue,i as de,n as W,o as G,r as K,t as q}from"./dialog-HCE4eLUW.js";import{t as fe}from"./utils-CTL16t2f.js";import{t as pe}from"./AgentAvatar-ziUs4sw3.js";import{n as me}from"./Icon-CLpn1mIz.js";import{t as he}from"./button-z0GOBtWi.js";import{i as ge}from"./OverlayScrollbar-C-jZ8ITG.js";import{B as _e,F as ve,I as J,Y as ye,t as be,z as xe}from"./ChatContainer-CnOrdAgs.js";import{t as Se}from"./ContextPanel-Cg_uCHzJ.js";import{a as Ce,c as we,l as Te,o as Ee,s as De}from"./shikiHighlight-C9Cx56Qg.js";var Y=e(d(),1),Oe=m(),X=e=>e.isVSCode||e.isPhoneShell||e.isMobile&&!e.isIPad?`session`:`context-panel`,Z=u(),ke=e=>{let t=(0,Oe.c)(56),{assistant:n,sessionID:r,warning:i,surface:a,onRevertMessage:o,onEditMessage:s,pendingUserMessages:c,onPendingUserMessagesMaterialized:u}=e,{t:d}=ee(),{isMobile:m}=ge(),h=n.effectiveWorkspacePath,_;t[0]!==n.sessionGeneration||t[1]!==r?(_={sessionID:r,sessionGeneration:n.sessionGeneration},t[0]=n.sessionGeneration,t[1]=r,t[2]=_):_=t[2];let v=H(n.id,_,a.active);v.data?.pages;let y;t[3]===v.data?.pages?y=t[4]:(y=v.data?.pages??[],t[3]=v.data?.pages,t[4]=y);let b;t[5]===y?b=t[6]:(b=E(y),t[5]=y,t[6]=b);let x=b,S;if(t[7]!==x){S=new Map;for(let e of x){let t=S.get(e.sessionID);S.set(e.sessionID,t===void 0||t===e.directory?e.directory:null)}t[7]=x,t[8]=S}else S=t[8];let te=S,C;t[9]===v?C=t[10]:(C=async()=>{(v.hasNextPage||v.isFetchNextPageError)&&await v.fetchNextPage()},t[9]=v,t[10]=C);let w=g(C),T=n.mode===`continuous`,D=ve(),O;t[11]===D?O=t[12]:(O=D&&!f(),t[11]=D,t[12]=O);let k=!!O,A;t[13]===k?A=t[14]:(A=(e,t)=>{P(e,t,{phoneShell:k,switchToChat:!0})},t[13]=k,t[14]=A);let j=g(A),M;t[15]!==h||t[16]!==te||t[17]!==j||t[18]!==r?(M=(e,t)=>{let n=e===r?h:te.get(e);if(!n||n!==t){N(e,`missing-directory`);return}j(e,t)},t[15]=h,t[16]=te,t[17]=j,t[18]=r,t[19]=M):M=t[19];let F=g(M),I;t[20]!==m||t[21]!==k||t[22]!==j||t[23]!==d?(I=(e,t)=>{let n=e.trim(),r=t.trim();if(!n){N(e,`missing-session-id`);return}if(!r){N(n,`missing-directory`);return}if(X({isPhoneShell:k,isMobile:m,isIPad:f(),isVSCode:l()})===`session`){j(n,r);return}p.getState().openContextPanelTab(r,{mode:`chat`,dedupeKey:`session:${n}`,label:d(`contextPanel.mode.chat`),readOnly:!0})},t[20]=m,t[21]=k,t[22]=j,t[23]=d,t[24]=I):I=t[24];let L=g(I),R;t[25]===T?R=t[26]:(R={...J,forkSession:!1,mutateSession:T},t[25]=T,t[26]=R);let z;t[27]===s?z=t[28]:(z=s?{onEditMessage:s}:{},t[27]=s,t[28]=z);let ne;t[29]!==h||t[30]!==L||t[31]!==o||t[32]!==F||t[33]!==r||t[34]!==a.active||t[35]!==a.surfaceID||t[36]!==z||t[37]!==R?(ne={kind:`embedded`,surfaceId:a.surfaceID,sessionId:r,directory:h,active:a.active,capabilities:R,navigateSession:L,onRevertMessage:o,...z,openSourceSession:F},t[29]=h,t[30]=L,t[31]=o,t[32]=F,t[33]=r,t[34]=a.active,t[35]=a.surfaceID,t[36]=z,t[37]=R,t[38]=ne):ne=t[38];let re=ne,ie=v.isError||v.isSuccess&&!v.hasNextPage,ae=v.isLoading||v.isFetchingNextPage,B;t[39]!==w||t[40]!==ie||t[41]!==x||t[42]!==ae?(B={entries:x,complete:ie,loading:ae,fetchPrevious:w},t[39]=w,t[40]=ie,t[41]=x,t[42]=ae,t[43]=B):B=t[43];let oe;t[44]!==h||t[45]!==u||t[46]!==o||t[47]!==c||t[48]!==r||t[49]!==re||t[50]!==a||t[51]!==B||t[52]!==i?(oe={sessionId:r,directory:h,composerSurface:a,sessionSurface:re,warning:i,pendingUserMessages:c,onPendingUserMessagesMaterialized:u,assistantHistory:B,onRevertMessage:o},t[44]=h,t[45]=u,t[46]=o,t[47]=c,t[48]=r,t[49]=re,t[50]=a,t[51]=B,t[52]=i,t[53]=oe):oe=t[53];let V=oe,U;return t[54]===V?U=t[55]:(U=(0,Z.jsx)(be,{autoOpenDraft:!1,host:V}),t[54]=V,t[55]=U),U},Ae=class extends Error{constructor(){super(`assistant_selection_stale`)}},Q=(e,t)=>e.assistantID===t.assistantID&&e.transportIdentity===t.transportIdentity&&e.runtimeGeneration===t.runtimeGeneration,je=class{onBusyChange;onError;flight=null;authoritativeIdentity=null;constructor(e,t){this.onBusyChange=e,this.onError=t}activate(e){this.authoritativeIdentity&&!Q(this.authoritativeIdentity,e)&&this.flight&&this.retire(this.flight),this.authoritativeIdentity=e}enqueue(e,t,n){if(!this.isAuthoritative(e))return Promise.reject(new Ae);let r=this.flight;r||(r={identity:e,controller:new AbortController,running:!1,desired:null,waiters:[],activeWaiters:[],idleWaiters:[],retired:!1},this.flight=r),r.desired=t;let i=new Promise((e,t)=>{r.waiters.push({resolve:e,reject:t})});return r.running||(r.running=!0,this.onBusyChange(!0),this.run(r,n)),i}async flush(e){if(!this.isAuthoritative(e))throw new Ae;let t=this.flight;t?.running&&await new Promise((e,n)=>t.idleWaiters.push({resolve:e,reject:n}))}assertAuthoritative(e){if(!this.isAuthoritative(e))throw new Ae}dispose(){this.flight&&this.retire(this.flight),this.authoritativeIdentity=null}async run(e,t){for(;!e.retired&&e.desired;){let n=e.desired;e.desired=null;let r=e.waiters.splice(0);e.activeWaiters=r;try{if(await t({identity:e.identity,selection:n,signal:e.controller.signal}),!e.retired)for(let e of r)e.resolve()}catch(t){if(!e.retired){this.onError(t);for(let e of r)e.reject(t)}}e.activeWaiters=[]}e.running=!1;for(let t of e.idleWaiters.splice(0))t.resolve();this.flight===e&&this.onBusyChange(!1)}retire(e){e.retired=!0,e.controller.abort();let t=new Ae;for(let n of e.activeWaiters.splice(0))n.reject(t);for(let n of e.waiters.splice(0))n.reject(t);for(let n of e.idleWaiters.splice(0))n.reject(t);this.flight===e&&(this.flight=null,this.onBusyChange(!1))}isAuthoritative(e){return this.authoritativeIdentity!==null&&Q(this.authoritativeIdentity,e)}},Me=(e,t)=>{let n=t.providerID??e.providerID,r=t.modelID??e.modelID,i=n!==e.providerID||r!==e.modelID;return{enabled:e.enabled,name:e.name,defaultPrompt:e.defaultPrompt,workspacePath:e.workspacePath,providerID:n,modelID:r,agent:t.agent??null,variant:i?null:t.variant??null,mode:e.mode}},Ne=async(e,t,n)=>{n.assertAuthoritative();let r=n.readSnapshot()?.assistants.find(t=>t.id===e.assistantID);if(!r)throw Error(`assistant_unavailable`);try{n.assertAuthoritative(),await n.updateAssistant(r,Me(r,t)),n.assertAuthoritative()}catch(i){if(n.assertAuthoritative(),n.signal.aborted)throw new Ae;if(!(i instanceof U)||i.code!==`revision_conflict`)throw i;if(n.assertAuthoritative(),r=(await n.ensureSnapshot(n.signal)).assistants.find(t=>t.id===e.assistantID),n.assertAuthoritative(),!r)throw new U(`revision_conflict`,409);n.assertAuthoritative(),await n.updateAssistant(r,Me(r,t)),n.assertAuthoritative()}};async function Pe(e){await I(e);let t=ce.getState().defaultShareAssistant;if(t?.assistantID!==e.id)return;let n=await L();n.serverInstanceID&&t.serverInstanceID===n.serverInstanceID&&ce.getState().setDefaultShareAssistant(null)}function Fe({assistant:e,open:t,onOpenChange:n,onDeleted:r}){let{t:i}=ee(),[a,o]=Y.useState(!1),s=e?_(e.name).displayName||e.name:``,c=g(e=>{a&&!e||n(e)}),l=g(()=>{a||n(!1)}),u=g(async()=>{if(!(!e||a)){o(!0);try{await Pe(e),r?.(e.id),n(!1),h.success(i(`assistants.settings.toast.deleted`))}catch{h.error(i(`assistants.settings.toast.deleteFailed`))}finally{o(!1)}}});return(0,Z.jsx)(q,{open:t&&e!==null,onOpenChange:c,children:(0,Z.jsxs)(W,{className:`max-w-md`,children:[(0,Z.jsxs)(ue,{children:[(0,Z.jsx)(G,{children:i(`assistants.settings.delete`)}),(0,Z.jsx)(K,{children:i(`assistants.settings.deleteConfirm`,{name:s})})]}),(0,Z.jsxs)(de,{children:[(0,Z.jsx)(he,{size:`sm`,variant:`ghost`,onClick:l,disabled:a,children:i(`settings.common.actions.cancel`)}),(0,Z.jsx)(he,{size:`sm`,variant:`destructive`,onClick:u,disabled:a,children:i(`settings.common.actions.delete`)})]})]})})}var Ie=[0,500,1500,4e3],Le=(e,t,n)=>{let r=!1,i=e.map(e=>e.info.id!==t||e.info.sessionID===n?e:(r=!0,{...e,info:{...e.info,sessionID:n}}));return r?i:e},Re=e=>{let t=e.refreshDelaysMs??Ie,n=e.sleep??(e=>new Promise(t=>setTimeout(t,e)));(async()=>{for(let r of t){if(r>0&&await n(r),!e.isCurrent())return;try{await e.refresh(e.binding);break}catch{}}})()},ze=e=>`${e.transport}\u0000${e.assistantID}`,Be=e=>({transport:e.transport,assistantID:e.assistantID}),Ve=(e,t)=>e.assistantID===t.assistantID&&e.sessionID===t.sessionID&&e.directory===t.directory&&e.sessionGeneration===t.sessionGeneration&&e.transport===t.transport&&e.runtimeGeneration===t.runtimeGeneration,He=(e,t)=>e.assistantID===t.assistantID&&e.sessionID===t.sessionID&&e.directory===t.directory&&e.sessionGeneration===t.sessionGeneration&&e.messageID===t.messageID&&e.transport===t.transport&&e.runtimeGeneration===t.runtimeGeneration,Ue=()=>{let e=new Map,t=new Map,n=1,r=e=>ze(e),i=async(e,n)=>{let i=r(e),a=t.get(i)??Promise.resolve(),o,s=new Promise(e=>{o=e}),c=a.catch(()=>void 0).then(()=>s);t.set(i,c),await a.catch(()=>void 0);try{return await n()}finally{o(),t.get(i)===c&&t.delete(i)}},a=(t,i)=>{let a=r(Be(t)),o=n++;return e.set(a,{identity:t,rollback:i,token:o}),o},o=t=>e.get(r(t))?.identity,s=t=>e.delete(r(t)),c=async e=>i(e,()=>s(e)),l=async t=>{let n=r(t),i=e.get(n);if(!i)return{kind:`none`};let a=i.token,o=i.identity,s;try{s=await i.rollback()}catch{return{kind:`blocked`,status:`failed`}}let c=e.get(n);return!c||c.token!==a||!He(c.identity,o)?{kind:`superseded`}:s.status===`rolled-back`||s.status===`conflict`?(e.delete(n),{kind:`cleared`,status:s.status}):{kind:`blocked`,status:s.status}},u=async(t,n)=>{let i=r(t),a=e.get(i);if(!a)return{kind:`none`};if(Ve(a.identity,n))return{kind:`match`};let o=a.token,s=a.identity,c=await a.rollback(),l=e.get(i);return!l||l.token!==o||!He(l.identity,s)?{kind:`superseded`}:c.status===`rolled-back`||c.status===`conflict`?(e.delete(i),{kind:`cleared`,status:c.status}):{kind:`rollback_failed`,retained:!0,status:c.status}};return{register:a,read:o,clear:s,clearExclusive:c,retireCurrent:l,rollbackAndClearIfBindingMismatch:async(e,t)=>i(e,()=>u(e,t)),rollbackAllBestEffort:async t=>{let n=[...e.entries()];await Promise.all(n.map(async([,n])=>{if(t?.excludeTransport!==void 0&&n.identity.transport===t.excludeTransport)return;let a=Be(n.identity);await i(a,async()=>{let t=r(a),i=e.get(t);if(!i||i.token!==n.token)return;let o=i.token,s=i.identity;try{let n=await i.rollback(),r=e.get(t);if(!r||r.token!==o||!He(r.identity,s))return;(n.status===`rolled-back`||n.status===`conflict`)&&e.delete(t)}catch{}})}))},stageExclusive:async(e,t)=>i(e,async()=>{let n=await l(e);if(n.kind===`blocked`)return{kind:`blocked`,status:n.status};let r=await t();if(!r)return{kind:`skipped`};let i=a(r.identity,r.rollback);return r.protectOnStale?{kind:`stale_protected`,token:i,identity:r.identity}:{kind:`registered`,token:i,identity:r.identity}})}},We=(e,t)=>!e?.attachments?.length||!t?[]:e.attachments.flatMap(e=>{let n=t[e.attachmentRefID];return n?[n]:[]}),Ge=(e,t)=>{let n=t??{};return e.map(e=>({partID:e.partID,text:e.text,...e.synthetic===!0?{synthetic:!0}:{},attachments:e.attachments.flatMap(e=>n[e.attachmentRefID]?[n[e.attachmentRefID]]:[])}))},Ke=(e,t)=>{if(t.length===0)return[...e];let n=new Map;for(let t of e)n.set(t.partID,t);for(let e of t)n.set(e.partID,e);let r=new Set,i=[];for(let t of e){let e=n.get(t.partID);e&&(i.push(e),r.add(t.partID))}for(let e of t)r.has(e.partID)||(i.push(e),r.add(e.partID));return i},qe=t({AssistantView:()=>et}),Je={},Ye=[],Xe=[],Ze=(e,t,n)=>[...e===void 0?[]:[{type:`text`,text:e}],...(t??[]).flatMap(e=>[{type:`text`,text:e.text,...e.synthetic===!0?{synthetic:!0}:{}},...(e.attachments??[]).map(e=>({type:`file`,mime:e.mimeType,url:e.dataUrl}))]),...(n??[]).map(e=>({type:`file`,mime:e.mimeType,url:e.dataUrl}))],Qe=e=>{let t=(0,Oe.c)(11),{assistant:n,onBack:r}=e,{t:i}=ee(),a;t[0]===n?a=t[1]:(a=n?_(n.name):null,t[0]=n,t[1]=a);let o=a,s=n&&o?o.displayName||n.name:``,c;t[2]!==s||t[3]!==i?(c=s||i(`assistants.title`),t[2]=s,t[3]=i,t[4]=c):c=t[4];let l;t[5]===i?l=t[6]:(l=i(`assistants.actions.backToChat`),t[5]=i,t[6]=l);let u;return t[7]!==r||t[8]!==c||t[9]!==l?(u=(0,Z.jsx)(V,{title:c,backAriaLabel:l,onBack:r,overlay:!0}),t[7]=r,t[8]=c,t[9]=l,t[10]=u):u=t[10],u},$e=e=>{let t=(0,Oe.c)(45),{assistantID:n,displayName:r,avatarEmoji:i,modeLabel:a,selected:o,enabled:s,editLabel:c,deleteLabel:l,onSelect:u,onEdit:d,onDelete:f}=e,[p,m]=Y.useState(!1),h;t[0]===u?h=t[1]:(h=()=>u(),t[0]=u,t[1]=h);let ee=g(h),_;t[2]===d?_=t[3]:(_=()=>{m(!1),d()},t[2]=d,t[3]=_);let v=g(_),y;t[4]===f?y=t[5]:(y=()=>{m(!1),f()},t[4]=f,t[5]=y);let b=g(y),x;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(x=e=>{e.preventDefault(),m(!0)},t[6]=x):x=t[6];let S=o?`border-border/50 bg-[var(--surface-elevated)]`:`border-transparent hover:bg-interactive-hover`,te=!s&&`opacity-65`,C;t[7]!==S||t[8]!==te?(C=fe(`flex w-full min-h-11 items-center gap-3 rounded-xl border px-3 py-3 text-left outline-none transition-[background-color,border-color,opacity] duration-150 ease-out active:bg-interactive-active focus-visible:ring-2 focus-visible:ring-[var(--interactive-focus-ring)] motion-reduce:transition-none`,S,te),t[7]=S,t[8]=te,t[9]=C):C=t[9];let w;t[10]!==ee||t[11]!==o||t[12]!==C?(w=(0,Z.jsx)(`button`,{type:`button`,role:`option`,"aria-selected":o,onClick:ee,onContextMenu:x,className:C}),t[10]=ee,t[11]=o,t[12]=C,t[13]=w):w=t[13];let T;t[14]!==n||t[15]!==i||t[16]!==r?(T=(0,Z.jsx)(pe,{name:n,emoji:i,size:24,label:r}),t[14]=n,t[15]=i,t[16]=r,t[17]=T):T=t[17];let E;t[18]===r?E=t[19]:(E=(0,Z.jsx)(`span`,{className:`block truncate typography-ui-label font-medium`,children:r}),t[18]=r,t[19]=E);let D;t[20]===a?D=t[21]:(D=(0,Z.jsx)(`span`,{className:`mt-0.5 block truncate typography-micro text-muted-foreground`,children:a}),t[20]=a,t[21]=D);let O;t[22]!==E||t[23]!==D?(O=(0,Z.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[E,D]}),t[22]=E,t[23]=D,t[24]=O):O=t[24];let k;t[25]!==O||t[26]!==w||t[27]!==T?(k=(0,Z.jsxs)(Te,{render:w,children:[T,O]}),t[25]=O,t[26]=w,t[27]=T,t[28]=k):k=t[28];let A;t[29]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,Z.jsx)(me,{name:`edit`,className:`size-4`}),t[29]=A):A=t[29];let j;t[30]!==c||t[31]!==v?(j=(0,Z.jsxs)(De,{onClick:v,children:[A,c]}),t[30]=c,t[31]=v,t[32]=j):j=t[32];let M;t[33]===Symbol.for(`react.memo_cache_sentinel`)?(M=(0,Z.jsx)(we,{}),t[33]=M):M=t[33];let N;t[34]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,Z.jsx)(me,{name:`delete-bin`,className:`size-4`}),t[34]=N):N=t[34];let P;t[35]!==l||t[36]!==b?(P=(0,Z.jsxs)(De,{onClick:b,className:`text-[var(--status-error)] focus:text-[var(--status-error)] data-[highlighted]:text-[var(--status-error)] [&_svg]:text-[var(--status-error)]`,children:[N,l]}),t[35]=l,t[36]=b,t[37]=P):P=t[37];let F;t[38]!==j||t[39]!==P?(F=(0,Z.jsxs)(Ee,{className:`min-w-[10rem]`,children:[j,M,P]}),t[38]=j,t[39]=P,t[40]=F):F=t[40];let I;return t[41]!==p||t[42]!==k||t[43]!==F?(I=(0,Z.jsxs)(Ce,{open:p,onOpenChange:m,children:[k,F]}),t[41]=p,t[42]=k,t[43]=F,t[44]=I):I=t[44],I},et=({activeOverride:e,onMobileBack:t})=>{let{t:l}=ee(),{isMobile:u}=ge(),d=ve(),f=Y.useSyncExternalStore(n,r,r),m=i(),E=p(e=>e.activeMainTab===`assistant`),N=e??E,P=p(e=>e.isMobile),I=u||P,L=F(),V=se(),H=V.data,U=ce(e=>e.assistantByTransport[f]??null),ue=ce(e=>e.selectAssistant),de=ce(e=>e.requestCreate),W=H?.assistants.find(e=>e.id===U)??null,G=W?.id??``,K=W?.sessionID??``,q=W?.effectiveWorkspacePath??``,J=Y.useMemo(()=>a({transportIdentity:f},`assistant:${G}`),[G,f]),be=c(J),Ce=O(e=>e.draftAttachmentViews[be]??Je),we=O(e=>e.drafts[be]),Te=Y.useMemo(()=>{let e=We(we,Ce);return e.length===0?Ye:e},[Ce,we]),Ee=we?.attachments,De=we?.syntheticParts,Oe=Y.useMemo(()=>!Ee||!De?``:`${Ee.map(e=>e.attachmentRefID).join(``)}\u0004${De.map(e=>`${e.partID}\u0002${e.attachments.map(e=>e.attachmentRefID).join(``)}`).join(``)}`,[Ee,De]);Y.useEffect(()=>{G&&O.getState().hydrateDraftAttachments(J)},[G,J,Oe]);let X=D(q||null,{enabled:!!q&&N}),Q=k(q||null,{enabled:!!q&&N}),Me=T(K,q||void 0),Pe=M(K,q||void 0),Ie=C(K),ze=ye(),[Ve,He]=Y.useState(()=>new Map),qe=Y.useRef(0),et=Y.useRef(Ue()),tt=Ve.get(G)??Xe,[,nt]=Y.useState(!1),rt=Y.useRef(()=>{});rt.current=()=>{h.error(l(`assistants.composer.selectionSaveFailed`))};let it=Y.useRef(null);it.current||=new je(nt,e=>rt.current(e));let at=Y.useMemo(()=>({assistantID:G,transportIdentity:f,runtimeGeneration:m}),[G,m,f]),$=it.current,ot=Y.useMemo(()=>({transport:f,assistantID:G}),[G,f]),st=g(async(e,t=f)=>{await et.current.clearExclusive({transport:t,assistantID:e})}),ct=g(e=>{et.current.rollbackAllBestEffort(e).catch(()=>void 0)});Y.useEffect(()=>{!U&&H?.assistants[0]&&ue(H.assistants[0].id)},[ue,U,H?.assistants]),Y.useEffect(()=>{V.isSuccess&&U&&!W&&ue(H?.assistants[0]?.id??null)},[W,ue,U,H?.assistants,V.isSuccess]),Y.useEffect(()=>{N&&G&&!K&&ae(G)},[N,G,K]),Y.useEffect(()=>{qe.current++,He(new Map),ct({excludeTransport:f})},[f,m,ct]),Y.useEffect(()=>()=>{qe.current++,ct()},[ct]),Y.useEffect(()=>{$.activate(at)},[$,at]),Y.useEffect(()=>()=>{$.dispose()},[$]),Y.useEffect(()=>{G&&et.current.rollbackAndClearIfBindingMismatch(ot,{assistantID:G,sessionID:K,directory:q,sessionGeneration:W?.sessionGeneration??-1,transport:f,runtimeGeneration:m}).catch(()=>void 0)},[W?.sessionGeneration,G,q,m,K,ot,f]);let lt=g(e=>at.assistantID?$.enqueue(at,e,async({identity:e,selection:t,signal:n})=>{await Ne(e,t,{readSnapshot:()=>z(void 0,e.transportIdentity),ensureSnapshot:e=>re(e),updateAssistant:ne,signal:n,assertAuthoritative:()=>{if($.assertAuthoritative(e),r()!==e.transportIdentity||i()!==e.runtimeGeneration)throw new Ae}})}):Promise.reject(Error(`assistant_unavailable`))),ut=Y.useMemo(()=>_e(Q.data),[Q.data]),dt=g(e=>{if(!W)return;let t=x(ut,W.agent??void 0,e);if(t){let e=b({providerID:W.providerID,modelID:W.modelID,agent:W.agent},t,ut,X.data??[]),n=e.providerID===W.providerID&&e.modelID===W.modelID;lt({...e,agent:e.agent??void 0,variant:n?W.variant??void 0:void 0})}}),ft=g(async(e,t)=>{e.sessionID&&await ze.ensureSessionRenderable(e.sessionID,{directory:e.directory,...t?.force?{force:!0}:{}})}),pt=W?.sessionGeneration;Y.useEffect(()=>{!N||!G||!K||!q||pt===void 0||ft({sessionID:K,directory:q,sessionGeneration:pt},{force:!0})},[N,G,q,ft,pt,K]);let mt=g((e,t)=>{if(t.length===0)return;let n=new Set(t);He(t=>{let r=t.get(e);if(!r?.some(e=>n.has(e.info.id)))return t;let i=new Map(t),a=r.filter(e=>!n.has(e.info.id));return a.length>0?i.set(e,a):i.delete(e),i})}),ht=g((e,t,n)=>{He(r=>{let i=r.get(e);if(!i)return r;let a=Le(i,t,n);if(a===i)return r;let o=new Map(r);return o.set(e,a),o})}),gt=g(e=>{mt(G,e)}),_t=g(async e=>{if(!K||!q)throw Error(`assistant_unavailable`);w(K,q).some(t=>t?.id===e)&&(await te(K,e,{directory:q,draftKey:J,restorePrimaryInput:!1}),await st(G))}),vt=g(async(e,t)=>{if(!W||W.mode!==`continuous`)return;if(!K||!q)throw Error(`assistant_unavailable`);if(!w(K,q).some(t=>t?.id===e))return;if(t.info.id!==e||t.info.sessionID!==K||t.info.role!==`user`)throw Error(`The selected user message is unavailable`);let n={assistantID:W.id,sessionID:K,directory:q,sessionGeneration:W.sessionGeneration,messageID:e,transport:f,runtimeGeneration:m},a=Be(n),o=await et.current.stageExclusive(a,async()=>{let a=await j(K,e,t,{directory:q,draftKey:J}),o=r()===n.transport&&i()===n.runtimeGeneration,s=o?z(void 0,n.transport)?.assistants.find(e=>e.id===n.assistantID):void 0,c=!!(s&&s.mode===`continuous`&&s.sessionID===n.sessionID&&s.sessionGeneration===n.sessionGeneration&&(s.effectiveWorkspacePath??``)===n.directory);if(o&&c)return{identity:n,rollback:()=>a.rollback()};let l=await a.rollback();return l.status===`failed`||l.status===`skipped`?{identity:n,rollback:()=>a.rollback(),protectOnStale:!0}:null});if(o.kind===`blocked`)throw Error(`assistant_stage_message_edit_prior_blocked`);if(o.kind===`stale_protected`)throw Error(`assistant_stage_message_edit_rollback_failed`)}),yt=Y.useMemo(()=>{let e=S(J,()=>O.getState());return{busy:!1,attachments:Te,addAttachment:t=>e.addLocal(t),removeAttachment:t=>e.removeByAttachmentID(t),clearAttachments:()=>e.clearRootAttachments(),restoreAttachments:t=>e.restoreRootAttachments(t),pendingInput:null,consumePendingInput:()=>null,pendingPreset:null,consumePendingPreset:()=>null,consumeSyntheticParts:()=>{let e=O.getState(),t=e.draftAttachmentViews[c(J)]??Je,n=e.consumeDraftSyntheticParts(J,y);return n?Ge(n,t):null},restoreSyntheticParts:e=>{(async()=>{let t=O.getState(),n=e.map(e=>({partID:e.partID??o(),text:e.text,attachments:[],...e.synthetic===!0?{synthetic:!0}:{}})),r=Ke(t.getDraft(J)?.syntheticParts??[],n);t.setDraftSyntheticParts(J,r);for(let r=0;r<n.length;r++){let i=n[r].partID;for(let n of e[r]?.attachments??[])n.source===`server`&&n.dataUrl?t.addDraftDurableAttachment(J,{attachmentID:n.id,filename:n.filename,mimeType:n.mimeType,size:n.size,source:`server`,url:n.dataUrl,serverPath:n.serverPath,partID:i}):await t.addDraftLocalAttachment(J,n.file,{attachmentID:n.id,filename:n.filename,source:n.source===`vscode`?`vscode`:`local`,vscodePath:n.vscodePath,vscodeSource:n.vscodeSource===`selection`?`selection`:void 0,partID:i})}})()},inlineDrafts:[],removeInlineDraft:()=>{},restoreInlineDrafts:()=>{},history:Ie,captureRuntime:()=>O.getState().captureDraftRuntime(),getDraft:e=>O.getState().getDraft(e),abortPrompt:{sessionID:null,clear:()=>{}}}},[Te,J,Ie]),bt=Y.useMemo(()=>{let e=(X.data??[]).find(e=>e.id===W?.providerID)?.models?.find(e=>e.id===W?.modelID);return xe(e)},[W?.modelID,W?.providerID,X.data]),xt=Me.length>0,St=Y.useMemo(()=>{if(!W||!K||!q)return null;let e={sessionID:K,directory:q,sessionGeneration:W.sessionGeneration};return{kind:`secondary`,surfaceID:`assistant:${W.id}`,active:N,sessionID:K,directory:q,draftKey:J,transportIdentity:f,runtimeGeneration:m,deliveryTarget:{kind:`assistant`,assistantID:W.id},resources:yt,...W.mode===`stateless`?{queueSessionID:`assistant:${W.id}`}:{},selection:{value:{providerID:W.providerID,modelID:W.modelID,agent:W.agent??void 0,variant:W.variant??void 0},catalog:{providers:X.data??[],agents:ut,variants:bt,variantsReady:X.isSuccess,ready:X.isSuccess&&Q.isSuccess,loading:X.isPending||Q.isPending,error:X.isError||Q.isError},change:lt,flush:()=>$.flush(at)},activity:{phase:Pe?.type===`busy`?`busy`:Pe?.type===`retry`?`retry`:`idle`,canAbort:Pe?.type===`busy`||Pe?.type===`retry`},commands:{sessionID:K,hasMessages:xt,hasNewDraft:!1},commandPolicy:e=>e.name!==`fork`&&e.name!==`thread`,backend:{send:async t=>{let n;for(let t of w(e.sessionID,e.directory)){let e=typeof t?.id==`string`?t.id:``;/^msg_[0-9a-f]{12}[0-9A-Za-z]{14}$/.test(e)&&(!n||e>n)&&(n=e)}let r=s(`msg`,n);t.options?.commitStagedMessageEdit&&et.current.clear({transport:f,assistantID:W.id});let i=A({messageID:r,sessionID:e.sessionID,providerID:t.providerID??W.providerID,modelID:t.modelID??W.modelID,agent:t.agent??W.agent??void 0,text:t.text,attachments:t.attachments,additionalParts:t.parts});He(e=>{let t=new Map(e);return t.set(W.id,[...e.get(W.id)??[],i]),t});let a;try{a=await B(W.id,e,r,Ze(t.text,t.parts,t.attachments))}catch(e){throw mt(W.id,[r]),e}if(L.data?.serverInstanceID){let e=_(W.name);v({serverInstanceID:L.data.serverInstanceID,assistantID:W.id,name:e.displayName||W.name,avatarSeed:W.id,...e.avatarEmoji?{avatarEmoji:e.avatarEmoji}:{}}).catch(()=>void 0)}a.binding.sessionID&&ht(W.id,r,a.binding.sessionID);let o=qe.current;Re({binding:a.binding,refresh:t=>ft(t,{force:t.sessionID!==e.sessionID||t.sessionGeneration!==e.sessionGeneration}),isCurrent:()=>qe.current===o})},sendQueued:async()=>{throw Error(`assistant-server-queue-required`)},create:async()=>{let e=await R(W.id);await st(W.id),await ft(e,{force:!0})},compact:async()=>{let t=await oe(W.id,e);await st(W.id),await ft(t.binding,{force:!0})},abort:async()=>{await ie(W.id,e)}},shortcuts:{cycle:dt,new:async()=>{let e=await R(W.id);await st(W.id),await ft(e,{force:!0})},abort:async()=>{await ie(W.id,e)},submit:()=>{}}}},[N,W,L.data?.serverInstanceID,lt,st,dt,q,J,xt,X.data,X.isError,X.isPending,X.isSuccess,Q.isError,Q.isPending,Q.isSuccess,ft,ht,mt,yt,m,$,at,K,Pe,f,bt,ut]),Ct=g(()=>{if(de(),d){d.openSettings();return}let e=p.getState();e.setSettingsPage(`assistants`),e.setSettingsDialogOpen(!0)}),wt=g(e=>{le(e,d?{openMobileSettings:d.openSettings}:void 0)}),[Tt,Et]=Y.useState(null),Dt=g(e=>{Et(e)}),Ot=g(e=>{e||Et(null)}),kt=g(()=>{p.getState().setActiveMainTab(`chat`)}),At=g(()=>{if(t){t();return}kt()}),jt=(e,t,n,r)=>(0,Z.jsxs)(`div`,{className:`relative flex h-full min-h-0 flex-col`,children:[I?(0,Z.jsx)(Qe,{assistant:W,onBack:At}):null,(0,Z.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col items-center justify-center px-6 pt-[calc(max(0.25rem,var(--oc-safe-area-top,0px))+var(--oc-mobile-detail-navigation-height,3.5rem))] text-center`,children:[(0,Z.jsx)(me,{name:e,className:`size-6 text-muted-foreground`}),(0,Z.jsx)(`h1`,{className:`mt-4 typography-ui-header font-semibold`,children:t}),n?(0,Z.jsx)(`p`,{className:`mt-2 max-w-md typography-ui text-muted-foreground`,children:n}):null,r?(0,Z.jsx)(`div`,{className:`mt-5`,children:r}):null]})]});if(L.isPending||V.isPending)return jt(`ai-agent`,l(`assistants.state.unavailable`));if(L.isError||!L.data?.supported||!L.data.enabled||!H?.enabled)return jt(`cloud-off`,l(`assistants.state.unavailable`));if(!H.assistants.length)return jt(`ai-agent`,l(`assistants.onboarding.title`),l(`assistants.onboarding.description`),(0,Z.jsx)(he,{onClick:Ct,children:l(`assistants.onboarding.action`)}));if(!W)return jt(`ai-agent`,l(`assistants.state.unavailable`));if(!St)return(0,Z.jsxs)(`div`,{className:`relative flex h-full min-h-0 flex-col bg-background`,children:[I?(0,Z.jsx)(Qe,{assistant:W,onBack:At}):null,(0,Z.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col items-center justify-center gap-3 px-6 pt-[calc(max(0.25rem,var(--oc-safe-area-top,0px))+var(--oc-mobile-detail-navigation-height,3.5rem))]`,"aria-busy":`true`,"aria-label":l(`assistants.state.unavailable`),children:[(0,Z.jsx)(`div`,{className:`size-10 animate-pulse rounded-xl bg-[var(--surface-muted)] motion-reduce:animate-none`}),(0,Z.jsx)(`div`,{className:`h-3.5 w-36 animate-pulse rounded-md bg-[var(--surface-muted)] motion-reduce:animate-none`})]})]});let Mt=_(W.name),Nt=W.enabled?V.isError?l(`assistants.state.staleSnapshot`):null:l(`assistants.state.assistantDisabled`);return(0,Z.jsxs)(`div`,{className:`relative flex h-full min-h-0 overflow-hidden bg-background`,"data-presentation":`workspace`,children:[I?null:(0,Z.jsxs)(`section`,{className:`flex h-full min-h-0 w-[clamp(16rem,22vw,20rem)] shrink-0 flex-col overflow-hidden`,children:[(0,Z.jsx)(`header`,{className:`shrink-0 px-4 pb-3 pt-4 sm:px-5`,children:(0,Z.jsx)(`h1`,{className:`truncate typography-ui-label font-semibold text-foreground`,children:l(`assistants.title`)})}),(0,Z.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-3 pb-4 sm:px-4`,role:`listbox`,"aria-label":l(`assistants.listAria`),children:(0,Z.jsx)(`div`,{className:`flex flex-col gap-1 border-t border-border/40 pt-3`,children:H.assistants.map(e=>{let t=e.id===U,n=_(e.name);return(0,Z.jsx)($e,{assistantID:e.id,displayName:n.displayName,avatarEmoji:n.avatarEmoji??void 0,modeLabel:e.mode===`stateless`?l(`assistants.mode.stateless`):l(`assistants.mode.continuous`),selected:t,enabled:e.enabled,editLabel:l(`assistants.menu.edit`),deleteLabel:l(`assistants.settings.delete`),onSelect:()=>ue(e.id),onEdit:()=>wt(e.id),onDelete:()=>Dt(e)},e.id)})})})]}),(0,Z.jsx)(Fe,{assistant:Tt,open:Tt!==null,onOpenChange:Ot}),(0,Z.jsxs)(`div`,{className:fe(`relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden bg-background`,!I&&`border-l border-border/60`),children:[I?(0,Z.jsx)(Qe,{assistant:W,onBack:At}):(0,Z.jsxs)(`header`,{className:`flex h-14 shrink-0 items-center gap-3 border-b border-border/40 px-4 sm:px-5`,children:[(0,Z.jsx)(pe,{name:W.id,emoji:Mt.avatarEmoji,size:24,label:Mt.displayName||W.name}),(0,Z.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Z.jsx)(`div`,{className:`truncate typography-ui-label font-medium`,children:Mt.displayName}),(0,Z.jsx)(`div`,{className:`mt-0.5 truncate typography-micro leading-none text-muted-foreground/70`,children:W.mode===`stateless`?l(`assistants.conversation.statelessHint`):l(`assistants.conversation.continuousHint`)})]})]}),(0,Z.jsx)(ke,{onRevertMessage:_t,onEditMessage:W.mode===`continuous`?vt:void 0,assistant:W,sessionID:K,warning:Nt,surface:St,pendingUserMessages:tt,onPendingUserMessagesMaterialized:gt})]}),I?null:(0,Z.jsx)(Se,{directory:q||null})]})};export{qe as n,Fe as r,et as t};