@genesislcap/ai-assistant 15.19.0 → 15.19.1

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 (288) hide show
  1. package/package.json +17 -18
  2. package/api-extractor.json +0 -11
  3. package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts +0 -2
  4. package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts.map +0 -1
  5. package/dist/dts/components/chat-driver/chat-driver.invocation-scope.test.d.ts +0 -2
  6. package/dist/dts/components/chat-driver/chat-driver.invocation-scope.test.d.ts.map +0 -1
  7. package/dist/dts/components/chat-driver/chat-driver.test.d.ts +0 -2
  8. package/dist/dts/components/chat-driver/chat-driver.test.d.ts.map +0 -1
  9. package/dist/dts/components/chat-driver/chat-driver.thinking-policy.test.d.ts +0 -2
  10. package/dist/dts/components/chat-driver/chat-driver.thinking-policy.test.d.ts.map +0 -1
  11. package/dist/dts/components/chat-driver/chat-driver.trace-capture.test.d.ts +0 -2
  12. package/dist/dts/components/chat-driver/chat-driver.trace-capture.test.d.ts.map +0 -1
  13. package/dist/dts/components/chat-driver/chat-driver.turn-usage.test.d.ts +0 -2
  14. package/dist/dts/components/chat-driver/chat-driver.turn-usage.test.d.ts.map +0 -1
  15. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.test.d.ts +0 -2
  16. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.test.d.ts.map +0 -1
  17. package/dist/dts/components/orchestrating-driver/orchestrating-driver.budget.test.d.ts +0 -2
  18. package/dist/dts/components/orchestrating-driver/orchestrating-driver.budget.test.d.ts.map +0 -1
  19. package/dist/dts/components/orchestrating-driver/orchestrating-driver.cost.test.d.ts +0 -2
  20. package/dist/dts/components/orchestrating-driver/orchestrating-driver.cost.test.d.ts.map +0 -1
  21. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts +0 -2
  22. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts.map +0 -1
  23. package/dist/dts/components/settings-modal/settings-modal.styles.test.d.ts +0 -2
  24. package/dist/dts/components/settings-modal/settings-modal.styles.test.d.ts.map +0 -1
  25. package/dist/dts/components/settings-modal/settings-modal.template.test.d.ts +0 -2
  26. package/dist/dts/components/settings-modal/settings-modal.template.test.d.ts.map +0 -1
  27. package/dist/dts/config/define-stateful-agent.test.d.ts +0 -2
  28. package/dist/dts/config/define-stateful-agent.test.d.ts.map +0 -1
  29. package/dist/dts/config/validate-providers.test.d.ts +0 -2
  30. package/dist/dts/config/validate-providers.test.d.ts.map +0 -1
  31. package/dist/dts/main/blocked-state.test.d.ts +0 -2
  32. package/dist/dts/main/blocked-state.test.d.ts.map +0 -1
  33. package/dist/dts/main/budget-meter.test.d.ts +0 -2
  34. package/dist/dts/main/budget-meter.test.d.ts.map +0 -1
  35. package/dist/dts/main/cost-session-banking.test.d.ts +0 -2
  36. package/dist/dts/main/cost-session-banking.test.d.ts.map +0 -1
  37. package/dist/dts/main/file-attachments.test.d.ts +0 -2
  38. package/dist/dts/main/file-attachments.test.d.ts.map +0 -1
  39. package/dist/dts/main/interaction-cost.test.d.ts +0 -2
  40. package/dist/dts/main/interaction-cost.test.d.ts.map +0 -1
  41. package/dist/dts/main/main.styles.test.d.ts +0 -2
  42. package/dist/dts/main/main.styles.test.d.ts.map +0 -1
  43. package/dist/dts/main/persistence-broken-sources.test.d.ts +0 -2
  44. package/dist/dts/main/persistence-broken-sources.test.d.ts.map +0 -1
  45. package/dist/dts/main/popout-interaction-gate.test.d.ts +0 -2
  46. package/dist/dts/main/popout-interaction-gate.test.d.ts.map +0 -1
  47. package/dist/dts/state/ai-assistant-slice.test.d.ts +0 -2
  48. package/dist/dts/state/ai-assistant-slice.test.d.ts.map +0 -1
  49. package/dist/dts/state/debug-event-log.test.d.ts +0 -2
  50. package/dist/dts/state/debug-event-log.test.d.ts.map +0 -1
  51. package/dist/dts/state/driver-registry.test.d.ts +0 -2
  52. package/dist/dts/state/driver-registry.test.d.ts.map +0 -1
  53. package/dist/dts/state/interaction-context.test.d.ts +0 -2
  54. package/dist/dts/state/interaction-context.test.d.ts.map +0 -1
  55. package/dist/dts/state/persistence/diagnostics-cursors.test.d.ts +0 -2
  56. package/dist/dts/state/persistence/diagnostics-cursors.test.d.ts.map +0 -1
  57. package/dist/dts/state/persistence/diagnostics.test.d.ts +0 -2
  58. package/dist/dts/state/persistence/diagnostics.test.d.ts.map +0 -1
  59. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts +0 -2
  60. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts.map +0 -1
  61. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts +0 -2
  62. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts.map +0 -1
  63. package/dist/dts/state/persistence/session-persister.test.d.ts +0 -2
  64. package/dist/dts/state/persistence/session-persister.test.d.ts.map +0 -1
  65. package/dist/dts/state/persistence/session-snapshot.test.d.ts +0 -2
  66. package/dist/dts/state/persistence/session-snapshot.test.d.ts.map +0 -1
  67. package/dist/dts/state/persistence/stateful-restore.e2e.test.d.ts +0 -2
  68. package/dist/dts/state/persistence/stateful-restore.e2e.test.d.ts.map +0 -1
  69. package/dist/dts/utils/animation-exclusivity.test.d.ts +0 -2
  70. package/dist/dts/utils/animation-exclusivity.test.d.ts.map +0 -1
  71. package/dist/dts/utils/collect-session-models.test.d.ts +0 -2
  72. package/dist/dts/utils/collect-session-models.test.d.ts.map +0 -1
  73. package/dist/dts/utils/condense-history.test.d.ts +0 -2
  74. package/dist/dts/utils/condense-history.test.d.ts.map +0 -1
  75. package/dist/dts/utils/cost-session-history.test.d.ts +0 -2
  76. package/dist/dts/utils/cost-session-history.test.d.ts.map +0 -1
  77. package/dist/dts/utils/derive-cost-session-title.test.d.ts +0 -2
  78. package/dist/dts/utils/derive-cost-session-title.test.d.ts.map +0 -1
  79. package/dist/dts/utils/flatten-sub-agent-messages.test.d.ts +0 -2
  80. package/dist/dts/utils/flatten-sub-agent-messages.test.d.ts.map +0 -1
  81. package/dist/dts/utils/history-transform.test.d.ts +0 -2
  82. package/dist/dts/utils/history-transform.test.d.ts.map +0 -1
  83. package/dist/dts/utils/message-partition.test.d.ts +0 -2
  84. package/dist/dts/utils/message-partition.test.d.ts.map +0 -1
  85. package/dist/dts/utils/resolve-cost-history-config.test.d.ts +0 -2
  86. package/dist/dts/utils/resolve-cost-history-config.test.d.ts.map +0 -1
  87. package/dist/dts/utils/resolve-preference-baseline.test.d.ts +0 -2
  88. package/dist/dts/utils/resolve-preference-baseline.test.d.ts.map +0 -1
  89. package/dist/dts/utils/strip-agent-handlers.test.d.ts +0 -2
  90. package/dist/dts/utils/strip-agent-handlers.test.d.ts.map +0 -1
  91. package/dist/dts/utils/sum-costs.test.d.ts +0 -2
  92. package/dist/dts/utils/sum-costs.test.d.ts.map +0 -1
  93. package/dist/dts/utils/sum-tokens.test.d.ts +0 -2
  94. package/dist/dts/utils/sum-tokens.test.d.ts.map +0 -1
  95. package/dist/dts/utils/sum-usage.test.d.ts +0 -2
  96. package/dist/dts/utils/sum-usage.test.d.ts.map +0 -1
  97. package/dist/dts/utils/usage-rows.test.d.ts +0 -2
  98. package/dist/dts/utils/usage-rows.test.d.ts.map +0 -1
  99. package/dist/esm/components/chat-driver/chat-driver.compact.test.js +0 -93
  100. package/dist/esm/components/chat-driver/chat-driver.invocation-scope.test.js +0 -238
  101. package/dist/esm/components/chat-driver/chat-driver.test.js +0 -2770
  102. package/dist/esm/components/chat-driver/chat-driver.thinking-policy.test.js +0 -137
  103. package/dist/esm/components/chat-driver/chat-driver.trace-capture.test.js +0 -200
  104. package/dist/esm/components/chat-driver/chat-driver.turn-usage.test.js +0 -268
  105. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.test.js +0 -104
  106. package/dist/esm/components/orchestrating-driver/orchestrating-driver.budget.test.js +0 -312
  107. package/dist/esm/components/orchestrating-driver/orchestrating-driver.cost.test.js +0 -76
  108. package/dist/esm/components/orchestrating-driver/orchestrating-driver.pin.test.js +0 -61
  109. package/dist/esm/components/settings-modal/settings-modal.styles.test.js +0 -80
  110. package/dist/esm/components/settings-modal/settings-modal.template.test.js +0 -91
  111. package/dist/esm/config/define-stateful-agent.test.js +0 -53
  112. package/dist/esm/config/validate-providers.test.js +0 -100
  113. package/dist/esm/main/blocked-state.test.js +0 -1065
  114. package/dist/esm/main/budget-meter.test.js +0 -359
  115. package/dist/esm/main/cost-session-banking.test.js +0 -538
  116. package/dist/esm/main/file-attachments.test.js +0 -164
  117. package/dist/esm/main/interaction-cost.test.js +0 -107
  118. package/dist/esm/main/main.styles.test.js +0 -161
  119. package/dist/esm/main/persistence-broken-sources.test.js +0 -180
  120. package/dist/esm/main/popout-interaction-gate.test.js +0 -54
  121. package/dist/esm/state/ai-assistant-slice.test.js +0 -229
  122. package/dist/esm/state/debug-event-log.test.js +0 -117
  123. package/dist/esm/state/driver-registry.test.js +0 -55
  124. package/dist/esm/state/interaction-context.test.js +0 -78
  125. package/dist/esm/state/persistence/diagnostics-cursors.test.js +0 -30
  126. package/dist/esm/state/persistence/diagnostics.test.js +0 -280
  127. package/dist/esm/state/persistence/session-persistence-provider.test.js +0 -110
  128. package/dist/esm/state/persistence/session-persistence.integration.test.js +0 -113
  129. package/dist/esm/state/persistence/session-persister.test.js +0 -613
  130. package/dist/esm/state/persistence/session-snapshot.test.js +0 -256
  131. package/dist/esm/state/persistence/stateful-restore.e2e.test.js +0 -158
  132. package/dist/esm/utils/animation-exclusivity.test.js +0 -52
  133. package/dist/esm/utils/collect-session-models.test.js +0 -53
  134. package/dist/esm/utils/condense-history.test.js +0 -547
  135. package/dist/esm/utils/cost-session-history.test.js +0 -174
  136. package/dist/esm/utils/derive-cost-session-title.test.js +0 -37
  137. package/dist/esm/utils/flatten-sub-agent-messages.test.js +0 -139
  138. package/dist/esm/utils/history-transform.test.js +0 -158
  139. package/dist/esm/utils/message-partition.test.js +0 -90
  140. package/dist/esm/utils/resolve-cost-history-config.test.js +0 -32
  141. package/dist/esm/utils/resolve-preference-baseline.test.js +0 -69
  142. package/dist/esm/utils/strip-agent-handlers.test.js +0 -81
  143. package/dist/esm/utils/sum-costs.test.js +0 -114
  144. package/dist/esm/utils/sum-tokens.test.js +0 -51
  145. package/dist/esm/utils/sum-usage.test.js +0 -164
  146. package/dist/esm/utils/usage-rows.test.js +0 -189
  147. package/dist/tsconfig.tsbuildinfo +0 -1
  148. package/license.txt +0 -46
  149. package/sandbox/tsconfig.json +0 -8
  150. package/src/channel/ai-activity-bus.ts +0 -209
  151. package/src/channel/ai-activity-channel.ts +0 -146
  152. package/src/chat-driver-node.ts +0 -159
  153. package/src/components/activity-halo/activity-halo.ts +0 -106
  154. package/src/components/agent-picker/agent-picker.constants.ts +0 -2
  155. package/src/components/agent-picker/agent-picker.styles.ts +0 -24
  156. package/src/components/agent-picker/agent-picker.template.ts +0 -54
  157. package/src/components/agent-picker/agent-picker.ts +0 -99
  158. package/src/components/agent-picker/index.ts +0 -1
  159. package/src/components/ai-driver/ai-driver.ts +0 -166
  160. package/src/components/ai-driver/index.ts +0 -1
  161. package/src/components/chat-bubble/chat-bubble.styles.ts +0 -194
  162. package/src/components/chat-bubble/chat-bubble.template.ts +0 -67
  163. package/src/components/chat-bubble/chat-bubble.ts +0 -436
  164. package/src/components/chat-bubble/index.ts +0 -1
  165. package/src/components/chat-driver/align-event-globals.ts +0 -23
  166. package/src/components/chat-driver/chat-driver.compact.test.ts +0 -131
  167. package/src/components/chat-driver/chat-driver.invocation-scope.test.ts +0 -285
  168. package/src/components/chat-driver/chat-driver.test.ts +0 -3679
  169. package/src/components/chat-driver/chat-driver.thinking-policy.test.ts +0 -185
  170. package/src/components/chat-driver/chat-driver.trace-capture.test.ts +0 -251
  171. package/src/components/chat-driver/chat-driver.ts +0 -3925
  172. package/src/components/chat-driver/chat-driver.turn-usage.test.ts +0 -362
  173. package/src/components/chat-driver/index.ts +0 -1
  174. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.styles.ts +0 -7
  175. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.template.ts +0 -6
  176. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.test.ts +0 -144
  177. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.ts +0 -243
  178. package/src/components/chat-interaction-wrapper/index.ts +0 -3
  179. package/src/components/chat-markdown/chat-markdown.ts +0 -89
  180. package/src/components/chat-markdown/index.ts +0 -1
  181. package/src/components/flowing-waves-indicator.ts +0 -286
  182. package/src/components/halo-overlay.ts +0 -184
  183. package/src/components/orchestrating-driver/index.ts +0 -1
  184. package/src/components/orchestrating-driver/orchestrating-driver.budget.test.ts +0 -438
  185. package/src/components/orchestrating-driver/orchestrating-driver.cost.test.ts +0 -107
  186. package/src/components/orchestrating-driver/orchestrating-driver.pin.test.ts +0 -96
  187. package/src/components/orchestrating-driver/orchestrating-driver.ts +0 -813
  188. package/src/components/plasma-orb-indicator.ts +0 -281
  189. package/src/components/popout-manager/index.ts +0 -1
  190. package/src/components/popout-manager/popout-manager.ts +0 -212
  191. package/src/components/settings-modal/index.ts +0 -2
  192. package/src/components/settings-modal/settings-modal.styles.test.ts +0 -94
  193. package/src/components/settings-modal/settings-modal.styles.ts +0 -853
  194. package/src/components/settings-modal/settings-modal.template.test.ts +0 -124
  195. package/src/components/settings-modal/settings-modal.template.ts +0 -943
  196. package/src/components/waves-indicator.ts +0 -241
  197. package/src/config/config.ts +0 -608
  198. package/src/config/define-stateful-agent.test.ts +0 -64
  199. package/src/config/define-stateful-agent.ts +0 -642
  200. package/src/config/fallback-agents.ts +0 -29
  201. package/src/config/index.ts +0 -2
  202. package/src/config/validate-providers.test.ts +0 -148
  203. package/src/config/validate-providers.ts +0 -58
  204. package/src/index.ts +0 -29
  205. package/src/main/blocked-state.test.ts +0 -1444
  206. package/src/main/budget-meter.test.ts +0 -477
  207. package/src/main/cost-session-banking.test.ts +0 -679
  208. package/src/main/file-attachments.test.ts +0 -215
  209. package/src/main/index.ts +0 -3
  210. package/src/main/interaction-cost.test.ts +0 -140
  211. package/src/main/main.styles.test.ts +0 -216
  212. package/src/main/main.styles.ts +0 -995
  213. package/src/main/main.template.ts +0 -1119
  214. package/src/main/main.ts +0 -5432
  215. package/src/main/main.types.ts +0 -225
  216. package/src/main/persistence-broken-sources.test.ts +0 -219
  217. package/src/main/popout-interaction-gate.test.ts +0 -87
  218. package/src/provider/ai-provider-switcher.ts +0 -40
  219. package/src/provider/assistant-app-settings.ts +0 -84
  220. package/src/state/ai-assistant-slice.test.ts +0 -336
  221. package/src/state/ai-assistant-slice.ts +0 -604
  222. package/src/state/debug-event-log.test.ts +0 -154
  223. package/src/state/debug-event-log.ts +0 -358
  224. package/src/state/driver-registry.test.ts +0 -70
  225. package/src/state/driver-registry.ts +0 -79
  226. package/src/state/interaction-context.test.ts +0 -90
  227. package/src/state/interaction-context.ts +0 -101
  228. package/src/state/persistence/build-timeline-entries.ts +0 -66
  229. package/src/state/persistence/diagnostics-cursors.test.ts +0 -53
  230. package/src/state/persistence/diagnostics-cursors.ts +0 -80
  231. package/src/state/persistence/diagnostics.test.ts +0 -346
  232. package/src/state/persistence/diagnostics.ts +0 -220
  233. package/src/state/persistence/index.ts +0 -10
  234. package/src/state/persistence/persister-registry.ts +0 -55
  235. package/src/state/persistence/session-persistence-provider.test.ts +0 -136
  236. package/src/state/persistence/session-persistence-provider.ts +0 -226
  237. package/src/state/persistence/session-persistence.integration.test.ts +0 -141
  238. package/src/state/persistence/session-persister.test.ts +0 -787
  239. package/src/state/persistence/session-persister.ts +0 -917
  240. package/src/state/persistence/session-snapshot.test.ts +0 -352
  241. package/src/state/persistence/session-snapshot.ts +0 -344
  242. package/src/state/persistence/stateful-restore.e2e.test.ts +0 -229
  243. package/src/state/session-store.ts +0 -56
  244. package/src/styles/ai-colours.ts +0 -30
  245. package/src/styles/menu.ts +0 -187
  246. package/src/styles/settings-section.ts +0 -40
  247. package/src/suggestions/chat-suggestions.ts +0 -186
  248. package/src/tags/index.ts +0 -1
  249. package/src/types/ai-chat-widget.ts +0 -67
  250. package/src/types/interaction-context.ts +0 -82
  251. package/src/utils/animated-panel-toggle.ts +0 -62
  252. package/src/utils/animation-exclusivity.test.ts +0 -72
  253. package/src/utils/animation-exclusivity.ts +0 -40
  254. package/src/utils/banked-usage-baselines.ts +0 -90
  255. package/src/utils/collect-session-models.test.ts +0 -82
  256. package/src/utils/collect-session-models.ts +0 -65
  257. package/src/utils/condense-history.test.ts +0 -746
  258. package/src/utils/condense-history.ts +0 -448
  259. package/src/utils/cost-session-history.test.ts +0 -226
  260. package/src/utils/cost-session-history.ts +0 -218
  261. package/src/utils/derive-cost-session-title.test.ts +0 -63
  262. package/src/utils/derive-cost-session-title.ts +0 -76
  263. package/src/utils/flatten-sub-agent-messages.test.ts +0 -163
  264. package/src/utils/flatten-sub-agent-messages.ts +0 -88
  265. package/src/utils/format-usd.ts +0 -26
  266. package/src/utils/history-transform.test.ts +0 -228
  267. package/src/utils/history-transform.ts +0 -163
  268. package/src/utils/index.ts +0 -3
  269. package/src/utils/logger.ts +0 -3
  270. package/src/utils/message-partition.test.ts +0 -129
  271. package/src/utils/message-partition.ts +0 -115
  272. package/src/utils/resolve-cost-history-config.test.ts +0 -38
  273. package/src/utils/resolve-cost-history-config.ts +0 -38
  274. package/src/utils/resolve-preference-baseline.test.ts +0 -84
  275. package/src/utils/resolve-preference-baseline.ts +0 -80
  276. package/src/utils/strip-agent-handlers.test.ts +0 -99
  277. package/src/utils/strip-agent-handlers.ts +0 -53
  278. package/src/utils/sum-costs.test.ts +0 -136
  279. package/src/utils/sum-costs.ts +0 -18
  280. package/src/utils/sum-tokens.test.ts +0 -93
  281. package/src/utils/sum-tokens.ts +0 -68
  282. package/src/utils/sum-usage.test.ts +0 -191
  283. package/src/utils/sum-usage.ts +0 -208
  284. package/src/utils/tool-fold.ts +0 -181
  285. package/src/utils/usage-rows.test.ts +0 -237
  286. package/src/utils/usage-rows.ts +0 -187
  287. package/src/utils/with-timeout.ts +0 -24
  288. package/tsconfig.json +0 -9
