@happyvertical/smrt-svelte 0.53.0 → 0.53.2

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 (254) hide show
  1. package/package.json +15 -15
  2. package/dist/__tests__/app-state.test.js +0 -156
  3. package/dist/__tests__/data-surface-bridge.test.js +0 -351
  4. package/dist/__tests__/provider-mode-harness.svelte +0 -14
  5. package/dist/__tests__/provider-mode-harness.svelte.d.ts +0 -11
  6. package/dist/__tests__/provider-mode-harness.svelte.d.ts.map +0 -1
  7. package/dist/__tests__/provider-mode-probe.svelte +0 -13
  8. package/dist/__tests__/provider-mode-probe.svelte.d.ts +0 -8
  9. package/dist/__tests__/provider-mode-probe.svelte.d.ts.map +0 -1
  10. package/dist/__tests__/provider-webmcp-harness.svelte +0 -14
  11. package/dist/__tests__/provider-webmcp-harness.svelte.d.ts +0 -8
  12. package/dist/__tests__/provider-webmcp-harness.svelte.d.ts.map +0 -1
  13. package/dist/__tests__/success-never-text.test.js +0 -100
  14. package/dist/__tests__/warm-clients.test.js +0 -186
  15. package/dist/browser-ai/adapters/llm/bitgpu-inference-backend.test.js +0 -464
  16. package/dist/browser-ai/adapters/llm/webllm-inference-backend.test.js +0 -646
  17. package/dist/browser-ai/adapters/stt/browser-speech.test.js +0 -113
  18. package/dist/browser-ai/adapters/stt/dictation-source.test.js +0 -52
  19. package/dist/browser-ai/svelte/components/__tests__/ModelStatusControl.test.js +0 -172
  20. package/dist/components/board/__tests__/Board.test.js +0 -498
  21. package/dist/components/board/__tests__/BoardSsrHarness.svelte +0 -30
  22. package/dist/components/board/__tests__/BoardSsrHarness.svelte.d.ts +0 -19
  23. package/dist/components/board/__tests__/BoardSsrHarness.svelte.d.ts.map +0 -1
  24. package/dist/components/forms/__tests__/AddressInput.behavior.test.js +0 -216
  25. package/dist/components/forms/__tests__/CheckboxInput.test.js +0 -92
  26. package/dist/components/forms/__tests__/DateRangeInput.behavior.test.js +0 -135
  27. package/dist/components/forms/__tests__/DateTimeInput.behavior.test.js +0 -113
  28. package/dist/components/forms/__tests__/FileUpload.error-alert.test.js +0 -37
  29. package/dist/components/forms/__tests__/FileUpload.native-form.test.js +0 -249
  30. package/dist/components/forms/__tests__/FileUpload.test.js +0 -90
  31. package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte +0 -24
  32. package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte.d.ts +0 -10
  33. package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte.d.ts.map +0 -1
  34. package/dist/components/forms/__tests__/Form.behavior.test.js +0 -137
  35. package/dist/components/forms/__tests__/Form.extraction.test.js +0 -68
  36. package/dist/components/forms/__tests__/Form.stt-error.test.js +0 -57
  37. package/dist/components/forms/__tests__/Form.test.js +0 -86
  38. package/dist/components/forms/__tests__/Form.ui-controls.test.js +0 -119
  39. package/dist/components/forms/__tests__/Form.webmcp.test.js +0 -2336
  40. package/dist/components/forms/__tests__/FormMicButton.test.js +0 -92
  41. package/dist/components/forms/__tests__/FormScope.test.js +0 -39
  42. package/dist/components/forms/__tests__/MeasurementInput.behavior.test.js +0 -129
  43. package/dist/components/forms/__tests__/MoneyInput.behavior.test.js +0 -124
  44. package/dist/components/forms/__tests__/NumberInput.behavior.test.js +0 -151
  45. package/dist/components/forms/__tests__/PhoneInput.behavior.test.js +0 -96
  46. package/dist/components/forms/__tests__/SearchInput.test.js +0 -79
  47. package/dist/components/forms/__tests__/SelectInput.behavior.test.js +0 -132
  48. package/dist/components/forms/__tests__/TextInput.behavior.test.js +0 -131
  49. package/dist/components/forms/__tests__/TextareaInput.behavior.test.js +0 -96
  50. package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte +0 -30
  51. package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte.d.ts +0 -7
  52. package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte.d.ts.map +0 -1
  53. package/dist/components/forms/__tests__/async-validation-form.fixture.svelte +0 -19
  54. package/dist/components/forms/__tests__/async-validation-form.fixture.svelte.d.ts +0 -9
  55. package/dist/components/forms/__tests__/async-validation-form.fixture.svelte.d.ts.map +0 -1
  56. package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte +0 -21
  57. package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte.d.ts +0 -8
  58. package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte.d.ts.map +0 -1
  59. package/dist/components/forms/__tests__/composite-inputs-a11y.test.js +0 -69
  60. package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte +0 -27
  61. package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte.d.ts +0 -9
  62. package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte.d.ts.map +0 -1
  63. package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte +0 -48
  64. package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte.d.ts +0 -10
  65. package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte.d.ts.map +0 -1
  66. package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte +0 -26
  67. package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte.d.ts +0 -13
  68. package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte.d.ts.map +0 -1
  69. package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte +0 -52
  70. package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte.d.ts +0 -16
  71. package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte.d.ts.map +0 -1
  72. package/dist/components/forms/__tests__/form-scope.fixture.svelte +0 -30
  73. package/dist/components/forms/__tests__/form-scope.fixture.svelte.d.ts +0 -10
  74. package/dist/components/forms/__tests__/form-scope.fixture.svelte.d.ts.map +0 -1
  75. package/dist/components/forms/__tests__/form-with-fields.fixture.svelte +0 -158
  76. package/dist/components/forms/__tests__/form-with-fields.fixture.svelte.d.ts +0 -51
  77. package/dist/components/forms/__tests__/form-with-fields.fixture.svelte.d.ts.map +0 -1
  78. package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte +0 -24
  79. package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte.d.ts +0 -11
  80. package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte.d.ts.map +0 -1
  81. package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte +0 -105
  82. package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte.d.ts +0 -42
  83. package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte.d.ts.map +0 -1
  84. package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte +0 -84
  85. package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte.d.ts +0 -14
  86. package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte.d.ts.map +0 -1
  87. package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte +0 -44
  88. package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte.d.ts +0 -9
  89. package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte.d.ts.map +0 -1
  90. package/dist/components/forms/__tests__/mic-keyboard-a11y.test.js +0 -74
  91. package/dist/components/forms/__tests__/policy-field.fixture.svelte +0 -35
  92. package/dist/components/forms/__tests__/policy-field.fixture.svelte.d.ts +0 -8
  93. package/dist/components/forms/__tests__/policy-field.fixture.svelte.d.ts.map +0 -1
  94. package/dist/components/forms/__tests__/rich-inputs-a11y.test.js +0 -87
  95. package/dist/components/settings/__tests__/SettingsCatalog.test.js +0 -69
  96. package/dist/components/settings/__tests__/catalog.test.js +0 -46
  97. package/dist/components/workspace/__tests__/AdminShell.responsive.test.js +0 -597
  98. package/dist/components/workspace/__tests__/AdminShell.test.js +0 -572
  99. package/dist/components/workspace/__tests__/RoleShell.test.js +0 -772
  100. package/dist/components/workspace/__tests__/TenantNav.test.js +0 -208
  101. package/dist/components/workspace/__tests__/WorkspaceAccountMenu.test.js +0 -79
  102. package/dist/components/workspace/__tests__/WorkspaceShell.test.js +0 -630
  103. package/dist/components/workspace/__tests__/admin-shell-header-overflow.test.js +0 -25
  104. package/dist/components/workspace/__tests__/admin-shell-hotkeys.test.js +0 -34
  105. package/dist/components/workspace/__tests__/admin-shell-mobile.test.js +0 -217
  106. package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte +0 -52
  107. package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.d.ts +0 -23
  108. package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.d.ts.map +0 -1
  109. package/dist/components/workspace/__tests__/admin-shell-page-contracts.test.js +0 -30
  110. package/dist/components/workspace/__tests__/admin-shell-responsive-state.test.js +0 -184
  111. package/dist/components/workspace/__tests__/admin-shell-settings.test.js +0 -25
  112. package/dist/components/workspace/__tests__/admin-shell-state.test.js +0 -286
  113. package/dist/components/workspace/__tests__/admin-shell-theme-hooks.test.js +0 -36
  114. package/dist/components/workspace/__tests__/breadcrumbs-helpers.test.js +0 -141
  115. package/dist/components/workspace/__tests__/context-forwarding-harness.svelte +0 -45
  116. package/dist/components/workspace/__tests__/context-forwarding-harness.svelte.d.ts +0 -21
  117. package/dist/components/workspace/__tests__/context-forwarding-harness.svelte.d.ts.map +0 -1
  118. package/dist/components/workspace/__tests__/define-tools-dock.test.js +0 -1188
  119. package/dist/components/workspace/__tests__/harness.svelte +0 -25
  120. package/dist/components/workspace/__tests__/harness.svelte.d.ts +0 -14
  121. package/dist/components/workspace/__tests__/harness.svelte.d.ts.map +0 -1
  122. package/dist/components/workspace/__tests__/index.test.js +0 -28
  123. package/dist/components/workspace/__tests__/legacy-index.test.js +0 -9
  124. package/dist/components/workspace/__tests__/manifest-nav-helpers.test.js +0 -24
  125. package/dist/components/workspace/__tests__/manifest-nav.test.js +0 -599
  126. package/dist/components/workspace/__tests__/nav-helpers.test.js +0 -95
  127. package/dist/components/workspace/__tests__/render-harness.svelte +0 -66
  128. package/dist/components/workspace/__tests__/render-harness.svelte.d.ts +0 -32
  129. package/dist/components/workspace/__tests__/render-harness.svelte.d.ts.map +0 -1
  130. package/dist/components/workspace/__tests__/render-tools-dock.test.js +0 -260
  131. package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte +0 -58
  132. package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte.d.ts +0 -16
  133. package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte.d.ts.map +0 -1
  134. package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte +0 -41
  135. package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte.d.ts +0 -13
  136. package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte.d.ts.map +0 -1
  137. package/dist/components/workspace/__tests__/shell-chrome-components.test.js +0 -108
  138. package/dist/components/workspace/__tests__/system-feed.test.js +0 -327
  139. package/dist/components/workspace/__tests__/test-icon.svelte +0 -17
  140. package/dist/components/workspace/__tests__/test-icon.svelte.d.ts +0 -19
  141. package/dist/components/workspace/__tests__/test-icon.svelte.d.ts.map +0 -1
  142. package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte +0 -38
  143. package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte.d.ts +0 -22
  144. package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte.d.ts.map +0 -1
  145. package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts +0 -66
  146. package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts.map +0 -1
  147. package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.js +0 -115
  148. package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.d.ts +0 -15
  149. package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.d.ts.map +0 -1
  150. package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.js +0 -7
  151. package/dist/components/workspace/__tests__/typed-tool-fixture.test.js +0 -115
  152. package/dist/components/workspace/__tests__/use-harness-orphan.svelte +0 -9
  153. package/dist/components/workspace/__tests__/use-harness-orphan.svelte.d.ts +0 -19
  154. package/dist/components/workspace/__tests__/use-harness-orphan.svelte.d.ts.map +0 -1
  155. package/dist/components/workspace/__tests__/use-harness.svelte +0 -23
  156. package/dist/components/workspace/__tests__/use-harness.svelte.d.ts +0 -8
  157. package/dist/components/workspace/__tests__/use-harness.svelte.d.ts.map +0 -1
  158. package/dist/components/workspace/__tests__/use-tools-dock.test.js +0 -33
  159. package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte +0 -43
  160. package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte.d.ts +0 -11
  161. package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte.d.ts.map +0 -1
  162. package/dist/components/workspace/server/__tests__/compose-availability.test.js +0 -383
  163. package/dist/components/workspace/server/__tests__/typed-context-fixture.d.ts +0 -78
  164. package/dist/components/workspace/server/__tests__/typed-context-fixture.d.ts.map +0 -1
  165. package/dist/components/workspace/server/__tests__/typed-context-fixture.js +0 -104
  166. package/dist/hooks/__tests__/stt-consumer.fixture.svelte +0 -25
  167. package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts +0 -15
  168. package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts.map +0 -1
  169. package/dist/hooks/__tests__/stt-ownership-harness.svelte +0 -42
  170. package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts +0 -20
  171. package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts.map +0 -1
  172. package/dist/hooks/__tests__/useSTT-ownership.test.js +0 -102
  173. package/dist/i18n/__tests__/server.spec.js +0 -57
  174. package/dist/internal/logger.test.js +0 -54
  175. package/dist/provider-mode.test.js +0 -86
  176. package/dist/provider-webmcp.test.js +0 -244
  177. package/dist/state/__tests__/app-state-ai-lifecycle.test.js +0 -240
  178. package/dist/state/__tests__/warm-clients.test.js +0 -40
  179. package/dist/web/__tests__/activity-feed-harness.svelte +0 -32
  180. package/dist/web/__tests__/activity-feed-harness.svelte.d.ts +0 -18
  181. package/dist/web/__tests__/activity-feed-harness.svelte.d.ts.map +0 -1
  182. package/dist/web/__tests__/activity-feed.integration.svelte.test.js +0 -190
  183. package/dist/web/__tests__/activity-feed.svelte.test.js +0 -235
  184. package/dist/web/__tests__/assistant-dock.integration.svelte.test.js +0 -204
  185. package/dist/web/__tests__/data-surface-conformance.integration.svelte.test.js +0 -1392
  186. package/dist/web/__tests__/harness.svelte +0 -25
  187. package/dist/web/__tests__/harness.svelte.d.ts +0 -15
  188. package/dist/web/__tests__/harness.svelte.d.ts.map +0 -1
  189. package/dist/web/__tests__/list-data-surface.fixture.svelte +0 -59
  190. package/dist/web/__tests__/list-data-surface.fixture.svelte.d.ts +0 -14
  191. package/dist/web/__tests__/list-data-surface.fixture.svelte.d.ts.map +0 -1
  192. package/dist/web/__tests__/list-data-surface.svelte.test.js +0 -106
  193. package/dist/web/__tests__/list-data-surface.test.js +0 -651
  194. package/dist/web/__tests__/list-sort-surface.fixture.svelte +0 -41
  195. package/dist/web/__tests__/list-sort-surface.fixture.svelte.d.ts +0 -15
  196. package/dist/web/__tests__/list-sort-surface.fixture.svelte.d.ts.map +0 -1
  197. package/dist/web/__tests__/list-sort-surface.svelte.test.js +0 -59
  198. package/dist/web/__tests__/live-collection.svelte.test.js +0 -185
  199. package/dist/web/__tests__/provider-ui-registry.fixture.svelte +0 -43
  200. package/dist/web/__tests__/provider-ui-registry.fixture.svelte.d.ts +0 -13
  201. package/dist/web/__tests__/provider-ui-registry.fixture.svelte.d.ts.map +0 -1
  202. package/dist/web/__tests__/provider-ui-registry.test.js +0 -235
  203. package/dist/web/__tests__/remote-query-harness.svelte +0 -27
  204. package/dist/web/__tests__/remote-query-harness.svelte.d.ts +0 -11
  205. package/dist/web/__tests__/remote-query-harness.svelte.d.ts.map +0 -1
  206. package/dist/web/__tests__/remote-query.svelte.test.js +0 -101
  207. package/dist/web/__tests__/surfaces.child.fixture.svelte +0 -69
  208. package/dist/web/__tests__/surfaces.child.fixture.svelte.d.ts +0 -16
  209. package/dist/web/__tests__/surfaces.child.fixture.svelte.d.ts.map +0 -1
  210. package/dist/web/__tests__/surfaces.fixture.svelte +0 -26
  211. package/dist/web/__tests__/surfaces.fixture.svelte.d.ts +0 -18
  212. package/dist/web/__tests__/surfaces.fixture.svelte.d.ts.map +0 -1
  213. package/dist/web/__tests__/surfaces.svelte.test.js +0 -140
  214. package/dist/web/__tests__/update-available-harness.svelte +0 -46
  215. package/dist/web/__tests__/update-available-harness.svelte.d.ts +0 -22
  216. package/dist/web/__tests__/update-available-harness.svelte.d.ts.map +0 -1
  217. package/dist/web/__tests__/update-available.svelte.test.js +0 -137
  218. package/dist/web/__tests__/view-intent-provider.fixture.svelte +0 -28
  219. package/dist/web/__tests__/view-intent-provider.fixture.svelte.d.ts +0 -13
  220. package/dist/web/__tests__/view-intent-provider.fixture.svelte.d.ts.map +0 -1
  221. package/dist/web/__tests__/view-intent.fixture.svelte +0 -33
  222. package/dist/web/__tests__/view-intent.fixture.svelte.d.ts +0 -15
  223. package/dist/web/__tests__/view-intent.fixture.svelte.d.ts.map +0 -1
  224. package/dist/web/__tests__/view-intent.intents.d.ts +0 -14
  225. package/dist/web/__tests__/view-intent.intents.d.ts.map +0 -1
  226. package/dist/web/__tests__/view-intent.intents.js +0 -38
  227. package/dist/web/__tests__/view-intent.svelte.test.js +0 -244
  228. package/dist/web/__tests__/webmcp-composed.child.fixture.svelte +0 -73
  229. package/dist/web/__tests__/webmcp-composed.child.fixture.svelte.d.ts +0 -8
  230. package/dist/web/__tests__/webmcp-composed.child.fixture.svelte.d.ts.map +0 -1
  231. package/dist/web/__tests__/webmcp-composed.fixture.svelte +0 -52
  232. package/dist/web/__tests__/webmcp-composed.fixture.svelte.d.ts +0 -12
  233. package/dist/web/__tests__/webmcp-composed.fixture.svelte.d.ts.map +0 -1
  234. package/dist/web/__tests__/webmcp-composed.integration.svelte.test.js +0 -251
  235. package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte +0 -16
  236. package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte.d.ts +0 -19
  237. package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte.d.ts.map +0 -1
  238. package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte +0 -11
  239. package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte.d.ts +0 -8
  240. package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte.d.ts.map +0 -1
  241. package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte +0 -20
  242. package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte.d.ts +0 -7
  243. package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte.d.ts.map +0 -1
  244. package/dist/web/__tests__/webmcp-harness-unannotated.svelte +0 -14
  245. package/dist/web/__tests__/webmcp-harness-unannotated.svelte.d.ts +0 -19
  246. package/dist/web/__tests__/webmcp-harness-unannotated.svelte.d.ts.map +0 -1
  247. package/dist/web/__tests__/webmcp-harness.svelte +0 -18
  248. package/dist/web/__tests__/webmcp-harness.svelte.d.ts +0 -7
  249. package/dist/web/__tests__/webmcp-harness.svelte.d.ts.map +0 -1
  250. package/dist/web/__tests__/webmcp-ssr.fixture.svelte +0 -13
  251. package/dist/web/__tests__/webmcp-ssr.fixture.svelte.d.ts +0 -19
  252. package/dist/web/__tests__/webmcp-ssr.fixture.svelte.d.ts.map +0 -1
  253. package/dist/web/__tests__/webmcp-ui.test.js +0 -723
  254. package/dist/web/__tests__/webmcp.test.js +0 -234
