@openchambery/web 1.19.6 → 1.19.7-beta.10

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 (151) hide show
  1. package/dist/assets/{AgentAvatar-CecaXP3U.js → AgentAvatar-Di8F4QJh.js} +1 -1
  2. package/dist/assets/AssistantView-DjRMIQm9.js +1 -0
  3. package/dist/assets/{ChatContainer-BNiQ84dy.js → ChatContainer-46JNO0wQ.js} +41 -41
  4. package/dist/assets/ContextPanel-C0ChXTuy.js +285 -0
  5. package/dist/assets/DiagramView-BgKMg0IV.js +1 -0
  6. package/dist/assets/FadeInOnReveal-CV2s6YN8.js +1 -0
  7. package/dist/assets/{Icon-Du1LX11Q.js → Icon-CLpn1mIz.js} +1 -1
  8. package/dist/assets/MarkdownRendererImpl-DeXN6UZF.js +7 -0
  9. package/dist/assets/MarkstreamRendererImpl-BRvprELo.js +1 -0
  10. package/dist/assets/MarkstreamRendererImpl-Ca7RATbs.css +1 -0
  11. package/dist/assets/MobileDetailNavigation-CyEjNnBa.js +1 -0
  12. package/dist/assets/MobileShareBridge-b_P7CIM8.js +4 -0
  13. package/dist/assets/MobileSurface-GUoCE7e3.js +2 -0
  14. package/dist/assets/{MultiRunWindow-BT7jpOmw.js → MultiRunWindow-BXKiOGl3.js} +1 -1
  15. package/dist/assets/OnboardingScreen-D6rtE7rj.js +1 -0
  16. package/dist/assets/OverlayScrollbar-DlNZho3q.js +2 -0
  17. package/dist/assets/SettingsView-CmQ9Gihu.js +25 -0
  18. package/dist/assets/{SettingsWindow-fsuSYQpN.js → SettingsWindow-oomlikIc.js} +1 -1
  19. package/dist/assets/TerminalView-DukmFrpQ.js +8 -0
  20. package/dist/assets/ToolOutputDialog-DfyASOZ3.js +10 -0
  21. package/dist/assets/__vite-optional-peer-dep_mermaid_markstream-react-CQGbcmkI.js +1 -0
  22. package/dist/assets/appThemeRegistry-BPIyegL1.js +2 -0
  23. package/dist/assets/{button-p6vbd3r6.js → button-z0GOBtWi.js} +1 -1
  24. package/dist/assets/clipboard-D35XSwID.js +1 -0
  25. package/dist/assets/{collapsible-Cimoz0kx.js → collapsible-D9zJRpeB.js} +1 -1
  26. package/dist/assets/d2_markstream-react-DtM9g53j.js +1 -0
  27. package/dist/assets/desktop-CfLlmafK.js +1 -0
  28. package/dist/assets/desktopHosts-C1Ns3DUu.js +1 -0
  29. package/dist/assets/desktopRelayRestore-8pvI_dSc.js +1 -0
  30. package/dist/assets/{diagram-DX_MPRs3.js → diagram-CoEqmReY.js} +1 -1
  31. package/dist/assets/{dialog-Bjnvo5pk.js → dialog-x2hirWBd.js} +1 -1
  32. package/dist/assets/{es-D9KcV5TX.js → es-C8Sqjsia.js} +1 -1
  33. package/dist/assets/fileQueries-DGHZqZHc.js +1 -0
  34. package/dist/assets/{fr-DPA9qUl3.js → fr-p-Zwm_j2.js} +1 -1
  35. package/dist/assets/{gitApi-DpRVHaQE.js → gitApi-CDZC-Lk_.js} +1 -1
  36. package/dist/assets/infographic_markstream-react-C3vVus-4.js +1 -0
  37. package/dist/assets/{input-gaFVNq1P.js → input-BG3VWTIF.js} +1 -1
  38. package/dist/assets/insertionBoundaries-COMpolc-.js +4 -0
  39. package/dist/assets/{ja-Dsif3NoD.js → ja-B6REu1qP.js} +1 -1
  40. package/dist/assets/{ko-Dixx4Ctg.js → ko-CJBNH9IZ.js} +1 -1
  41. package/dist/assets/main-BUoqbfN5.js +29 -0
  42. package/dist/assets/main-CzBK9fLh.js +2 -0
  43. package/dist/assets/markdown-worker-y3ewaqAK.js +4 -0
  44. package/dist/assets/markdownHeightCache-CvUyZT4q.js +1 -0
  45. package/dist/assets/markdownTheme-SPe4jOwX.js +2 -0
  46. package/dist/assets/miniChat-B_1WEof_.js +2 -0
  47. package/dist/assets/mobile-BeF7OWnn.js +2 -0
  48. package/dist/assets/multirun-CIJ8QEaF.js +4 -0
  49. package/dist/assets/persistence-w-AiX2i4.js +3 -0
  50. package/dist/assets/{pl-Bj78ZGgf.js → pl-B2cBI_7K.js} +1 -1
  51. package/dist/assets/platform-4eCmsdol.js +2 -0
  52. package/dist/assets/projectMeta-DDlv5Ikc.js +3 -0
  53. package/dist/assets/{pt-BR-CFL3xSAf.js → pt-BR-CrCc9hmt.js} +1 -1
  54. package/dist/assets/radio-CavTQQap.js +1 -0
  55. package/dist/assets/renderElectronMiniChatApp-BsJ8uce6.js +2 -0
  56. package/dist/assets/renderMobileApp-DlUGMmJA.js +28 -0
  57. package/dist/assets/runtime-switch-BkpTTbEi.js +1 -0
  58. package/dist/assets/runtimeConfig-Bd6v740T.js +2 -0
  59. package/dist/assets/runtimeEndpointReset-BWSOrCQV.js +4 -0
  60. package/dist/assets/{shikiHighlight-Bs6Tt3X-.js → shikiHighlight-B-VbG24L.js} +1 -1
  61. package/dist/assets/sortable-tabs-strip-CNDgyX0B.js +1 -0
  62. package/dist/assets/{src-2eFAiBLq.css → src-DZt1nWf5.css} +1 -1
  63. package/dist/assets/{store-DzpbXWX1.js → store-CL3WP48T.js} +2 -2
  64. package/dist/assets/terminalApi-CGtOtc8I.js +1 -0
  65. package/dist/assets/{tooltip-D1a6rKLA.js → tooltip-CtH61mQh.js} +1 -1
  66. package/dist/assets/{uk-BY60Ub3Z.js → uk-C8YKAz0x.js} +1 -1
  67. package/dist/assets/url-KeihbE0d.js +1 -0
  68. package/dist/assets/useAppFontEffects-DgTFkg79.js +7 -0
  69. package/dist/assets/useAssistantUIStore-I0VWrB5V.js +1 -0
  70. package/dist/assets/useDesktopWindowControlsLayout-D7acNtOm.js +1 -0
  71. package/dist/assets/{useEffectiveDirectory-CmjO98kZ.js → useEffectiveDirectory-SLhBW8Ri.js} +1 -1
  72. package/dist/assets/useFontPreferences-BLZ3y6mN.js +1 -0
  73. package/dist/assets/useMobileNavigationStore-BDD3R1c_.js +412 -0
  74. package/dist/assets/useSessionAutoCleanup-da8DkQd4.js +1 -0
  75. package/dist/assets/useUIStore-CNLmCoPU.js +1 -0
  76. package/dist/assets/useWorkerHighlightedLines-CG8Rl5i3.js +7 -0
  77. package/dist/assets/utils-CTL16t2f.js +1 -0
  78. package/dist/assets/vendor-floating-ui-core-Co1I1lFV.js +1 -0
  79. package/dist/assets/vendor-floating-ui-dom-BHhLtF5l.js +1 -0
  80. package/dist/assets/vendor-katex--B5dHUyk.js +257 -0
  81. package/dist/assets/vendor-markstream-core-Cm34iPLL.js +3 -0
  82. package/dist/assets/vendor-markstream-react-CGQrpq8a.css +1 -0
  83. package/dist/assets/vendor-markstream-react-CwvbEg9R.js +173 -0
  84. package/dist/assets/vendor-pierre-diffs-DX7XTPG3.js +2795 -0
  85. package/dist/assets/vendor-pierre-theme-D9JzKBPc.js +1 -0
  86. package/dist/assets/vendor-stream-diffs-DWy3xSmp.js +6 -0
  87. package/dist/assets/{zh-CN-Cox1LaOW.js → zh-CN-CCYwUnmB.js} +1 -1
  88. package/dist/assets/{zh-TW-B6RU0mxa.js → zh-TW-D8Y6py08.js} +1 -1
  89. package/dist/index.html +11 -9
  90. package/dist/mini-chat.html +11 -9
  91. package/dist/mobile.html +11 -9
  92. package/package.json +1 -1
  93. package/server/lib/notifications/APNS.md +4 -4
  94. package/server/lib/notifications/DOCUMENTATION.md +1 -1
  95. package/server/lib/notifications/apns-runtime.js +139 -20
  96. package/server/lib/notifications/apns-runtime.test.js +66 -7
  97. package/server/lib/notifications/apns-titles.js +62 -62
  98. package/server/lib/notifications/apns-titles.test.js +3 -1
  99. package/server/lib/notifications/routes.js +1 -1
  100. package/server/lib/notifications/runtime.js +29 -49
  101. package/server/lib/notifications/runtime.test.js +22 -0
  102. package/server/lib/opencode/settings-runtime.js +16 -0
  103. package/dist/assets/AssistantView-BJv9QUM-.js +0 -1
  104. package/dist/assets/ContextPanel-Df7BbJaq.js +0 -285
  105. package/dist/assets/DiagramView-Cw96eBGZ.js +0 -1
  106. package/dist/assets/FadeInOnReveal-Cj9ZC3Ab.js +0 -1
  107. package/dist/assets/MarkdownRendererImpl-DtZOlgmm.js +0 -7
  108. package/dist/assets/MobileDetailNavigation-C_4Y_X61.js +0 -1
  109. package/dist/assets/MobileShareBridge-CRpk-w3Q.js +0 -4
  110. package/dist/assets/MobileSurface-Brh-Z1KZ.js +0 -2
  111. package/dist/assets/OnboardingScreen-BkbprNa7.js +0 -1
  112. package/dist/assets/OverlayScrollbar-oOLMqq2s.js +0 -2
  113. package/dist/assets/SettingsView-BFP8FEvx.js +0 -25
  114. package/dist/assets/TerminalView-Z11uL87z.js +0 -8
  115. package/dist/assets/ToolOutputDialog-BV2y1sgg.js +0 -10
  116. package/dist/assets/appThemeRegistry-CNVnIaLQ.js +0 -2
  117. package/dist/assets/clipboard-C0bgPFn5.js +0 -1
  118. package/dist/assets/desktopHosts-DceeVBky.js +0 -1
  119. package/dist/assets/desktopRelayRestore-B0MRdR5y.js +0 -1
  120. package/dist/assets/fileQueries-BDld6h3B.js +0 -1
  121. package/dist/assets/insertionBoundaries-Dj5ZcWxy.js +0 -4
  122. package/dist/assets/main-B_kb4yxM.js +0 -29
  123. package/dist/assets/main-BqE-HYIY.js +0 -2
  124. package/dist/assets/markdown-worker-CoO82KYF.js +0 -4
  125. package/dist/assets/markdownTheme-St8zxDvJ.js +0 -2
  126. package/dist/assets/miniChat-CUYIqudA.js +0 -2
  127. package/dist/assets/mobile-C4xx6vwy.js +0 -2
  128. package/dist/assets/multirun-CfDp-MKW.js +0 -4
  129. package/dist/assets/persistence-CLUawIlm.js +0 -3
  130. package/dist/assets/platform-BrncW9ab.js +0 -2
  131. package/dist/assets/projectMeta-DuKavDZ0.js +0 -3
  132. package/dist/assets/radio-BgPFAtiV.js +0 -1
  133. package/dist/assets/renderElectronMiniChatApp-BjwbnKC-.js +0 -2
  134. package/dist/assets/renderMobileApp-DzGInnvc.js +0 -25
  135. package/dist/assets/runtimeConfig-D5qWnnR3.js +0 -2
  136. package/dist/assets/runtimeEndpointReset-kob_Gqd0.js +0 -4
  137. package/dist/assets/sortable-tabs-strip-oDpTDVoQ.js +0 -1
  138. package/dist/assets/terminalApi-D2OzR0I3.js +0 -1
  139. package/dist/assets/url-zwuNq3GS.js +0 -1
  140. package/dist/assets/useAppFontEffects-DR99zjde.js +0 -7
  141. package/dist/assets/useAssistantUIStore-D699Sbdb.js +0 -1
  142. package/dist/assets/useDesktopWindowControlsLayout-DT4BmF4D.js +0 -1
  143. package/dist/assets/useFontPreferences-F2QPNE2V.js +0 -1
  144. package/dist/assets/useMobileNavigationStore-DLW9tcn6.js +0 -412
  145. package/dist/assets/useSessionAutoCleanup-BE7yfJLF.js +0 -1
  146. package/dist/assets/useUIStore-BXjMQrel.js +0 -1
  147. package/dist/assets/useWorkerHighlightedLines-5n25LYcg.js +0 -7
  148. package/dist/assets/utils-D94hxQYq.js +0 -1
  149. package/dist/assets/vendor-katex-CNGgSigB.js +0 -257
  150. package/dist/assets/vendor-pierre-diffs-BenIz2TM.js +0 -1418
  151. package/dist/assets/vendor-pierre-theme-F9vQJHIe.js +0 -1