@@ -1,281 +0,0 @@
1
- import { css, customElement, GenesisElement, html } from '@genesislcap/web-core';
2
- import {
3
- AI_COLOUR_AMBER,
4
- AI_COLOUR_CYAN,
5
- AI_COLOUR_PINK,
6
- AI_COLOUR_VIOLET,
7
- } from '../styles/ai-colours';
8
-
9
- /**
10
- * Animated "plasma orb" loading indicator — a fixed glowing energy sphere whose
11
- * luminous filaments and swirls drift and rotate inside it, like a plasma ball.
12
- * The globe never resizes; only the energy moves.
13
- *
14
- * Brand-coloured: a violet energy core, a slow cyan/pink tint wash, and a warm
15
- * amber hot-spot — covering all four brand colours.
16
- *
17
- * Visual sibling of the dots loading indicator; interchangeable with the other
18
- * loading styles for the "assistant is working" state.
19
- *
20
- * @example
21
- * ```html
22
- * <ai-plasma-orb-indicator></ai-plasma-orb-indicator>
23
- * ```
24
- *
25
- * @beta
26
- */
27
- @customElement({
28
- name: 'ai-plasma-orb-indicator',
29
- template: html<AiPlasmaOrbIndicator>`
30
- <div class="pulse" role="img" aria-label="Assistant is working">
31
- <div class="plasma">
32
- <div class="swirl1"></div>
33
- <div class="swirl2"></div>
34
- <svg class="filaments" viewBox="0 0 100 100">
35
- <g>
36
- <path d="M8 50 Q50 18 92 50" />
37
- <path d="M50 8 Q82 50 50 92" />
38
- <path d="M18 22 Q52 54 82 80" />
39
- <path d="M82 20 Q48 46 20 82" />
40
- <path d="M12 64 Q50 38 88 34" />
41
- <path d="M30 12 Q55 50 72 88" />
42
- <path d="M14 38 Q50 60 86 62" />
43
- <path d="M66 10 Q44 48 24 90" />
44
- <path d="M10 28 Q56 44 90 72" />
45
- <path d="M88 44 Q46 52 16 76" />
46
- <path d="M40 6 Q58 50 88 86" />
47
- <path d="M22 86 Q46 44 60 8" />
48
- </g>
49
- </svg>
50
- <div class="tint"></div>
51
- <div class="hot"></div>
52
- </div>
53
- <div class="ring-emit"></div>
54
- <div class="ring-emit r2"></div>
55
- </div>
56
- `,
57
- styles: css`
58
- :host {
59
- position: relative;
60
- display: inline-block;
61
- width: 56px;
62
- height: 56px;
63
- }
64
-
65
- /* Authored at the gallery's native 100px size and scaled down so the px
66
- glow/filament geometry keeps its proportions. Absolutely centred so the
67
- overflowing glow/rings don't affect the host's layout box. */
68
- .pulse {
69
- position: absolute;
70
- top: 50%;
71
- left: 50%;
72
- width: 100px;
73
- height: 100px;
74
- transform: translate(-50%, -50%) scale(0.56);
75
- display: flex;
76
- align-items: center;
77
- justify-content: center;
78
- }
79
-
80
- .plasma {
81
- position: relative;
82
- width: 86px;
83
- height: 86px;
84
- border-radius: 50%;
85
- overflow: hidden;
86
- isolation: isolate;
87
- background: radial-gradient(
88
- circle at 50% 40%,
89
- #fdf2ff 0%,
90
- #f3c7fd 14%,
91
- #e362ff 38%,
92
- ${AI_COLOUR_VIOLET} 62%,
93
- #8a0a9c 84%,
94
- #3a0044 100%
95
- );
96
- box-shadow:
97
- 0 0 20px 5px color-mix(in srgb, ${AI_COLOUR_VIOLET}, transparent 20%),
98
- 0 0 48px 12px color-mix(in srgb, ${AI_COLOUR_VIOLET}, transparent 58%),
99
- inset 0 0 22px rgb(255 255 255 / 22%),
100
- inset 0 0 8px rgb(255 255 255 / 50%);
101
- }
102
-
103
- /* bright rim light */
104
- .plasma::after {
105
- content: '';
106
- position: absolute;
107
- inset: 0;
108
- border-radius: 50%;
109
- z-index: 5;
110
- pointer-events: none;
111
- box-shadow:
112
- inset 0 0 6px 1px rgb(245 220 255 / 90%),
113
- inset 0 0 16px color-mix(in srgb, ${AI_COLOUR_VIOLET}, transparent 35%);
114
- }
115
-
116
- /* slow colour shift: washes the orb toward cyan/pink and back */
117
- .tint {
118
- position: absolute;
119
- inset: 0;
120
- border-radius: 50%;
121
- z-index: 4;
122
- pointer-events: none;
123
- background: radial-gradient(
124
- circle at 50% 40%,
125
- color-mix(in srgb, ${AI_COLOUR_CYAN}, white 35%) 0%,
126
- ${AI_COLOUR_CYAN} 45%,
127
- ${AI_COLOUR_PINK} 100%
128
- );
129
- mix-blend-mode: color;
130
- opacity: 0;
131
- animation: plasma-tint 9s ease-in-out infinite;
132
- }
133
- @keyframes plasma-tint {
134
- 0%,
135
- 100% {
136
- opacity: 0;
137
- }
138
- 50% {
139
- opacity: 0.85;
140
- }
141
- }
142
-
143
- /* warm white-hot core highlight (shifts, never resizes the orb) */
144
- .hot {
145
- position: absolute;
146
- left: 50%;
147
- top: 38%;
148
- width: 42px;
149
- height: 36px;
150
- z-index: 4;
151
- border-radius: 50%;
152
- pointer-events: none;
153
- filter: blur(3px);
154
- background: radial-gradient(
155
- circle,
156
- rgb(255 255 255 / 90%) 0%,
157
- color-mix(in srgb, ${AI_COLOUR_AMBER}, white 30%) 42%,
158
- rgb(255 255 255 / 0%) 70%
159
- );
160
- animation: plasma-hot 5s ease-in-out infinite;
161
- }
162
- @keyframes plasma-hot {
163
- 0%,
164
- 100% {
165
- opacity: 0.65;
166
- transform: translate(-50%, -50%) translate(-2px, 1px);
167
- }
168
- 50% {
169
- opacity: 1;
170
- transform: translate(-50%, -50%) translate(3px, -2px);
171
- }
172
- }
173
-
174
- /* swirling radial filaments */
175
- .swirl1,
176
- .swirl2 {
177
- position: absolute;
178
- inset: -25%;
179
- border-radius: 50%;
180
- z-index: 2;
181
- mix-blend-mode: screen;
182
- }
183
- .swirl1 {
184
- background: conic-gradient(
185
- from 0deg,
186
- transparent 0 4deg,
187
- rgb(225 240 255 / 55%) 7deg,
188
- transparent 11deg 58deg,
189
- rgb(190 225 255 / 45%) 64deg,
190
- transparent 70deg 138deg,
191
- rgb(255 255 255 / 50%) 144deg,
192
- transparent 150deg 220deg,
193
- rgb(200 230 255 / 45%) 226deg,
194
- transparent 232deg 300deg,
195
- rgb(255 255 255 / 45%) 306deg,
196
- transparent 312deg 360deg
197
- );
198
- filter: blur(3px);
199
- animation: plasma-spin-cw 9s linear infinite;
200
- }
201
- .swirl2 {
202
- background: conic-gradient(
203
- from 40deg,
204
- transparent 0 30deg,
205
- rgb(180 215 255 / 40%) 36deg,
206
- transparent 42deg 110deg,
207
- rgb(255 255 255 / 40%) 116deg,
208
- transparent 122deg 190deg,
209
- rgb(190 225 255 / 40%) 196deg,
210
- transparent 202deg 280deg,
211
- rgb(255 255 255 / 40%) 286deg,
212
- transparent 292deg 360deg
213
- );
214
- filter: blur(5px);
215
- animation: plasma-spin-ccw 13s linear infinite;
216
- }
217
-
218
- /* curved web filaments */
219
- .filaments {
220
- position: absolute;
221
- inset: 0;
222
- width: 100%;
223
- height: 100%;
224
- z-index: 3;
225
- overflow: visible;
226
- mix-blend-mode: screen;
227
- filter: blur(0.5px);
228
- }
229
- .filaments g {
230
- transform-box: fill-box;
231
- transform-origin: center;
232
- animation: plasma-spin-ccw 18s linear infinite;
233
- }
234
- .filaments path {
235
- fill: none;
236
- stroke: rgb(230 245 255 / 50%);
237
- stroke-width: 0.7;
238
- }
239
-
240
- /* soft light rings emitting outward from the orb */
241
- .ring-emit {
242
- position: absolute;
243
- left: 50%;
244
- top: 50%;
245
- width: 86px;
246
- height: 86px;
247
- transform: translate(-50%, -50%);
248
- border-radius: 50%;
249
- border: 2px solid color-mix(in srgb, ${AI_COLOUR_VIOLET}, transparent 25%);
250
- box-shadow: 0 0 8px color-mix(in srgb, ${AI_COLOUR_VIOLET}, transparent 35%);
251
- pointer-events: none;
252
- z-index: 0;
253
- animation: plasma-emit 2.8s ease-out infinite;
254
- }
255
- .ring-emit.r2 {
256
- animation-delay: 1.4s;
257
- }
258
- @keyframes plasma-emit {
259
- 0% {
260
- transform: translate(-50%, -50%) scale(1);
261
- opacity: 0.7;
262
- }
263
- 100% {
264
- transform: translate(-50%, -50%) scale(1.45);
265
- opacity: 0;
266
- }
267
- }
268
-
269
- @keyframes plasma-spin-cw {
270
- to {
271
- transform: rotate(360deg);
272
- }
273
- }
274
- @keyframes plasma-spin-ccw {
275
- to {
276
- transform: rotate(-360deg);
277
- }
278
- }
279
- `,
280
- })
281
- export class AiPlasmaOrbIndicator extends GenesisElement {}
@@ -1 +0,0 @@
1
- export * from './popout-manager';
@@ -1,212 +0,0 @@
1
- import { customElement, GenesisElement, html, observable } from '@genesislcap/web-core';
2
- import { agenticActivityBus } from '../../channel/ai-activity-bus';
3
-
4
- /**
5
- * Contract for pages that support docking the AI assistant.
6
- * Register an implementation with {@link getAiPopoutManager} on mount and deregister on unmount.
7
- *
8
- * @beta
9
- */
10
- export interface AiDockProvider {
11
- /**
12
- * Called when the user expands the bubble. The provider **moves the given
13
- * element** into its layout — e.g. via a layout factory that re-parents it into
14
- * a pane. It is the ONE live assistant element, so it must be moved by reference,
15
- * **not cloned** (a clone would be a second, dead instance). Session state
16
- * survives the move because it lives in module-level registries, not the element.
17
- */
18
- onDock(element: HTMLElement): Promise<void>;
19
- /**
20
- * Called when the user collapses the panel or before navigation. By the time
21
- * this runs the manager has already moved the assistant element back into the
22
- * bubble, so the provider only needs to tear down its now-empty layout slot.
23
- */
24
- onUndock(): Promise<void>;
25
- /**
26
- * Called by `collapseIfDocked` before navigation. The provider is responsible for
27
- * finding the docked assistant element and calling `handlePopout()` on it, which
28
- * publishes `chat-popin` and returns the assistant to the bubble.
29
- */
30
- initiateCollapse(): void;
31
- }
32
-
33
- /**
34
- * App-shell component that owns the pop-out/pop-in lifecycle for the AI assistant bubble.
35
- *
36
- * @remarks
37
- * Place this in the persistent app shell, wrapping a `foundation-ai-chat-bubble` that
38
- * contains an AI assistant element in the `dialog-content` slot.
39
- *
40
- * GENC-1351 (Option A — single element): rather than cloning a second assistant to
41
- * dock, this manager **moves the one real element** between the bubble and the page
42
- * layout. One connected instance means no dual-view coordination (no shared-driver
43
- * unwire/rewire, host election, or duplicated side-effects); the session survives the
44
- * move because the driver/store/persister live in module-level registries keyed by the
45
- * element's identity.
46
- *
47
- * Pages that support docking call `aiPopoutManager.registerDockProvider()` on mount
48
- * and `aiPopoutManager.deregisterDockProvider()` on unmount.
49
- *
50
- * @example
51
- * ```html
52
- * <foundation-ai-popout-manager>
53
- * <foundation-ai-chat-bubble title="My Assistant">
54
- * <my-assistant slot="dialog-content"></my-assistant>
55
- * </foundation-ai-chat-bubble>
56
- * </foundation-ai-popout-manager>
57
- * ```
58
- *
59
- * @beta
60
- */
61
- @customElement({
62
- name: 'foundation-ai-popout-manager',
63
- template: html`
64
- <slot></slot>
65
- `,
66
- })
67
- export class FoundationAiPopoutManager extends GenesisElement {
68
- /** True when a dock provider is registered — controls expand button visibility. */
69
- @observable canDock = false;
70
-
71
- /**
72
- * The single assistant element. Captured while it's in the bubble slot and held
73
- * across the move (it's the same instance whether docked or in the bubble), so
74
- * pop-in can re-home it even though it's no longer a child of this manager.
75
- */
76
- private assistantEl: HTMLElement | null = null;
77
- private dockProvider: AiDockProvider | null = null;
78
- private isDocked = false;
79
- private unsubBus?: () => void;
80
-
81
- connectedCallback() {
82
- super.connectedCallback();
83
- // oxlint-disable-next-line typescript/no-this-alias -- module-level singleton, not a local alias
84
- _aiPopoutManager = this;
85
-
86
- this.assistantEl = this.findAssistant();
87
-
88
- const unsubPopout = agenticActivityBus.subscribe('chat-popout', async () => {
89
- if (this.isDocked || !this.dockProvider) return;
90
- const el = (this.assistantEl ??= this.findAssistant());
91
- if (!el) return;
92
- this.isDocked = true;
93
- _aiAssistantDocked = true;
94
- this.syncBubbleVisibility();
95
- // Reflect the new location on the assistant so its header shows the "collapse"
96
- // affordance. This is now purely cosmetic — the element stays wired across the
97
- // move, so an async mode-forward by a wrapper element can't break it.
98
- el.setAttribute('popout-mode', 'collapse');
99
- // Hand the ONE real element to the page; the provider moves it into its layout.
100
- await this.dockProvider.onDock(el);
101
- });
102
-
103
- const unsubPopin = agenticActivityBus.subscribe('chat-popin', async () => {
104
- if (!this.isDocked) return;
105
- this.isDocked = false;
106
- _aiAssistantDocked = false;
107
- // Re-home the assistant into the bubble BEFORE the provider tears down its
108
- // layout slot — its removeItems (or equivalent) would otherwise destroy the
109
- // moved element.
110
- const bubble = this.querySelector('foundation-ai-chat-bubble');
111
- if (this.assistantEl && bubble) {
112
- this.assistantEl.setAttribute('popout-mode', 'expand');
113
- this.assistantEl.setAttribute('slot', 'dialog-content');
114
- bubble.appendChild(this.assistantEl);
115
- }
116
- this.syncBubbleVisibility();
117
- await this.dockProvider?.onUndock();
118
- });
119
-
120
- this.unsubBus = () => {
121
- unsubPopout();
122
- unsubPopin();
123
- };
124
- this.syncBubbleVisibility();
125
- }
126
-
127
- disconnectedCallback() {
128
- super.disconnectedCallback();
129
- this.unsubBus?.();
130
- this.unsubBus = undefined;
131
- _aiPopoutManager = undefined;
132
- }
133
-
134
- /** Locate the assistant element currently slotted into the bubble. */
135
- private findAssistant(): HTMLElement | null {
136
- const bubble = this.querySelector('foundation-ai-chat-bubble');
137
- return (bubble?.querySelector('[slot="dialog-content"]') as HTMLElement | null) ?? null;
138
- }
139
-
140
- /**
141
- * Register an externally-created assistant element and its docked state. For
142
- * single-element hosts that create the assistant directly in a layout pane (rather
143
- * than statically in the bubble), so the manager tracks the one element, whether it's
144
- * currently docked (for pop-in re-homing), reflects the right `popout-mode` on it
145
- * (drives the header button), and hides the empty bubble.
146
- */
147
- adoptAssistant(el: HTMLElement, docked: boolean): void {
148
- this.assistantEl = el;
149
- this.isDocked = docked;
150
- _aiAssistantDocked = docked;
151
- el.setAttribute('popout-mode', docked ? 'collapse' : 'expand');
152
- this.syncBubbleVisibility();
153
- }
154
-
155
- /** Hide the floating bubble unless it currently contains the assistant. */
156
- private syncBubbleVisibility(): void {
157
- const bubble = this.querySelector('foundation-ai-chat-bubble') as HTMLElement | null;
158
- if (!bubble) return;
159
- const hasAssistant = !!bubble.querySelector('[slot="dialog-content"]');
160
- bubble.style.display = this.isDocked || !hasAssistant ? 'none' : '';
161
- }
162
-
163
- canDockChanged() {
164
- const el = (this.assistantEl ??= this.findAssistant());
165
- if (this.canDock) {
166
- el?.setAttribute('popout-mode', this.isDocked ? 'collapse' : 'expand');
167
- } else {
168
- el?.removeAttribute('popout-mode');
169
- }
170
- }
171
-
172
- registerDockProvider(provider: AiDockProvider): void {
173
- this.dockProvider = provider;
174
- this.canDock = true;
175
- }
176
-
177
- deregisterDockProvider(): void {
178
- this.isDocked = false;
179
- _aiAssistantDocked = false;
180
- this.dockProvider = null;
181
- this.canDock = false;
182
- }
183
-
184
- /**
185
- * If the assistant is currently docked, collapses it back into the bubble.
186
- * Await this in `onBeforeNavButtonClick` to ensure cleanup before navigation.
187
- */
188
- collapseIfDocked(): Promise<void> {
189
- if (!this.isDocked || !this.dockProvider) return Promise.resolve();
190
- this.dockProvider.initiateCollapse();
191
- return Promise.resolve();
192
- }
193
- }
194
-
195
- let _aiPopoutManager: FoundationAiPopoutManager | undefined;
196
- /** Whether the assistant is currently docked in the layout panel (vs bubble-only). */
197
- let _aiAssistantDocked = false;
198
-
199
- /** True when the assistant is active in the layout panel (docked) rather than the bubble. */
200
- export function isAiAssistantDocked(): boolean {
201
- return _aiAssistantDocked;
202
- }
203
-
204
- /**
205
- * Returns the active `FoundationAiPopoutManager` instance, or `undefined` if none is mounted.
206
- * Import this in pages to call `registerDockProvider` / `deregisterDockProvider`.
207
- *
208
- * @beta
209
- */
210
- export function getAiPopoutManager(): FoundationAiPopoutManager | undefined {
211
- return _aiPopoutManager;
212
- }
@@ -1,2 +0,0 @@
1
- export { SettingsModalTemplate, type SettingsModalTab } from './settings-modal.template';
2
- export { settingsModalStyles } from './settings-modal.styles';
@@ -1,94 +0,0 @@
1
- import { assert, createLogicSuite } from '@genesislcap/foundation-testing';
2
- import { settingsModalStyles } from './settings-modal.styles';
3
-
4
- // GENC-1464 budget meter — the styling invariants a reviewer would otherwise
5
- // have to catch by eye, following main.styles.test.ts (see there for why CSS
6
- // gets asserted from the generated text at all, and for the scoping lesson:
7
- // these assertions are about the BUDGET rules only, not a global style policy).
8
- //
9
- // 1. Design-system tokens are consumed UNFALLBACKED — the #2411/#2436 review
10
- // rule. Every token the meter reads ships a DS default, so a
11
- // `var(--token, fallback)` is dead code at best and a silently-broken
12
- // token name at worst.
13
- // 2. The meter's row anatomy is SHARED with the context indicator via grouped
14
- // selectors, not copied. The two indicators are siblings by design;
15
- // copied declarations would let them drift apart one edit at a time, which
16
- // is exactly what the grouping was chosen to make impossible.
17
-
18
- const suite = createLogicSuite('settings-modal.styles budget-meter rules');
19
-
20
- /**
21
- * The generated stylesheet text, flattened recursively — `css` composes nested
22
- * `ElementStyles`, and a shallow read can return almost nothing, making every
23
- * negative assertion below pass vacuously. The first test guards that.
24
- */
25
- const flatten = (value: unknown): string => {
26
- if (typeof value === 'string') return value;
27
- if (Array.isArray(value)) return value.map(flatten).join('\n');
28
- const nested = (value as { styles?: unknown } | null | undefined)?.styles;
29
- return nested ? flatten(nested) : '';
30
- };
31
-
32
- /**
33
- * Comments stripped before matching: the assertions below are about
34
- * DECLARATIONS, and the sheet's own prose legitimately mentions the very
35
- * pattern (`var(--x, y)`) the negative assertion hunts for.
36
- */
37
- const cssText = flatten(settingsModalStyles).replace(/\/\*[\s\S]*?\*\//g, '');
38
-
39
- /** Every declaration block whose selector mentions `.settings-budget-`, joined. */
40
- const budgetRules = (cssText.match(/[^{}]*\.settings-budget-[^{}]*\{[^}]*\}/g) ?? []).join('\n');
41
-
42
- suite('the budget rules were extracted as text (guards the assertions below)', () => {
43
- assert.ok(cssText.includes('.settings-budget-usage'), 'the meter container rule is in the sheet');
44
- assert.ok(budgetRules.length > 0, 'the extraction found the budget rules');
45
- });
46
-
47
- suite('the meter consumes design-system tokens without dead fallbacks', () => {
48
- // One structural probe rather than a per-token list: ANY `var(--x,` inside a
49
- // budget rule is a fallback, and the meter reads only tokens that ship DS
50
- // defaults (--design-unit, --neutral-foreground-*), so there is no legitimate
51
- // fallback for this scope. Scoped to the budget rules on purpose — see
52
- // main.styles.test.ts for why a whole-sheet grep is the wrong test.
53
- assert.not.ok(/var\(--[a-z-]+\s*,/.test(budgetRules), 'no var(--token, fallback) in the meter');
54
- assert.ok(budgetRules.includes('var(--design-unit)'), 'and it does consume tokens');
55
- });
56
-
57
- suite('every meter row sits on one shared rhythm', () => {
58
- // The 4/2/2 fix. `.settings-modal-section-body` gaps at 4 units and the
59
- // budget meter at 2, so an unwrapped context indicator sat 4 units above the
60
- // FIRST vendor row while the vendor rows sat 2 apart — three visually
61
- // identical meter rows, unevenly spaced. Both meters now live in
62
- // `.settings-usage-meters`, which must carry the SAME gap as the meter it
63
- // wraps: asserted as ONE grouped rule, so the two cannot drift to different
64
- // rhythms. (settings-modal.template.test.ts pins the other half — that the
65
- // wrapper is conditional, so a host with no meters pays no stray gap for it.)
66
- const shared = /\.settings-usage-meters\s*,\s*\.settings-budget-usage\s*\{([^}]*)\}/.exec(
67
- cssText,
68
- );
69
- assert.ok(shared, '.settings-usage-meters is grouped with .settings-budget-usage');
70
- assert.ok(shared![1].includes('flex-direction: column'), 'the shared container is a column');
71
- assert.ok(
72
- shared![1].includes('gap: calc(var(--design-unit) * 2px)'),
73
- 'gapped at the meter rhythm (2 units), not the section body 4',
74
- );
75
- });
76
-
77
- suite("the meter shares the context indicator's row anatomy by grouped selector", () => {
78
- // The invariant is the SHARING, not the shape: each budget class must sit in
79
- // the same selector list as its context sibling, so restyling one restyles
80
- // both and the two indicators cannot drift apart.
81
- const sharedPairs: Array<[string, string]> = [
82
- ['.settings-context-header', '.settings-budget-header'],
83
- ['.settings-context-label', '.settings-budget-label'],
84
- ['.settings-context-tokens', '.settings-budget-figures'],
85
- ];
86
- for (const [contextClass, budgetClass] of sharedPairs) {
87
- const grouped = new RegExp(
88
- `${contextClass.replace(/\./g, '\\.')}\\s*,\\s*${budgetClass.replace(/\./g, '\\.')}\\s*\\{`,
89
- );
90
- assert.ok(grouped.test(cssText), `${budgetClass} is grouped with ${contextClass}`);
91
- }
92
- });
93
-
94
- suite.run();