@@ -1,235 +0,0 @@
1
- /**
2
- * Unit tests for the AdminShell activity feed adapter's reconciliation core
3
- * (#1779).
4
- *
5
- * These exercise {@link ActivityFeedReconciler} — the pure diff between a set of
6
- * live rows and the shell activity registry — against a REAL {@link ShellState}.
7
- * Per repo policy nothing here is mocked: the shell, its activity events, and
8
- * the mapping are all real; the reconciler is fed plain row arrays that stand in
9
- * for successive live-collection ticks (`liveCollection`'s engine is exercised
10
- * separately in `activity-feed.integration.svelte.test.ts`). This isolates the
11
- * mapping / create-update-remove / ownership behavior the adapter guarantees.
12
- */
13
- import { afterEach, describe, expect, it } from 'vitest';
14
- import { createShellState } from '../../components/workspace/admin-shell/state.svelte.js';
15
- import { ActivityFeedReconciler, } from '../activity-feed.svelte.js';
16
- /** Editorial map: a job row → focus-scope activity, or `null` for a draft. */
17
- const mapJob = (row) => {
18
- if (row.draft)
19
- return null;
20
- return {
21
- kind: 'render-job',
22
- scope: 'focus',
23
- label: row.title,
24
- status: row.state,
25
- progress: row.progress ?? null,
26
- };
27
- };
28
- /** Record every activity event the shell emits, for sequence assertions. */
29
- function recordEvents(shell) {
30
- const events = [];
31
- const stop = shell.watchActivities((event) => events.push(event));
32
- return { events, stop };
33
- }
34
- describe('ActivityFeedReconciler', () => {
35
- const teardown = [];
36
- afterEach(() => {
37
- for (const fn of teardown.splice(0))
38
- fn();
39
- });
40
- function setup() {
41
- const shell = createShellState();
42
- const recorded = recordEvents(shell);
43
- teardown.push(recorded.stop);
44
- const reconciler = new ActivityFeedReconciler(shell, mapJob);
45
- return { shell, reconciler, events: recorded.events };
46
- }
47
- it('upserts a shell activity when a row first appears', () => {
48
- const { shell, reconciler, events } = setup();
49
- reconciler.reconcile([
50
- { id: 'job-1', title: 'Render intro', state: 'running', progress: 20 },
51
- ]);
52
- const activities = shell.listActivities();
53
- expect(activities).toHaveLength(1);
54
- expect(activities[0]).toMatchObject({
55
- id: 'job-1',
56
- kind: 'render-job',
57
- scope: 'focus',
58
- label: 'Render intro',
59
- status: 'running',
60
- progress: 20,
61
- });
62
- // The activity id defaults to the row id, and the shell stamped createdAt.
63
- expect(activities[0].createdAt).toBeTruthy();
64
- // A single create event (upsert), no transition/remove.
65
- expect(events.map((e) => e.type)).toEqual(['upsert']);
66
- });
67
- it('updates the activity in place when a row changes (status transition)', () => {
68
- const { shell, reconciler, events } = setup();
69
- reconciler.reconcile([
70
- { id: 'job-1', title: 'Render intro', state: 'running', progress: 20 },
71
- ]);
72
- const createdAt = shell.listActivities()[0].createdAt;
73
- // Same row id, advanced progress + status flip → an UPDATE, not a second
74
- // create, and the shell reports it as a `transition` (status changed).
75
- reconciler.reconcile([
76
- { id: 'job-1', title: 'Render intro', state: 'completed', progress: 100 },
77
- ]);
78
- const activities = shell.listActivities();
79
- expect(activities).toHaveLength(1);
80
- expect(activities[0]).toMatchObject({
81
- id: 'job-1',
82
- status: 'completed',
83
- progress: 100,
84
- });
85
- // createdAt preserved across the update (update went through updateActivity,
86
- // not a fresh upsert that would re-stamp it).
87
- expect(activities[0].createdAt).toBe(createdAt);
88
- expect(events.map((e) => e.type)).toEqual(['upsert', 'transition']);
89
- });
90
- it('performs no shell mutation when a reconcile tick is unchanged', () => {
91
- const { reconciler, events } = setup();
92
- const rows = [
93
- { id: 'job-1', title: 'Render intro', state: 'running', progress: 20 },
94
- ];
95
- reconciler.reconcile(rows);
96
- // Re-feed identical content (a common no-op reactive tick): a new array with
97
- // an equal-but-distinct row object. Must not emit a second event.
98
- reconciler.reconcile([{ ...rows[0] }]);
99
- expect(events.map((e) => e.type)).toEqual(['upsert']);
100
- });
101
- it('removes the activity when its row vanishes from the collection', () => {
102
- const { shell, reconciler, events } = setup();
103
- reconciler.reconcile([
104
- { id: 'job-1', title: 'Render intro', state: 'running' },
105
- { id: 'job-2', title: 'Render outro', state: 'queued' },
106
- ]);
107
- expect(shell.listActivities()).toHaveLength(2);
108
- // job-1 gone from the next tick → removed; job-2 unchanged → left alone.
109
- reconciler.reconcile([
110
- { id: 'job-2', title: 'Render outro', state: 'queued' },
111
- ]);
112
- const remaining = shell.listActivities();
113
- expect(remaining).toHaveLength(1);
114
- expect(remaining[0].id).toBe('job-2');
115
- expect(events.map((e) => e.type)).toEqual([
116
- 'upsert', // job-1 create
117
- 'upsert', // job-2 create
118
- 'remove', // job-1 removed
119
- ]);
120
- });
121
- it('treats a row that maps to null as absent (excluded, then removed when it flips)', () => {
122
- const { shell, reconciler } = setup();
123
- // A draft row maps to null → never becomes an activity.
124
- reconciler.reconcile([
125
- { id: 'job-1', title: 'Draft', state: 'queued', draft: true },
126
- ]);
127
- expect(shell.listActivities()).toHaveLength(0);
128
- // It leaves draft → now an activity appears.
129
- reconciler.reconcile([
130
- { id: 'job-1', title: 'Published', state: 'running' },
131
- ]);
132
- expect(shell.listActivities()).toHaveLength(1);
133
- // It goes back to draft (maps to null again) → activity is removed.
134
- reconciler.reconcile([
135
- { id: 'job-1', title: 'Published', state: 'running', draft: true },
136
- ]);
137
- expect(shell.listActivities()).toHaveLength(0);
138
- });
139
- it('lets the map decouple the activity id from the row id', () => {
140
- const shell = createShellState();
141
- const reconciler = new ActivityFeedReconciler(shell, (row) => ({
142
- id: `activity:${row.id}`,
143
- kind: 'render-job',
144
- scope: 'system',
145
- label: row.title,
146
- status: row.state,
147
- }));
148
- reconciler.reconcile([{ id: 'job-1', title: 'Job', state: 'running' }]);
149
- const activities = shell.listActivities();
150
- expect(activities).toHaveLength(1);
151
- expect(activities[0].id).toBe('activity:job-1');
152
- });
153
- it('routes an activity to the shell edge for its scope', () => {
154
- const { shell, reconciler } = setup();
155
- reconciler.reconcile([{ id: 'job-1', title: 'Job', state: 'running' }]);
156
- // scope 'focus' homes to the right edge (SCOPE_EDGES.focus === 'right').
157
- expect(shell.listActivities({ edge: 'right' })).toHaveLength(1);
158
- });
159
- it('re-homes the activity to the new edge when its scope changes (no explicit edge)', () => {
160
- const shell = createShellState();
161
- // Map keys scope off the row so a later tick can change it; no `edge` set.
162
- const reconciler = new ActivityFeedReconciler(shell, (row) => ({
163
- kind: 'render-job',
164
- // Reuse the unused `draft` flag as a cheap "move to system scope" toggle.
165
- scope: row.draft ? 'system' : 'focus',
166
- label: row.title,
167
- status: row.state,
168
- }));
169
- reconciler.reconcile([{ id: 'job-1', title: 'Job', state: 'running' }]);
170
- // Focus → right edge.
171
- expect(shell.listActivities({ edge: 'right' })).toHaveLength(1);
172
- expect(shell.listActivities({ edge: 'bottom' })).toHaveLength(0);
173
- // Scope flips to system; the map still sets no explicit edge. The activity
174
- // must RE-DERIVE its edge from the new scope (system → bottom), not stay
175
- // pinned to the old right edge.
176
- reconciler.reconcile([
177
- { id: 'job-1', title: 'Job', state: 'running', draft: true },
178
- ]);
179
- expect(shell.listActivities({ edge: 'right' })).toHaveLength(0);
180
- expect(shell.listActivities({ edge: 'bottom' })).toHaveLength(1);
181
- expect(shell.listActivities()[0].scope).toBe('system');
182
- });
183
- it('clears a previously-set optional field when a later mapping drops it', () => {
184
- const shell = createShellState();
185
- // Map emits `message`/`detailHref` only while the job is running.
186
- const reconciler = new ActivityFeedReconciler(shell, (row) => ({
187
- kind: 'render-job',
188
- scope: 'focus',
189
- label: row.title,
190
- status: row.state,
191
- ...(row.state === 'running'
192
- ? { message: 'Rendering frames', detailHref: '/jobs/job-1' }
193
- : {}),
194
- }));
195
- reconciler.reconcile([{ id: 'job-1', title: 'Job', state: 'running' }]);
196
- let activity = shell.listActivities()[0];
197
- expect(activity.message).toBe('Rendering frames');
198
- expect(activity.detailHref).toBe('/jobs/job-1');
199
- // The job completes → the map no longer emits message/detailHref. Those
200
- // stale values must be CLEARED, not retained from the previous mapping.
201
- reconciler.reconcile([{ id: 'job-1', title: 'Job', state: 'completed' }]);
202
- activity = shell.listActivities()[0];
203
- expect(activity.status).toBe('completed');
204
- expect(activity.message).toBeUndefined();
205
- expect(activity.detailHref).toBeUndefined();
206
- });
207
- it('dispose() removes exactly the feed activities and stops reconciling', () => {
208
- const { shell, reconciler, events } = setup();
209
- // An activity from ANOTHER source the feed must never touch.
210
- shell.upsertActivity({
211
- id: 'external-1',
212
- label: 'External',
213
- kind: 'other',
214
- scope: 'app',
215
- status: 'running',
216
- });
217
- reconciler.reconcile([
218
- { id: 'job-1', title: 'Render intro', state: 'running' },
219
- ]);
220
- expect(shell.listActivities()).toHaveLength(2);
221
- reconciler.dispose();
222
- // Only the feed's own activity was retracted; the external one survives.
223
- const remaining = shell.listActivities();
224
- expect(remaining).toHaveLength(1);
225
- expect(remaining[0].id).toBe('external-1');
226
- expect(reconciler.isDisposed).toBe(true);
227
- // Reconciling after dispose is a no-op (no new activities, no events).
228
- const eventsBefore = events.length;
229
- reconciler.reconcile([
230
- { id: 'job-2', title: 'Late job', state: 'running' },
231
- ]);
232
- expect(shell.listActivities()).toHaveLength(1);
233
- expect(events.length).toBe(eventsBefore);
234
- });
235
- });
@@ -1,204 +0,0 @@
1
- // @vitest-environment jsdom
2
- /**
3
- * AssistantDock conformance-style integration test (#2904).
4
- *
5
- * Mirrors `data-surface-conformance.integration.svelte.test.ts` in this
6
- * directory: a real `DataSurfaceRegistry` and a real
7
- * `createAssistantDockController`/`AssistantDock` are composed together;
8
- * only the chat transport and the action client are in-process test doubles
9
- * (`createInMemoryAssistantTransport`, and a thin `actionClient` adapter over
10
- * the registry's own `execute()`), matching that file's stated scope of
11
- * faking only the transport boundary.
12
- *
13
- * Scope note (disclosed deviation from the original test plan): the action
14
- * preview/apply path here is driven directly through
15
- * `createAssistantDockController` rather than by having a fake model reply
16
- * trigger it through the rendered `AssistantDock` DOM — `AssistantDock` has
17
- * no built-in "parse this assistant message as an action proposal" step (no
18
- * such parsing is specified anywhere in #2904's binding decisions), so the
19
- * host application is expected to call `controller.previewAction(...)` from
20
- * its own message-rendering logic. This test still exercises the full
21
- * dock (registry discovery, rendering, send/poll) through the DOM, and
22
- * separately proves the action pathway (preview → confirm → apply → registry
23
- * "command" event) end-to-end against the real registry.
24
- */
25
- import { AssistantDock, createAssistantDockController, createInMemoryAssistantTransport, } from '@happyvertical/smrt-chat/svelte';
26
- import { createDataSurfaceRegistry, } from '@happyvertical/smrt-ui/data-surface';
27
- import { render, screen, waitFor } from '@testing-library/svelte';
28
- import { describe, expect, it } from 'vitest';
29
- const identity = {
30
- surfaceId: 'assistant-dock-orders',
31
- kind: 'table',
32
- subject: { type: 'tenant', id: 'tenant-a' },
33
- };
34
- const descriptor = {
35
- version: 1,
36
- identity,
37
- schemaVersion: 1,
38
- label: 'Orders',
39
- rowKey: 'id',
40
- columns: [
41
- {
42
- id: 'id',
43
- label: 'ID',
44
- capabilities: ['read', 'project'],
45
- role: 'row-key',
46
- },
47
- ],
48
- query: {
49
- modes: ['rows'],
50
- projectableColumnIds: ['id'],
51
- searchableColumnIds: [],
52
- filterableColumnIds: [],
53
- sortableColumnIds: [],
54
- },
55
- actions: [
56
- {
57
- id: 'archive',
58
- label: 'Archive',
59
- selectionScopes: ['explicit-ids'],
60
- requiresConfirmation: true,
61
- },
62
- ],
63
- controls: [{ id: 'data-surface.action.archive', label: 'Archive' }],
64
- limits: { maxQueryRows: 100, maxQueryBytes: 100_000, maxSelectionSize: 100 },
65
- };
66
- function mountRegistryWithOneSurface() {
67
- const registry = createDataSurfaceRegistry();
68
- let revision = 1;
69
- const state = { archived: false };
70
- const unregister = registry.register({
71
- descriptor,
72
- getSnapshot: () => ({
73
- version: 1,
74
- descriptor,
75
- revision,
76
- state: { archived: state.archived },
77
- }),
78
- execute: async (command) => {
79
- // A minimal real mutation: the "archive" action flips `archived` and
80
- // bumps the snapshot revision, which is what makes the registry emit a
81
- // 'command' event other mounted UI can react to.
82
- state.archived = true;
83
- revision += 1;
84
- return {
85
- version: 1,
86
- commandId: command.commandId,
87
- identity: command.identity,
88
- ok: true,
89
- revision,
90
- };
91
- },
92
- });
93
- return { registry, unregister, state: () => state.archived };
94
- }
95
- describe('AssistantDock integration (#2904)', () => {
96
- it('fails closed and shows the no-surfaces notice with an empty registry', async () => {
97
- const registry = createDataSurfaceRegistry();
98
- const transport = createInMemoryAssistantTransport();
99
- render(AssistantDock, { props: { transport, registry } });
100
- await waitFor(() => {
101
- expect(screen.getByText(/Nothing on this page can be changed from the chat/i)).toBeInTheDocument();
102
- });
103
- });
104
- it('discovers a mounted surface via the registry and renders a sent conversation', async () => {
105
- const { registry } = mountRegistryWithOneSurface();
106
- const transport = createInMemoryAssistantTransport({
107
- respond: (_threadId, userMessage) => ({
108
- id: 'assistant-1',
109
- threadId: userMessage.threadId,
110
- content: 'Archived the order.',
111
- role: 'assistant',
112
- createdAt: new Date(),
113
- }),
114
- });
115
- render(AssistantDock, { props: { transport, registry } });
116
- await waitFor(() => {
117
- expect(screen.queryByText(/Nothing on this page can be changed from the chat/i)).not.toBeInTheDocument();
118
- });
119
- const thread = await transport.createThread('Order question');
120
- // Drive the same controller the component owns internally by exercising
121
- // the transport directly (the composer's own send() path is covered at
122
- // the unit level in packages/chat); here we assert the descriptor is
123
- // visible to a controller built against this exact registry instance.
124
- const controller = createAssistantDockController({ transport, registry });
125
- await controller.openThread(thread.id);
126
- // Cycle-3 second final finding 1: an attached file must round-trip onto
127
- // the sent message, not just the message text — this is the surface
128
- // that previously rendered nothing for message.attachments.
129
- await controller.send('please archive this order', [
130
- { id: 'att-1', name: 'order-details.pdf' },
131
- ]);
132
- await waitFor(() => {
133
- expect(controller.messages.some((m) => m.content === 'Archived the order.')).toBe(true);
134
- });
135
- const sentMessage = controller.messages.find((m) => m.content === 'please archive this order');
136
- expect(sentMessage?.attachments).toEqual([
137
- { id: 'att-1', name: 'order-details.pdf' },
138
- ]);
139
- expect(controller.surfaces).toHaveLength(1);
140
- expect(controller.surfaces[0].surfaceId).toBe('assistant-dock-orders');
141
- controller.dispose();
142
- });
143
- it('drives preview → confirm → apply through the real registry and fires its "command" event', async () => {
144
- const { registry, state } = mountRegistryWithOneSurface();
145
- const events = [];
146
- registry.subscribe((event) => events.push(event));
147
- const actionClient = {
148
- async preview(request) {
149
- // A preview never mutates: assert the surface is untouched.
150
- expect(state()).toBe(false);
151
- return {
152
- version: 1,
153
- requestId: request.requestId,
154
- identity: request.identity,
155
- actionId: request.actionId,
156
- phase: 'preview',
157
- ok: true,
158
- confirmationToken: 'token-1',
159
- };
160
- },
161
- async apply(request) {
162
- const result = await registry.execute({
163
- version: 1,
164
- commandId: request.requestId,
165
- identity: request.identity,
166
- expectedRevision: 1,
167
- controlId: `data-surface.action.${request.actionId}`,
168
- });
169
- return {
170
- version: 1,
171
- requestId: request.requestId,
172
- identity: request.identity,
173
- actionId: request.actionId,
174
- phase: 'apply',
175
- ok: result.ok,
176
- reason: result.ok ? undefined : result.reason,
177
- };
178
- },
179
- };
180
- const controller = createAssistantDockController({
181
- transport: createInMemoryAssistantTransport(),
182
- registry,
183
- actionClient,
184
- });
185
- const requestId = 'archive-req-1';
186
- await controller.previewAction({
187
- version: 1,
188
- requestId,
189
- identity,
190
- actionId: 'archive',
191
- phase: 'preview',
192
- selection: { scope: 'explicit-ids', rowIds: ['order-1'] },
193
- });
194
- expect(controller.actions.get(requestId)?.status).toBe('previewed');
195
- expect(state()).toBe(false); // preview never mutated the surface
196
- // applyAction now takes only requestId — it reuses the idempotencyKey
197
- // minted once by previewAction (binding decision #2904, build phase 2).
198
- await controller.applyAction(requestId);
199
- expect(controller.actions.get(requestId)?.status).toBe('applied');
200
- expect(state()).toBe(true);
201
- expect(events.some((e) => e.type === 'command')).toBe(true);
202
- controller.dispose();
203
- });
204
- });