@@ -20,113 +20,113 @@ export const APNS_LOCALES = Object.freeze([
20
20
 
21
21
  const TITLES = Object.freeze({
22
22
  en: Object.freeze({
23
- ready: 'Agent response is ready',
24
- error: 'Agent hit an error',
25
- question: 'Agent needs your input',
26
- permission: 'Agent needs permission',
27
- goal_complete: 'Goal complete',
23
+ ready: 'Task completed',
24
+ error: 'Something went wrong',
25
+ question: 'Needs your answer',
26
+ permission: 'Needs permission',
27
+ goal_complete: 'Goal completed',
28
28
  goal_blocked: 'Goal blocked',
29
- goal_budget: 'Goal reached its token budget',
30
- update: 'Agent update',
29
+ goal_budget: 'Token budget reached',
30
+ update: 'Update',
31
31
  session: 'Session',
32
32
  }),
33
33
  fr: Object.freeze({
34
- ready: "La réponse de l'agent est prête",
35
- error: "L'agent a rencontré une erreur",
36
- question: "L'agent a besoin de votre saisie",
37
- permission: "L'agent a besoin d'une autorisation",
38
- goal_complete: 'Objectif terminé',
34
+ ready: 'Tâche terminée',
35
+ error: "Une erreur s'est produite",
36
+ question: 'Besoin de votre réponse',
37
+ permission: 'Autorisation requise',
38
+ goal_complete: 'Objectif atteint',
39
39
  goal_blocked: 'Objectif bloqué',
40
- goal_budget: "L'objectif a atteint son budget de tokens",
41
- update: "Mise à jour de l'agent",
40
+ goal_budget: 'Budget de tokens atteint',
41
+ update: 'Mise à jour',
42
42
  session: 'Session',
43
43
  }),
44
44
  'zh-CN': Object.freeze({
45
- ready: '智能体回复已就绪',
46
- error: '智能体遇到错误',
47
- question: '智能体需要你的输入',
48
- permission: '智能体需要权限',
45
+ ready: '任务已完成',
46
+ error: '出现错误',
47
+ question: '需要你回答',
48
+ permission: '需要你授权',
49
49
  goal_complete: '目标已完成',
50
50
  goal_blocked: '目标受阻',
51
- goal_budget: '目标已达 token 预算',
52
- update: '智能体更新',
51
+ goal_budget: '已达用量上限',
52
+ update: '有新进展',
53
53
  session: '会话',
54
54
  }),
55
55
  'zh-TW': Object.freeze({
56
- ready: '智能體回覆已就緒',
57
- error: '智能體遇到錯誤',
58
- question: '智能體需要你的輸入',
59
- permission: '智能體需要權限',
56
+ ready: '任務已完成',
57
+ error: '出現錯誤',
58
+ question: '需要你回答',
59
+ permission: '需要你授權',
60
60
  goal_complete: '目標已完成',
61
61
  goal_blocked: '目標受阻',
62
- goal_budget: '目標已達 token 預算',
63
- update: '智能體更新',
62
+ goal_budget: '已達用量上限',
63
+ update: '有新進展',
64
64
  session: '工作階段',
65
65
  }),
66
66
  uk: Object.freeze({
67
- ready: 'Відповідь агента готова',
68
- error: 'Агент зіткнувся з помилкою',
69
- question: 'Агенту потрібне ваше введення',
70
- permission: 'Агенту потрібен дозвіл',
67
+ ready: 'Завдання виконано',
68
+ error: 'Сталася помилка',
69
+ question: 'Потрібна ваша відповідь',
70
+ permission: 'Потрібен дозвіл',
71
71
  goal_complete: 'Цілі досягнуто',
72
72
  goal_blocked: 'Цілі заблоковано',
73
- goal_budget: 'Ціль досягла ліміту токенів',
74
- update: 'Оновлення агента',
73
+ goal_budget: 'Досягнуто ліміт токенів',
74
+ update: 'Оновлення',
75
75
  session: 'Сесія',
76
76
  }),
77
77
  es: Object.freeze({
78
- ready: 'La respuesta del agente está lista',
79
- error: 'El agente encontró un error',
80
- question: 'El agente necesita tu entrada',
81
- permission: 'El agente necesita permiso',
78
+ ready: 'Tarea completada',
79
+ error: 'Se produjo un error',
80
+ question: 'Necesita tu respuesta',
81
+ permission: 'Necesita permiso',
82
82
  goal_complete: 'Objetivo completado',
83
83
  goal_blocked: 'Objetivo bloqueado',
84
- goal_budget: 'El objetivo alcanzó su presupuesto de tokens',
85
- update: 'Actualización del agente',
84
+ goal_budget: 'Presupuesto de tokens alcanzado',
85
+ update: 'Actualización',
86
86
  session: 'Sesión',
87
87
  }),
88
88
  'pt-BR': Object.freeze({
89
- ready: 'A resposta do agente está pronta',
90
- error: 'O agente encontrou um erro',
91
- question: 'O agente precisa da sua entrada',
92
- permission: 'O agente precisa de permissão',
89
+ ready: 'Tarefa concluída',
90
+ error: 'Ocorreu um erro',
91
+ question: 'Precisa da sua resposta',
92
+ permission: 'Precisa de permissão',
93
93
  goal_complete: 'Objetivo concluído',
94
94
  goal_blocked: 'Objetivo bloqueado',
95
- goal_budget: 'O objetivo atingiu o orçamento de tokens',
96
- update: 'Atualização do agente',
95
+ goal_budget: 'Orçamento de tokens atingido',
96
+ update: 'Atualização',
97
97
  session: 'Sessão',
98
98
  }),
99
99
  ko: Object.freeze({
100
- ready: '에이전트 응답이 준비되었습니다',
101
- error: '에이전트에서 오류가 발생했습니다',
102
- question: '에이전트가 입력을 요청합니다',
103
- permission: '에이전트가 권한이 필요합니다',
100
+ ready: '작업 완료',
101
+ error: '오류가 발생했습니다',
102
+ question: '답변이 필요합니다',
103
+ permission: '권한이 필요합니다',
104
104
  goal_complete: '목표 완료',
105
105
  goal_blocked: '목표 차단됨',
106
- goal_budget: '목표가 토큰 예산에 도달했습니다',
107
- update: '에이전트 업데이트',
106
+ goal_budget: '토큰 한도 도달',
107
+ update: '업데이트',
108
108
  session: '세션',
109
109
  }),
110
110
  pl: Object.freeze({
111
- ready: 'Odpowiedź agenta jest gotowa',
112
- error: 'Agent napotkał błąd',
113
- question: 'Agent potrzebuje Twojego wejścia',
114
- permission: 'Agent potrzebuje uprawnienia',
111
+ ready: 'Zadanie ukończone',
112
+ error: 'Wystąpił błąd',
113
+ question: 'Potrzebna twoja odpowiedź',
114
+ permission: 'Potrzebne uprawnienie',
115
115
  goal_complete: 'Cel ukończony',
116
116
  goal_blocked: 'Cel zablokowany',
117
- goal_budget: 'Cel osiągnął budżet tokenów',
118
- update: 'Aktualizacja agenta',
117
+ goal_budget: 'Osiągnięto limit tokenów',
118
+ update: 'Aktualizacja',
119
119
  session: 'Sesja',
120
120
  }),
121
121
  ja: Object.freeze({
122
- ready: 'エージェントの応答が準備できました',
123
- error: 'エージェントでエラーが発生しました',
124
- question: 'エージェントが入力を求めています',
125
- permission: 'エージェントが許可を求めています',
122
+ ready: 'タスク完了',
123
+ error: 'エラーが発生しました',
124
+ question: '回答が必要です',
125
+ permission: '許可が必要です',
126
126
  goal_complete: '目標完了',
127
127
  goal_blocked: '目標がブロックされました',
128
- goal_budget: '目標がトークン予算に達しました',
129
- update: 'エージェントの更新',
128
+ goal_budget: 'トークン上限に達しました',
129
+ update: '更新',
130
130
  session: 'セッション',
131
131
  }),
132
132
  });
@@ -33,12 +33,14 @@ describe('apns-titles', () => {
33
33
 
34
34
  it('localizes payload title by type and keeps session name as body', () => {
35
35
  expect(localizeApnsPayload({ type: 'question', sessionName: 'Build fix' }, 'zh-CN')).toEqual({
36
- title: '智能体需要你的输入',
36
+ title: '需要你回答',
37
37
  body: 'Build fix',
38
38
  badge: undefined,
39
39
  tag: undefined,
40
40
  data: undefined,
41
41
  });
42
+ expect(resolveApnsTitle('ready', 'zh-CN')).toBe('任务已完成');
43
+ expect(resolveApnsTitle('ready', 'en')).toBe('Task completed');
42
44
  expect(localizeApnsPayload({ type: 'ready' }, 'fr').body).toBe('Session');
43
45
  expect(localizeApnsPayload({ type: 'ready' }, 'zh-CN').body).toBe('会话');
44
46
  });
@@ -219,7 +219,7 @@ export const registerNotificationRoutes = (app, dependencies) => {
219
219
  }
220
220
 
221
221
  if (typeof addOrUpdateLiveActivityToken === 'function') {
222
- await addOrUpdateLiveActivityToken(uiToken, token, activityId, sessionId);
222
+ await addOrUpdateLiveActivityToken(uiToken, token, activityId, sessionId, req.body?.items);
223
223
  }
224
224
  return res.json({ ok: true });
225
225
  });
@@ -273,40 +273,6 @@ export const createNotificationTriggerRuntime = (deps) => {
273
273
  return trimmed.length > 0 ? trimmed : undefined;
274
274
  };
275
275
 
276
- const formatMode = (raw) => {
277
- const value = typeof raw === 'string' ? raw.trim() : '';
278
- const normalized = value.length > 0 ? value : 'agent';
279
- return normalized
280
- .split(/[-_\s]+/)
281
- .filter(Boolean)
282
- .map((token) => token.charAt(0).toUpperCase() + token.slice(1))
283
- .join(' ');
284
- };
285
-
286
- const formatModelId = (raw) => {
287
- const value = typeof raw === 'string' ? raw.trim() : '';
288
- if (!value) {
289
- return 'Assistant';
290
- }
291
-
292
- const tokens = value.split(/[-_]+/).filter(Boolean);
293
- const result = [];
294
- for (let i = 0; i < tokens.length; i += 1) {
295
- const current = tokens[i];
296
- const next = tokens[i + 1];
297
- if (/^\d+$/.test(current) && next && /^\d+$/.test(next)) {
298
- result.push(`${current}.${next}`);
299
- i += 1;
300
- continue;
301
- }
302
- result.push(current);
303
- }
304
-
305
- return result
306
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
307
- .join(' ');
308
- };
309
-
310
276
  // A session with an ACTIVE goal suppresses per-turn ready notifications;
311
277
  // the session-goal runtime sends its own notification when the goal
312
278
  // settles. Fetch failures fall through to normal notification behavior.
@@ -338,6 +304,20 @@ export const createNotificationTriggerRuntime = (deps) => {
338
304
 
339
305
  const sessionId = extractSessionIdFromPayload(payload);
340
306
  const notificationDirectory = extractDirectoryFromPayload(payload);
307
+ if ((payload.type === 'session.updated' || payload.type === 'session.created') && sessionId) {
308
+ const title = payload.properties?.info?.title;
309
+ if (
310
+ typeof title === 'string'
311
+ && title.trim()
312
+ && !(await shouldSkipSystemSessionNotification(sessionId, notificationDirectory))
313
+ ) {
314
+ try {
315
+ await sendLiveActivityEnd?.({ sessionId, title: title.trim() });
316
+ } catch (error) {
317
+ console.warn('[Live Activity] title update failed:', error?.message ?? error);
318
+ }
319
+ }
320
+ }
341
321
  if ((payload.type === 'session.idle' || payload.type === 'session.error') && sessionId) {
342
322
  const error = payload.properties?.error;
343
323
  const errorText = typeof error?.message === 'string'
@@ -404,13 +384,13 @@ export const createNotificationTriggerRuntime = (deps) => {
404
384
  }
405
385
  lastReadyNotificationAt.set(sessionId, now);
406
386
 
407
- let title = `${formatMode(info?.mode)} agent is ready`;
408
- let body = `${formatModelId(info?.modelID)} completed the task`;
387
+ let title = 'Task completed';
388
+ let body = '';
409
389
  let sessionName = '';
410
390
 
411
391
  try {
412
392
  const templates = settings.notificationTemplates || {};
413
- const completionTemplate = templates.completion || { title: '{agent_name} is ready', message: '{model_name} completed the task' };
393
+ const completionTemplate = templates.completion || { title: 'Task completed', message: '{session_name}' };
414
394
 
415
395
  const variables = await buildTemplateVariables(payload, sessionId);
416
396
  sessionName = typeof variables.session_name === 'string' ? variables.session_name : sessionName;
@@ -430,8 +410,10 @@ export const createNotificationTriggerRuntime = (deps) => {
430
410
  const resolvedBody = resolveNotificationTemplate(completionTemplate.message, variables);
431
411
  if (resolvedTitle) title = resolvedTitle;
432
412
  if (shouldApplyResolvedTemplateMessage(completionTemplate.message, resolvedBody, variables)) body = resolvedBody;
413
+ if (!body) body = sessionName || resolvedBody || 'Session';
433
414
  } catch (error) {
434
415
  console.warn('[Notification] Template resolution failed, using defaults:', error?.message || error);
416
+ if (!body) body = sessionName || 'Session';
435
417
  }
436
418
 
437
419
  if (settings.nativeNotificationsEnabled) {
@@ -492,12 +474,8 @@ export const createNotificationTriggerRuntime = (deps) => {
492
474
  const header = typeof firstQuestion?.header === 'string' ? firstQuestion.header.trim() : '';
493
475
  const questionText = typeof firstQuestion?.question === 'string' ? firstQuestion.question.trim() : '';
494
476
 
495
- let title = /plan\s*mode/i.test(header)
496
- ? 'Switch to plan mode'
497
- : /build\s*agent/i.test(header)
498
- ? 'Switch to build mode'
499
- : header || 'Input needed';
500
- let body = questionText || 'Agent is waiting for your response';
477
+ let title = 'Needs your answer';
478
+ let body = '';
501
479
  let sessionName = '';
502
480
 
503
481
  try {
@@ -506,14 +484,16 @@ export const createNotificationTriggerRuntime = (deps) => {
506
484
  variables.last_message = questionText || header || '';
507
485
 
508
486
  const templates = settings.notificationTemplates || {};
509
- const questionTemplate = templates.question || { title: 'Input needed', message: '{last_message}' };
487
+ const questionTemplate = templates.question || { title: 'Needs your answer', message: '{session_name}' };
510
488
 
511
489
  const resolvedTitle = resolveNotificationTemplate(questionTemplate.title, variables);
512
490
  const resolvedBody = resolveNotificationTemplate(questionTemplate.message, variables);
513
491
  if (resolvedTitle) title = resolvedTitle;
514
492
  if (shouldApplyResolvedTemplateMessage(questionTemplate.message, resolvedBody, variables)) body = resolvedBody;
493
+ if (!body) body = sessionName || resolvedBody || 'Session';
515
494
  } catch (error) {
516
495
  console.warn('[Notification] Question template resolution failed, using defaults:', error?.message || error);
496
+ if (!body) body = sessionName || 'Session';
517
497
  }
518
498
 
519
499
  if (settings.nativeNotificationsEnabled) {
@@ -618,8 +598,8 @@ export const createNotificationTriggerRuntime = (deps) => {
618
598
  ? sessionTitle.trim()
619
599
  : permissionText || 'Agent is waiting for your approval';
620
600
 
621
- let title = 'Permission required';
622
- let body = fallbackMessage;
601
+ let title = 'Needs permission';
602
+ let body = '';
623
603
  let sessionName = '';
624
604
 
625
605
  try {
@@ -628,14 +608,14 @@ export const createNotificationTriggerRuntime = (deps) => {
628
608
  variables.last_message = fallbackMessage;
629
609
 
630
610
  const templates = settings.notificationTemplates || {};
631
- const questionTemplate = templates.question || { title: 'Permission required', message: '{last_message}' };
611
+ const questionTemplate = templates.question || { title: 'Needs permission', message: '{session_name}' };
632
612
 
633
- const resolvedTitle = resolveNotificationTemplate(questionTemplate.title, variables);
634
613
  const resolvedBody = resolveNotificationTemplate(questionTemplate.message, variables);
635
- if (resolvedTitle) title = resolvedTitle;
636
614
  if (shouldApplyResolvedTemplateMessage(questionTemplate.message, resolvedBody, variables)) body = resolvedBody;
615
+ if (!body) body = sessionName || fallbackMessage || 'Session';
637
616
  } catch (error) {
638
617
  console.warn('[Notification] Permission template resolution failed, using defaults:', error?.message || error);
618
+ if (!body) body = sessionName || fallbackMessage || 'Session';
639
619
  }
640
620
 
641
621
  if (settings.nativeNotificationsEnabled) {
@@ -232,6 +232,28 @@ describe('notification trigger live activity end', () => {
232
232
  expect(sendApnsToAllUiSessions).toHaveBeenCalledTimes(1);
233
233
  });
234
234
 
235
+ it('does not patch live activity titles for child sessions', async () => {
236
+ vi.stubGlobal('fetch', vi.fn(async () => jsonResponse({
237
+ id: 'ses_child',
238
+ parentID: 'ses_parent',
239
+ metadata: {},
240
+ })));
241
+ const { runtime, sendLiveActivityEnd } = createRuntime();
242
+ await runtime.maybeSendPushForTrigger({
243
+ type: 'session.updated',
244
+ properties: {
245
+ directory: '/repo',
246
+ info: {
247
+ id: 'ses_child',
248
+ sessionID: 'ses_child',
249
+ parentID: 'ses_parent',
250
+ title: 'Fixer',
251
+ },
252
+ },
253
+ });
254
+ expect(sendLiveActivityEnd).not.toHaveBeenCalled();
255
+ });
256
+
235
257
  it('suppresses live activity end for child and small-model sessions', async () => {
236
258
  const fetchMock = vi.fn(async (url) => {
237
259
  if (String(url).includes('ses_child')) {
@@ -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
 
@@ -1 +0,0 @@
1
- import{o as e,r as t}from"./rolldown-runtime-C0FnF6B9.js";import{A as n,E as r,t as i,w as a}from"./useUIStore-BXjMQrel.js";import{$t as o,Ot as s,et as c,rt as l,yt as u}from"./persistence-CLUawIlm.js";import{nt as d,rt as f}from"./vendor-base-ui-CnHfUmDN.js";import{r as p}from"./platform-BrncW9ab.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 _}from"./clipboard-C0bgPFn5.js";import{a as v,n as y,s as b}from"./MobileShareBridge-CRpk-w3Q.js";import{Ga as x,Ha as S,Pi as C,Ur as ee,_n as w,aa as T,an as E,hi as D,ho as O,ko as k,mo as A,o as j,qr as M,un as N,vn as P,yn as F}from"./useMobileNavigationStore-DLW9tcn6.js";import{_ as I,a as L,c as R,d as z,f as B,g as te,l as ne,n as re,o as ie,p as ae,r as oe,t as V,v as H,x as U,y as se}from"./MobileDetailNavigation-C_4Y_X61.js";import{i as ce,r as le}from"./useAssistantUIStore-D699Sbdb.js";import{a as ue,i as de,n as W,o as G,r as K,t as q}from"./dialog-Bjnvo5pk.js";import{t as fe}from"./utils-D94hxQYq.js";import{t as pe}from"./AgentAvatar-CecaXP3U.js";import{n as me}from"./Icon-Du1LX11Q.js";import{t as he}from"./button-p6vbd3r6.js";import{i as ge}from"./OverlayScrollbar-oOLMqq2s.js";import{B as _e,I as ve,L as J,V as ye,X as be,t as xe}from"./ChatContainer-BNiQ84dy.js";import{t as Se}from"./ContextPanel-Df7BbJaq.js";import{a as Ce,c as we,l as Te,o as Ee,s as De}from"./shikiHighlight-Bs6Tt3X-.js";var Y=e(f(),1),Oe=m(),X=e=>e.isVSCode||e.isPhoneShell||e.isMobile&&!e.isIPad?`session`:`context-panel`,Z=d(),ke=e=>{let t=(0,Oe.c)(56),{assistant:n,sessionID:r,warning:a,surface:s,onRevertMessage:c,onEditMessage:l,pendingUserMessages:u,onPendingUserMessagesMaterialized:d}=e,{t:f}=_(),{isMobile:m}=ge(),h=n.effectiveWorkspacePath,v;t[0]!==n.sessionGeneration||t[1]!==r?(v={sessionID:r,sessionGeneration:n.sessionGeneration},t[0]=n.sessionGeneration,t[1]=r,t[2]=v):v=t[2];let y=H(n.id,v,s.active);y.data?.pages;let b;t[3]===y.data?.pages?b=t[4]:(b=y.data?.pages??[],t[3]=y.data?.pages,t[4]=b);let x;t[5]===b?x=t[6]:(x=D(b),t[5]=b,t[6]=x);let S=x,C;if(t[7]!==S){C=new Map;for(let e of S){let t=C.get(e.sessionID);C.set(e.sessionID,t===void 0||t===e.directory?e.directory:null)}t[7]=S,t[8]=C}else C=t[8];let ee=C,w;t[9]===y?w=t[10]:(w=async()=>{(y.hasNextPage||y.isFetchNextPageError)&&await y.fetchNextPage()},t[9]=y,t[10]=w);let T=g(w),E=n.mode===`continuous`,O=ve(),k;t[11]===O?k=t[12]:(k=O&&!p(),t[11]=O,t[12]=k);let A=!!k,j;t[13]===A?j=t[14]:(j=(e,t)=>{F(e,t,{phoneShell:A,switchToChat:!0})},t[13]=A,t[14]=j);let M=g(j),N;t[15]!==h||t[16]!==ee||t[17]!==M||t[18]!==r?(N=(e,t)=>{let n=e===r?h:ee.get(e);if(!n||n!==t){P(e,`missing-directory`);return}M(e,t)},t[15]=h,t[16]=ee,t[17]=M,t[18]=r,t[19]=N):N=t[19];let I=g(N),L;t[20]!==m||t[21]!==A||t[22]!==M||t[23]!==f?(L=(e,t)=>{let n=e.trim(),r=t.trim();if(!n){P(e,`missing-session-id`);return}if(!r){P(n,`missing-directory`);return}if(X({isPhoneShell:A,isMobile:m,isIPad:p(),isVSCode:o()})===`session`){M(n,r);return}i.getState().openContextPanelTab(r,{mode:`chat`,dedupeKey:`session:${n}`,label:f(`contextPanel.mode.chat`),readOnly:!0})},t[20]=m,t[21]=A,t[22]=M,t[23]=f,t[24]=L):L=t[24];let R=g(L),z;t[25]===E?z=t[26]:(z={...J,forkSession:!1,mutateSession:E},t[25]=E,t[26]=z);let B;t[27]===l?B=t[28]:(B=l?{onEditMessage:l}:{},t[27]=l,t[28]=B);let te;t[29]!==h||t[30]!==R||t[31]!==c||t[32]!==I||t[33]!==r||t[34]!==s.active||t[35]!==s.surfaceID||t[36]!==B||t[37]!==z?(te={kind:`embedded`,surfaceId:s.surfaceID,sessionId:r,directory:h,active:s.active,capabilities:z,navigateSession:R,onRevertMessage:c,...B,openSourceSession:I},t[29]=h,t[30]=R,t[31]=c,t[32]=I,t[33]=r,t[34]=s.active,t[35]=s.surfaceID,t[36]=B,t[37]=z,t[38]=te):te=t[38];let ne=te,re=y.isError||y.isSuccess&&!y.hasNextPage,ie=y.isLoading||y.isFetchingNextPage,ae;t[39]!==T||t[40]!==re||t[41]!==S||t[42]!==ie?(ae={entries:S,complete:re,loading:ie,fetchPrevious:T},t[39]=T,t[40]=re,t[41]=S,t[42]=ie,t[43]=ae):ae=t[43];let oe;t[44]!==h||t[45]!==d||t[46]!==c||t[47]!==u||t[48]!==r||t[49]!==ne||t[50]!==s||t[51]!==ae||t[52]!==a?(oe={sessionId:r,directory:h,composerSurface:s,sessionSurface:ne,warning:a,pendingUserMessages:u,onPendingUserMessagesMaterialized:d,assistantHistory:ae,onRevertMessage:c},t[44]=h,t[45]=d,t[46]=c,t[47]=u,t[48]=r,t[49]=ne,t[50]=s,t[51]=ae,t[52]=a,t[53]=oe):oe=t[53];let V=oe,U;return t[54]===V?U=t[55]:(U=(0,Z.jsx)(xe,{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 L(e);let t=ce.getState().defaultShareAssistant;if(t?.assistantID!==e.id)return;let n=await R();n.serverInstanceID&&t.serverInstanceID===n.serverInstanceID&&ce.getState().setDefaultShareAssistant(null)}function Fe({assistant:e,open:t,onOpenChange:n,onDeleted:r}){let{t:i}=_(),[a,o]=Y.useState(!1),s=e?v(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}=_(),a;t[0]===n?a=t[1]:(a=n?v(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 _=g(h),v;t[2]===d?v=t[3]:(v=()=>{m(!1),d()},t[2]=d,t[3]=v);let y=g(v),b;t[4]===f?b=t[5]:(b=()=>{m(!1),f()},t[4]=f,t[5]=b);let x=g(b),S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(S=e=>{e.preventDefault(),m(!0)},t[6]=S):S=t[6];let C=o?`border-border/50 bg-[var(--surface-elevated)]`:`border-transparent hover:bg-interactive-hover`,ee=!s&&`opacity-65`,w;t[7]!==C||t[8]!==ee?(w=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`,C,ee),t[7]=C,t[8]=ee,t[9]=w):w=t[9];let T;t[10]!==_||t[11]!==o||t[12]!==w?(T=(0,Z.jsx)(`button`,{type:`button`,role:`option`,"aria-selected":o,onClick:_,onContextMenu:S,className:w}),t[10]=_,t[11]=o,t[12]=w,t[13]=T):T=t[13];let E;t[14]!==n||t[15]!==i||t[16]!==r?(E=(0,Z.jsx)(pe,{name:n,emoji:i,size:24,label:r}),t[14]=n,t[15]=i,t[16]=r,t[17]=E):E=t[17];let D;t[18]===r?D=t[19]:(D=(0,Z.jsx)(`span`,{className:`block truncate typography-ui-label font-medium`,children:r}),t[18]=r,t[19]=D);let O;t[20]===a?O=t[21]:(O=(0,Z.jsx)(`span`,{className:`mt-0.5 block truncate typography-micro text-muted-foreground`,children:a}),t[20]=a,t[21]=O);let k;t[22]!==D||t[23]!==O?(k=(0,Z.jsxs)(`span`,{className:`min-w-0 flex-1`,children:[D,O]}),t[22]=D,t[23]=O,t[24]=k):k=t[24];let A;t[25]!==k||t[26]!==T||t[27]!==E?(A=(0,Z.jsxs)(Te,{render:T,children:[E,k]}),t[25]=k,t[26]=T,t[27]=E,t[28]=A):A=t[28];let j;t[29]===Symbol.for(`react.memo_cache_sentinel`)?(j=(0,Z.jsx)(me,{name:`edit`,className:`size-4`}),t[29]=j):j=t[29];let M;t[30]!==c||t[31]!==y?(M=(0,Z.jsxs)(De,{onClick:y,children:[j,c]}),t[30]=c,t[31]=y,t[32]=M):M=t[32];let N;t[33]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,Z.jsx)(we,{}),t[33]=N):N=t[33];let P;t[34]===Symbol.for(`react.memo_cache_sentinel`)?(P=(0,Z.jsx)(me,{name:`delete-bin`,className:`size-4`}),t[34]=P):P=t[34];let F;t[35]!==l||t[36]!==x?(F=(0,Z.jsxs)(De,{onClick:x,className:`text-[var(--status-error)] focus:text-[var(--status-error)] data-[highlighted]:text-[var(--status-error)] [&_svg]:text-[var(--status-error)]`,children:[P,l]}),t[35]=l,t[36]=x,t[37]=F):F=t[37];let I;t[38]!==M||t[39]!==F?(I=(0,Z.jsxs)(Ee,{className:`min-w-[10rem]`,children:[M,N,F]}),t[38]=M,t[39]=F,t[40]=I):I=t[40];let L;return t[41]!==p||t[42]!==A||t[43]!==I?(L=(0,Z.jsxs)(Ce,{open:p,onOpenChange:m,children:[A,I]}),t[41]=p,t[42]=A,t[43]=I,t[44]=L):L=t[44],L},et=({activeOverride:e,onMobileBack:t})=>{let{t:o}=_(),{isMobile:d}=ge(),f=ve(),p=Y.useSyncExternalStore(n,r,r),m=a(),D=i(e=>e.activeMainTab===`assistant`),P=e??D,F=i(e=>e.isMobile),L=d||F,R=I(),V=se(),H=V.data,U=ce(e=>e.assistantByTransport[p]??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(()=>s({transportIdentity:p},`assistant:${G}`),[G,p]),xe=u(J),Ce=k(e=>e.draftAttachmentViews[xe]??Je),we=k(e=>e.drafts[xe]),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&&k.getState().hydrateDraftAttachments(J)},[G,J,Oe]);let X=O(q||null,{enabled:!!q&&P}),Q=A(q||null,{enabled:!!q&&P}),Me=E(K,q||void 0),Pe=N(K,q||void 0),Ie=w(K),ze=be(),[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(o(`assistants.composer.selectionSaveFailed`))};let it=Y.useRef(null);it.current||=new je(nt,e=>rt.current(e));let at=Y.useMemo(()=>({assistantID:G,transportIdentity:p,runtimeGeneration:m}),[G,m,p]),$=it.current,ot=Y.useMemo(()=>({transport:p,assistantID:G}),[G,p]),st=g(async(e,t=p)=>{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(()=>{P&&G&&!K&&ie(G)},[P,G,K]),Y.useEffect(()=>{qe.current++,He(new Map),ct({excludeTransport:p})},[p,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:p,runtimeGeneration:m}).catch(()=>void 0)},[W?.sessionGeneration,G,q,m,K,ot,p]);let lt=g(e=>at.assistantID?$.enqueue(at,e,async({identity:e,selection:t,signal:n})=>{await Ne(e,t,{readSnapshot:()=>B(void 0,e.transportIdentity),ensureSnapshot:e=>ne(e),updateAssistant:te,signal:n,assertAuthoritative:()=>{if($.assertAuthoritative(e),r()!==e.transportIdentity||a()!==e.runtimeGeneration)throw new Ae}})}):Promise.reject(Error(`assistant_unavailable`))),ut=Y.useMemo(()=>ye(Q.data),[Q.data]),dt=g(e=>{if(!W)return;let t=S(ut,W.agent??void 0,e);if(t){let e=x({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(()=>{!P||!G||!K||!q||pt===void 0||ft({sessionID:K,directory:q,sessionGeneration:pt},{force:!0})},[P,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`);T(K,q).some(t=>t?.id===e)&&(await ee(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(!T(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:p,runtimeGeneration:m},i=Be(n),o=await et.current.stageExclusive(i,async()=>{let i=await M(K,e,t,{directory:q,draftKey:J}),o=r()===n.transport&&a()===n.runtimeGeneration,s=o?B(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:()=>i.rollback()};let l=await i.rollback();return l.status===`failed`||l.status===`skipped`?{identity:n,rollback:()=>i.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=C(J,()=>k.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=k.getState(),t=e.draftAttachmentViews[u(J)]??Je,n=e.consumeDraftSyntheticParts(J,b);return n?Ge(n,t):null},restoreSyntheticParts:e=>{(async()=>{let t=k.getState(),n=e.map(e=>({partID:e.partID??c(),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:()=>k.getState().captureDraftRuntime(),getDraft:e=>k.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 _e(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:P,sessionID:K,directory:q,draftKey:J,transportIdentity:p,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 T(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=l(`msg`,n);t.options?.commitStagedMessageEdit&&et.current.clear({transport:p,assistantID:W.id});let i=j({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 ae(W.id,e,r,Ze(t.text,t.parts,t.attachments))}catch(e){throw mt(W.id,[r]),e}if(R.data?.serverInstanceID){let e=v(W.name);y({serverInstanceID:R.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 z(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 re(W.id,e)}},shortcuts:{cycle:dt,new:async()=>{let e=await z(W.id);await st(W.id),await ft(e,{force:!0})},abort:async()=>{await re(W.id,e)},submit:()=>{}}}},[P,W,R.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,p,bt,ut]),Ct=g(()=>{if(de(),f){f.openSettings();return}let e=i.getState();e.setSettingsPage(`assistants`),e.setSettingsDialogOpen(!0)}),wt=g(e=>{le(e,f?{openMobileSettings:f.openSettings}:void 0)}),[Tt,Et]=Y.useState(null),Dt=g(e=>{Et(e)}),Ot=g(e=>{e||Et(null)}),kt=g(()=>{i.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:[L?(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(R.isPending||V.isPending)return jt(`ai-agent`,o(`assistants.state.unavailable`));if(R.isError||!R.data?.supported||!R.data.enabled||!H?.enabled)return jt(`cloud-off`,o(`assistants.state.unavailable`));if(!H.assistants.length)return jt(`ai-agent`,o(`assistants.onboarding.title`),o(`assistants.onboarding.description`),(0,Z.jsx)(he,{onClick:Ct,children:o(`assistants.onboarding.action`)}));if(!W)return jt(`ai-agent`,o(`assistants.state.unavailable`));if(!St)return(0,Z.jsxs)(`div`,{className:`relative flex h-full min-h-0 flex-col bg-background`,children:[L?(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":o(`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=v(W.name),Nt=W.enabled?V.isError?o(`assistants.state.staleSnapshot`):null:o(`assistants.state.assistantDisabled`);return(0,Z.jsxs)(`div`,{className:`relative flex h-full min-h-0 overflow-hidden bg-background`,"data-presentation":`workspace`,children:[L?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:o(`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":o(`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=v(e.name);return(0,Z.jsx)($e,{assistantID:e.id,displayName:n.displayName,avatarEmoji:n.avatarEmoji??void 0,modeLabel:e.mode===`stateless`?o(`assistants.mode.stateless`):o(`assistants.mode.continuous`),selected:t,enabled:e.enabled,editLabel:o(`assistants.menu.edit`),deleteLabel:o(`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`,!L&&`border-l border-border/60`),children:[L?(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`?o(`assistants.conversation.statelessHint`):o(`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})]}),L?null:(0,Z.jsx)(Se,{directory:q||null})]})};export{qe as n,Fe as r,et as t};