@happyvertical/smrt-svelte 0.39.10 → 0.39.12

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.
package/AGENTS.md CHANGED
@@ -82,7 +82,8 @@ the top-of-stack, domain-aware pieces:
82
82
  | Forms (`/forms`) | `TextInput`, `Select`, `MoneyInput`, `DateTimeInput`, `Toggle`, `FileUpload`, `AddressInput`, + more (AI-wired inputs use the hooks/browser-ai here) |
83
83
  | Module | `ModulePanel` |
84
84
  | Settings (`/settings`) | `SettingsCatalog`, `paginateSettingsCatalog` |
85
- | Workspace (`/workspace`) | `WorkspaceShell`, `NavTree`, `Breadcrumbs`, `ToolsDock`, `RoleShell` |
85
+ | Workspace (`/workspace`) | `AdminShell`, `ShellState`, `TenantNav`, focus tools, settings, activities, and system/app panels |
86
+ | Legacy workspace (`/workspace/legacy`) | First-generation `ToolsDock` compatibility surface during AdminShell migration |
86
87
 
87
88
  ### Gap primitives & S10 consolidation (L3 #1422)
88
89
 
@@ -120,7 +121,8 @@ library. Which barrel for what:
120
121
  | `Modal`, `ConfirmDialog`, `LoadingOverlay`, `ProgressBar` | `@happyvertical/smrt-svelte/feedback` |
121
122
  | `Container`, `Grid`, `Header`, `Footer`, `PageHeader`, `EmptyState` | `@happyvertical/smrt-svelte/layout` |
122
123
  | Chat message bubble, reaction picker, typing indicator | `@happyvertical/smrt-svelte/chat` |
123
- | Admin shell, nav tree, breadcrumbs, tools dock | `@happyvertical/smrt-svelte/workspace` |
124
+ | Admin shell, tenant navigation, focus tools, settings, and activities | `@happyvertical/smrt-svelte/workspace` |
125
+ | First-generation ToolsDock during AdminShell migration | `@happyvertical/smrt-svelte/workspace/legacy` |
124
126
  | Server-paged settings search, selection, and list/detail layout | `@happyvertical/smrt-svelte/settings` |
125
127
 
126
128
  The package root re-exports `./ui`, `./forms`, etc., so `from
@@ -268,7 +270,9 @@ activities, tenant nav, app/system panels) from `workspace/admin-shell/`.
268
270
  The first-generation workspace family (`WorkspaceShell`, `RoleShell`,
269
271
  `NavTree`, `Breadcrumbs`, `ToolsDock`) remains in source as migration reference
270
272
  only. Do not re-export it from the public `./workspace` barrel just to preserve
271
- compatibility.
273
+ compatibility. Applications that still need ToolsDock during migration may use
274
+ the explicit `@happyvertical/smrt-svelte/workspace/legacy` subpath; keep legacy
275
+ additions isolated there so the canonical workspace surface remains AdminShell.
272
276
 
273
277
  **Principles**:
274
278
  - SvelteKit-agnostic core — no `$app/state` or `$app/navigation` imports
@@ -349,3 +353,13 @@ Recommended pattern: in the consumer's `+server.ts` endpoint that backs
349
353
  unconditionally visible (back-compat). Anytown's hand-coded
350
354
  `apps/dashboard/src/lib/server/content-tool-dock.ts` is a candidate for
351
355
  migration in a follow-up.
356
+
357
+ Legacy ToolsDock treats availability fetch failures as degraded presentation
358
+ state: it preserves the current context's last successful tool IDs, labels,
359
+ and badges. Before the first success, or after a context change, it falls back
360
+ to registered-tool metadata so contextual values do not cross boundaries.
361
+ Consumers can read `dock.availabilityError` to surface the current context's
362
+ failure; a context change or later successful refresh clears the signal, and
363
+ success applies the new snapshot.
364
+ Availability is never an authorization boundary—server operations must still
365
+ enforce permissions.
package/README.md CHANGED
@@ -156,10 +156,19 @@ scaffold adopts AdminShell as its default chrome exactly this way; copy its
156
156
  | `@happyvertical/smrt-ui/data` | DataTable, CollectionList/ContentList, CollectionToolbar |
157
157
  | `@happyvertical/smrt-svelte/registry` | ModuleUIRegistry for agent admin panels |
158
158
  | `@happyvertical/smrt-svelte/workspace` | AdminShell, ShellState, tenant nav, focus tools, settings, activities, and system/app panels |
159
+ | `@happyvertical/smrt-svelte/workspace/legacy` | Opt-in ToolsDock compatibility surface for applications migrating to AdminShell |
159
160
  | `@happyvertical/smrt-svelte/browser-ai` | Browser AI client (STT/TTS/LLM adapters, capability detection) |
160
161
  | `@happyvertical/smrt-svelte/browser-ai/svelte` | Svelte AI components (VoiceInput, CapabilityGate, etc.) |
161
162
  | `@happyvertical/smrt-svelte/styles/tokens.css` | Design tokens CSS |
162
163
 
164
+ Legacy ToolsDock availability is presentation-only, not authorization.
165
+ `fetchAvailability` failures intentionally keep controls usable using the
166
+ current context's last-known-good result, or registered-tool metadata after a
167
+ context change. Every tool operation and server endpoint must independently
168
+ enforce permissions. Consumers can surface current-context degraded state
169
+ through `dock.availabilityError`; a context change or later valid refresh
170
+ clears it.
171
+
163
172
  ### Components by Category
164
173
 
165
174
  **Forms**: `AddressInput`, `CheckboxInput`, `DateRangeInput`, `DateTimeInput`, `FileUpload`, `Form`, `FormGroup`, `FormMicButton`, `Input`, `MeasurementInput`, `MoneyInput`, `NumberInput`, `PhoneInput`, `SearchInput`, `Select`, `SelectInput`, `Textarea`, `TextareaInput`, `TextInput`, `Toggle`
@@ -64,6 +64,7 @@ describe('defineToolsDock', () => {
64
64
  expect(dock.activeTool).toBeNull();
65
65
  expect(dock.layout).toBe('rail');
66
66
  expect(dock.storageKey).toBeNull();
67
+ expect(dock.availabilityError).toBeNull();
67
68
  expect(dock.availableTools.map((t) => t.id)).toEqual(['chat', 'jobs']);
68
69
  });
69
70
  it('open() / close() / toggle() update isOpen and activeTool', () => {
@@ -181,6 +182,37 @@ describe('defineToolsDock', () => {
181
182
  flushSync();
182
183
  expect(dock.availableTools.map((t) => t.id)).toEqual(['jobs']);
183
184
  });
185
+ it('drops stale fetchAvailability failures after a newer success', async () => {
186
+ let rejectFirst = null;
187
+ let resolveSecond = null;
188
+ const fetchAvailability = vi
189
+ .fn()
190
+ .mockImplementationOnce(() => new Promise((_resolve, reject) => {
191
+ rejectFirst = reject;
192
+ }))
193
+ .mockImplementationOnce(() => new Promise((resolve) => {
194
+ resolveSecond = resolve;
195
+ }));
196
+ const { dock } = track(mountDock({
197
+ tools: [
198
+ { id: 'chat', label: 'Chat', component: noopTool },
199
+ { id: 'jobs', label: 'Jobs', component: noopTool },
200
+ ],
201
+ fetchAvailability,
202
+ }));
203
+ dock.setContext({ type: 'A' });
204
+ dock.setContext({ type: 'B' });
205
+ resolveSecond?.([{ id: 'jobs' }]);
206
+ await Promise.resolve();
207
+ await Promise.resolve();
208
+ flushSync();
209
+ rejectFirst?.(new Error('stale failure'));
210
+ await Promise.resolve();
211
+ await Promise.resolve();
212
+ flushSync();
213
+ expect(dock.availableTools.map((tool) => tool.id)).toEqual(['jobs']);
214
+ expect(dock.availabilityError).toBeNull();
215
+ });
184
216
  it('emit / on / unsubscribe', () => {
185
217
  const { dock } = track(mountDock({
186
218
  tools: [{ id: 'chat', label: 'Chat', component: noopTool }],
@@ -272,9 +304,10 @@ describe('defineToolsDock', () => {
272
304
  // `badge: null` is explicit ("clear it"), not a fallback signal.
273
305
  expect(dock.availableTools[0].badge).toBeNull();
274
306
  });
275
- it('handles synchronous throws from fetchAvailability without surfacing them', async () => {
307
+ it('preserves the registered fallback and exposes synchronous availability errors', async () => {
308
+ const failure = new Error('sync boom');
276
309
  const fetchAvailability = vi.fn(() => {
277
- throw new Error('sync boom');
310
+ throw failure;
278
311
  });
279
312
  const { dock } = track(mountDock({
280
313
  tools: [{ id: 'chat', label: 'Chat', component: noopTool }],
@@ -283,10 +316,155 @@ describe('defineToolsDock', () => {
283
316
  // The sync throw must be caught by the wrapped promise chain, not
284
317
  // propagate out of setContext to the caller.
285
318
  expect(() => dock.setContext({ type: 'a' })).not.toThrow();
286
- // The internal `.catch` applies an empty-availability result.
319
+ // The failure is exposed without replacing the safe initial fallback.
320
+ await new Promise((r) => setTimeout(r, 0));
321
+ flushSync();
322
+ expect(dock.availableTools.map((tool) => tool.id)).toEqual(['chat']);
323
+ expect(dock.availabilityError).toBe(failure);
324
+ dock.open('chat');
325
+ flushSync();
326
+ expect(dock.isOpen).toBe(true);
327
+ expect(dock.activeTool).toBe('chat');
328
+ });
329
+ it('exposes a consumable error for a reasonless rejection', async () => {
330
+ const fetchAvailability = vi.fn().mockRejectedValueOnce(undefined);
331
+ const { dock } = track(mountDock({
332
+ tools: [{ id: 'chat', label: 'Chat', component: noopTool }],
333
+ fetchAvailability,
334
+ }));
335
+ dock.setContext({ type: 'route' });
336
+ await new Promise((r) => setTimeout(r, 0));
337
+ flushSync();
338
+ expect(dock.availableTools.map((tool) => tool.id)).toEqual(['chat']);
339
+ expect(dock.availabilityError).toBeInstanceOf(Error);
340
+ expect(dock.availabilityError.message).toContain('without a reason');
341
+ });
342
+ it('preserves last-known-good availability and badges after a rejected refresh', async () => {
343
+ const failure = new Error('availability offline');
344
+ const fetchAvailability = vi
345
+ .fn()
346
+ .mockResolvedValueOnce([
347
+ { id: 'chat', badge: 2 },
348
+ { id: 'jobs', badge: 7 },
349
+ ])
350
+ .mockRejectedValueOnce(failure);
351
+ const { dock } = track(mountDock({
352
+ tools: [
353
+ { id: 'chat', label: 'Chat', component: noopTool },
354
+ { id: 'jobs', label: 'Jobs', component: noopTool },
355
+ ],
356
+ fetchAvailability,
357
+ }));
358
+ dock.setContext({ type: 'route' });
359
+ await new Promise((r) => setTimeout(r, 0));
360
+ flushSync();
361
+ expect(dock.availableTools).toEqual([
362
+ { id: 'chat', label: 'Chat', badge: 2 },
363
+ { id: 'jobs', label: 'Jobs', badge: 7 },
364
+ ]);
365
+ dock.open('jobs');
366
+ dock.refreshAvailability();
367
+ await new Promise((r) => setTimeout(r, 0));
368
+ flushSync();
369
+ expect(dock.availabilityError).toBe(failure);
370
+ expect(dock.availableTools).toEqual([
371
+ { id: 'chat', label: 'Chat', badge: 2 },
372
+ { id: 'jobs', label: 'Jobs', badge: 7 },
373
+ ]);
374
+ expect(dock.isOpen).toBe(true);
375
+ expect(dock.activeTool).toBe('jobs');
376
+ dock.toggle('jobs');
377
+ flushSync();
378
+ expect(dock.isOpen).toBe(false);
379
+ dock.toggle('jobs');
380
+ flushSync();
381
+ expect(dock.isOpen).toBe(true);
382
+ expect(dock.activeTool).toBe('jobs');
383
+ });
384
+ it('preserves last-known-good availability after malformed entries', async () => {
385
+ const fetchAvailability = vi
386
+ .fn()
387
+ .mockResolvedValueOnce([{ id: 'jobs', badge: 4 }])
388
+ .mockResolvedValueOnce([
389
+ { label: 'Missing id' },
390
+ ]);
391
+ const { dock } = track(mountDock({
392
+ tools: [
393
+ { id: 'chat', label: 'Chat', component: noopTool },
394
+ { id: 'jobs', label: 'Jobs', component: noopTool },
395
+ ],
396
+ fetchAvailability,
397
+ }));
398
+ dock.setContext({ type: 'route' });
399
+ await new Promise((r) => setTimeout(r, 0));
400
+ flushSync();
401
+ expect(dock.availableTools).toEqual([
402
+ { id: 'jobs', label: 'Jobs', badge: 4 },
403
+ ]);
404
+ dock.refreshAvailability();
405
+ await new Promise((r) => setTimeout(r, 0));
406
+ flushSync();
407
+ expect(dock.availableTools).toEqual([
408
+ { id: 'jobs', label: 'Jobs', badge: 4 },
409
+ ]);
410
+ expect(dock.availabilityError).toBeInstanceOf(TypeError);
411
+ });
412
+ it('resets contextual availability before a new-context failure', async () => {
413
+ const failure = new Error('tenant B unavailable');
414
+ const fetchAvailability = vi
415
+ .fn()
416
+ .mockResolvedValueOnce([{ id: 'jobs', label: 'Tenant A jobs', badge: 9 }])
417
+ .mockRejectedValueOnce(failure);
418
+ const { dock } = track(mountDock({
419
+ tools: [
420
+ { id: 'chat', label: 'Chat', component: noopTool },
421
+ { id: 'jobs', label: 'Jobs', badge: 1, component: noopTool },
422
+ ],
423
+ fetchAvailability,
424
+ }));
425
+ dock.setContext({ type: 'tenant-a' });
426
+ await new Promise((r) => setTimeout(r, 0));
427
+ flushSync();
428
+ expect(dock.availableTools).toEqual([
429
+ { id: 'jobs', label: 'Tenant A jobs', badge: 9 },
430
+ ]);
431
+ dock.setContext({ type: 'tenant-b' });
432
+ await new Promise((r) => setTimeout(r, 0));
433
+ flushSync();
434
+ expect(dock.availabilityError).toBe(failure);
435
+ expect(dock.availableTools).toEqual([
436
+ { id: 'chat', label: 'Chat', badge: null },
437
+ { id: 'jobs', label: 'Jobs', badge: 1 },
438
+ ]);
439
+ });
440
+ it('recovers after a later successful availability refresh', async () => {
441
+ const failure = new Error('temporary failure');
442
+ const fetchAvailability = vi
443
+ .fn()
444
+ .mockRejectedValueOnce(failure)
445
+ .mockResolvedValueOnce([{ id: 'jobs', badge: 3 }]);
446
+ const { dock } = track(mountDock({
447
+ tools: [
448
+ { id: 'chat', label: 'Chat', component: noopTool },
449
+ { id: 'jobs', label: 'Jobs', component: noopTool },
450
+ ],
451
+ fetchAvailability,
452
+ }));
453
+ dock.setContext({ type: 'route' });
454
+ await new Promise((r) => setTimeout(r, 0));
455
+ flushSync();
456
+ expect(dock.availabilityError).toBe(failure);
457
+ expect(dock.availableTools.map((tool) => tool.id)).toEqual([
458
+ 'chat',
459
+ 'jobs',
460
+ ]);
461
+ dock.refreshAvailability();
287
462
  await new Promise((r) => setTimeout(r, 0));
288
463
  flushSync();
289
- expect(dock.availableTools).toEqual([]);
464
+ expect(dock.availabilityError).toBeNull();
465
+ expect(dock.availableTools).toEqual([
466
+ { id: 'jobs', label: 'Jobs', badge: 3 },
467
+ ]);
290
468
  });
291
469
  describe('refreshAvailability()', () => {
292
470
  it('re-runs fetchAvailability with the current context', async () => {
@@ -0,0 +1,9 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import * as legacyWorkspace from '../legacy.js';
3
+ describe('legacy workspace barrel', () => {
4
+ it('exposes the opt-in ToolsDock compatibility surface', () => {
5
+ expect(legacyWorkspace.ToolsDock).toBeDefined();
6
+ expect(legacyWorkspace.defineToolsDock).toBeDefined();
7
+ expect(legacyWorkspace.useToolsDock).toBeDefined();
8
+ });
9
+ });
@@ -240,4 +240,21 @@ describe('<ToolsDock> rail layout', () => {
240
240
  const empty = target.querySelector('.tools-dock__empty');
241
241
  expect(empty?.textContent).toContain('No tools');
242
242
  });
243
+ it('keeps registered rail controls usable after an initial availability rejection', async () => {
244
+ const target = render({
245
+ tools: [{ id: 'chat', label: 'Chat' }],
246
+ fetchAvailability: async () => {
247
+ throw new Error('temporary availability failure');
248
+ },
249
+ setContextOnMount: { type: 'route' },
250
+ });
251
+ await new Promise((r) => setTimeout(r, 0));
252
+ flushSync();
253
+ const chatButton = target.querySelector('.tools-dock__rail-button');
254
+ expect(chatButton).not.toBeNull();
255
+ chatButton?.click();
256
+ flushSync();
257
+ expect(chatButton?.getAttribute('aria-pressed')).toBe('true');
258
+ expect(target.querySelector('.tools-dock__panel-header h3')?.textContent).toBe('Chat');
259
+ });
243
260
  });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Explicit compatibility entry for the first-generation ToolsDock family.
3
+ *
4
+ * The canonical `@happyvertical/smrt-svelte/workspace` surface is AdminShell.
5
+ * Existing applications that still need ToolsDock while migrating can import
6
+ * this opt-in subpath without adding legacy components back to that barrel.
7
+ */
8
+ export { type DefineToolsDockOptions, defineToolsDock, TOOLS_DOCK_KEY, type ToolsDockInstance, } from './tools-dock/define-tools-dock.svelte.js';
9
+ export { default as ToolsDock } from './tools-dock/ToolsDock.svelte';
10
+ export { tryUseToolsDock, useToolsDock } from './tools-dock/use-tools-dock.js';
11
+ export type { AvailableTool, ToolDef, ToolsDockApi, ToolsDockContext, ToolsDockEvents, } from './types.js';
12
+ //# sourceMappingURL=legacy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy.d.ts","sourceRoot":"","sources":["../../../src/components/workspace/legacy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,sBAAsB,EAC3B,eAAe,EACf,cAAc,EACd,KAAK,iBAAiB,GACvB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC/E,YAAY,EACV,aAAa,EACb,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Explicit compatibility entry for the first-generation ToolsDock family.
3
+ *
4
+ * The canonical `@happyvertical/smrt-svelte/workspace` surface is AdminShell.
5
+ * Existing applications that still need ToolsDock while migrating can import
6
+ * this opt-in subpath without adding legacy components back to that barrel.
7
+ */
8
+ export { defineToolsDock, TOOLS_DOCK_KEY, } from './tools-dock/define-tools-dock.svelte.js';
9
+ export { default as ToolsDock } from './tools-dock/ToolsDock.svelte';
10
+ export { tryUseToolsDock, useToolsDock } from './tools-dock/use-tools-dock.js';
@@ -17,7 +17,7 @@
17
17
  * @example Register a dock and a tool
18
18
  * ```ts
19
19
  * // somewhere in a +layout.svelte:
20
- * import { defineToolsDock } from '@happyvertical/smrt-svelte/workspace';
20
+ * import { defineToolsDock } from '@happyvertical/smrt-svelte/workspace/legacy';
21
21
  * import ChatTool from './ChatTool.svelte';
22
22
  *
23
23
  * const dock = defineToolsDock({
@@ -67,14 +67,25 @@ export interface DefineToolsDockOptions<TData = Record<string, unknown>, TAction
67
67
  /** Registered tools. Order is preserved when rendering the activation rail/topbar. */
68
68
  tools: ToolDef[];
69
69
  /**
70
- * Optional backend-driven gating callback. Returns the subset of tools that
71
- * should be exposed for the current `context`. When omitted, every
72
- * registered tool is treated as available.
70
+ * Optional backend-driven presentation-gating callback. Returns the subset
71
+ * of tools that should be exposed for the current `context`. When omitted,
72
+ * every registered tool is treated as available.
73
+ *
74
+ * This is not an authorization boundary. Failures intentionally keep the
75
+ * dock usable, so every tool operation and server endpoint must enforce its
76
+ * own permissions independently.
73
77
  *
74
78
  * The callback may return tool ids that aren't present in `tools` — these
75
79
  * are ignored. Conversely, tools missing from the callback's response are
76
80
  * hidden from the dock UI.
77
81
  *
82
+ * A thrown error, rejected promise, or malformed response preserves the
83
+ * last-known-good availability for the current context and is exposed
84
+ * through `dock.availabilityError`. Before the first success, and whenever
85
+ * context changes, the fallback is the registered tool set with registered
86
+ * labels and badges. A later valid response clears the error and replaces
87
+ * availability normally.
88
+ *
78
89
  * The `ctx` parameter is typed against the factory's `TData` / `TActions`
79
90
  * generics — narrow them at the factory site for typed access to
80
91
  * `ctx.data` / `ctx.actions` here without manual casts.
@@ -1 +1 @@
1
- {"version":3,"file":"define-tools-dock.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/tools-dock/define-tools-dock.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,OAAO,EACP,YAAY,EACZ,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,eAAO,MAAM,cAAc,eAA4B,CAAC;AAExD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,sBAAsB,CACrC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,SAAS;KACd,CAAC,IAAI,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO;CACrD,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC;IAEjD,sFAAsF;IACtF,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,CAClB,GAAG,EAAE,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAI,KAC1C,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,wFAAwF;IACxF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB,CAChC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,SAAS;KACd,CAAC,IAAI,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO;CACrD,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,CACjD,SAAQ,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gGAAgG;IAChG,OAAO,IAAI,IAAI,CAAC;IAChB,yDAAyD;IACzD,OAAO,IAAI,IAAI,CAAC;CACjB;AAiDD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,SAAS;KACd,CAAC,IAAI,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO;CACrD,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,EAEjD,OAAO,EAAE,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,GAC/C,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAyZpC"}
1
+ {"version":3,"file":"define-tools-dock.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/tools-dock/define-tools-dock.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,OAAO,EACP,YAAY,EACZ,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,eAAO,MAAM,cAAc,eAA4B,CAAC;AAExD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,sBAAsB,CACrC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,SAAS;KACd,CAAC,IAAI,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO;CACrD,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC;IAEjD,sFAAsF;IACtF,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,iBAAiB,CAAC,EAAE,CAClB,GAAG,EAAE,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAI,KAC1C,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,wFAAwF;IACxF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB,CAChC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,SAAS;KACd,CAAC,IAAI,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO;CACrD,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,CACjD,SAAQ,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gGAAgG;IAChG,OAAO,IAAI,IAAI,CAAC;IAChB,yDAAyD;IACzD,OAAO,IAAI,IAAI,CAAC;CACjB;AAiDD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,SAAS;KACd,CAAC,IAAI,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO;CACrD,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,EAEjD,OAAO,EAAE,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,GAC/C,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAgcpC"}
@@ -17,7 +17,7 @@
17
17
  * @example Register a dock and a tool
18
18
  * ```ts
19
19
  * // somewhere in a +layout.svelte:
20
- * import { defineToolsDock } from '@happyvertical/smrt-svelte/workspace';
20
+ * import { defineToolsDock } from '@happyvertical/smrt-svelte/workspace/legacy';
21
21
  * import ChatTool from './ChatTool.svelte';
22
22
  *
23
23
  * const dock = defineToolsDock({
@@ -111,10 +111,34 @@ export function defineToolsDock(options) {
111
111
  // reference equality and avoids the `state_proxy_equality_mismatch`
112
112
  // warning.
113
113
  let rawContextRef = null;
114
- let availableTools = $state(registeredTools.map((t) => ({ id: t.id, label: t.label, badge: t.badge })));
114
+ let availableTools = $state(registeredAvailability());
115
+ let availabilityError = $state(null);
115
116
  // Race-handle: each fetchAvailability call gets a token; only the most
116
117
  // recent token may apply its result.
117
118
  let availabilityToken = 0;
119
+ function registeredAvailability() {
120
+ return registeredTools.map((tool) => ({
121
+ id: tool.id,
122
+ label: tool.label,
123
+ badge: tool.badge,
124
+ }));
125
+ }
126
+ function isAvailableTool(value) {
127
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
128
+ return false;
129
+ }
130
+ const candidate = value;
131
+ if (typeof candidate.id !== 'string' || candidate.id.trim().length === 0) {
132
+ return false;
133
+ }
134
+ if (candidate.label !== undefined && typeof candidate.label !== 'string') {
135
+ return false;
136
+ }
137
+ return (candidate.badge === undefined ||
138
+ candidate.badge === null ||
139
+ typeof candidate.badge === 'string' ||
140
+ (typeof candidate.badge === 'number' && Number.isFinite(candidate.badge)));
141
+ }
118
142
  /**
119
143
  * Set to `true` once the factory has finished wiring the instance. Used
120
144
  * to gate `'dock:change'` emits so handlers can't run before the instance
@@ -297,11 +321,7 @@ export function defineToolsDock(options) {
297
321
  function refreshAvailability() {
298
322
  if (!fetchAvailability) {
299
323
  // Static availability — every registered tool.
300
- applyAvailability(registeredTools.map((t) => ({
301
- id: t.id,
302
- label: t.label,
303
- badge: t.badge,
304
- })));
324
+ applyAvailability(registeredAvailability());
305
325
  return;
306
326
  }
307
327
  const token = ++availabilityToken;
@@ -325,13 +345,21 @@ export function defineToolsDock(options) {
325
345
  .then((result) => {
326
346
  if (token !== availabilityToken)
327
347
  return; // stale
328
- applyAvailability(Array.isArray(result) ? result : []);
348
+ if (!Array.isArray(result) || !result.every(isAvailableTool)) {
349
+ availabilityError = new TypeError('fetchAvailability must resolve to valid AvailableTool entries');
350
+ return;
351
+ }
352
+ availabilityError = null;
353
+ applyAvailability(result);
329
354
  })
330
- .catch(() => {
355
+ .catch((error) => {
331
356
  if (token !== availabilityToken)
332
357
  return;
333
- // On error, surface zero availability rather than stale state.
334
- applyAvailability([]);
358
+ // Preserve the last-known-good snapshot. Before the first successful
359
+ // request this is the safe registered-tool fallback seeded above, so a
360
+ // transient backend failure never makes open()/toggle() inert.
361
+ availabilityError =
362
+ error ?? new Error('fetchAvailability rejected without a reason');
335
363
  });
336
364
  }
337
365
  function persist() {
@@ -432,14 +460,19 @@ export function defineToolsDock(options) {
432
460
  return;
433
461
  rawContextRef = erased;
434
462
  context = erased;
435
- if (fetchAvailability)
463
+ if (fetchAvailability) {
464
+ // A successful snapshot can contain context-specific labels and badges.
465
+ // Reset those to registration metadata before fetching for a new
466
+ // context, so a failure cannot carry tenant/user details across it.
467
+ availabilityError = null;
468
+ applyAvailability(registeredAvailability());
436
469
  refreshAvailability();
470
+ }
437
471
  // Emit AFTER kicking off availability refresh. The refresh is async and
438
472
  // may emit a second event later if it clears `activeTool` — that is
439
473
  // the intended behaviour (one event per observable state transition).
440
- // `contextChanged: true` fires `'dock:context-changed'`; `stateChanged`
441
- // stays false here because `setContext` itself doesn't touch isOpen/
442
- // activeTool (the async availability refresh handles that).
474
+ // `contextChanged: true` fires `'dock:context-changed'`; any observable
475
+ // availability reset above emits its own legacy change event.
443
476
  emitChange({ stateChanged: false, contextChanged: true });
444
477
  }
445
478
  const instance = {
@@ -453,6 +486,9 @@ export function defineToolsDock(options) {
453
486
  get availableTools() {
454
487
  return availableTools;
455
488
  },
489
+ get availabilityError() {
490
+ return availabilityError;
491
+ },
456
492
  // Internal `context` `$state` is typed as the default-generic shape so
457
493
  // the runtime store stays homogeneous. Cast at the public boundary —
458
494
  // structurally a `ToolsDockContext<TData, TActions>` IS a
@@ -18,7 +18,7 @@
18
18
  * @example
19
19
  * ```svelte
20
20
  * <script lang="ts">
21
- * import { useToolsDock } from '@happyvertical/smrt-svelte/workspace';
21
+ * import { useToolsDock } from '@happyvertical/smrt-svelte/workspace/legacy';
22
22
  * const dock = useToolsDock();
23
23
  * </script>
24
24
  *
@@ -18,7 +18,7 @@
18
18
  * @example
19
19
  * ```svelte
20
20
  * <script lang="ts">
21
- * import { useToolsDock } from '@happyvertical/smrt-svelte/workspace';
21
+ * import { useToolsDock } from '@happyvertical/smrt-svelte/workspace/legacy';
22
22
  * const dock = useToolsDock();
23
23
  * </script>
24
24
  *
@@ -99,7 +99,7 @@ export interface ToolDef {
99
99
  * ```svelte
100
100
  * <script lang="ts">
101
101
  * import type { ToolsDockApi, ToolsDockContext } from
102
- * '@happyvertical/smrt-svelte/workspace';
102
+ * '@happyvertical/smrt-svelte/workspace/legacy';
103
103
  *
104
104
  * interface MyData { siteSlug: string; contentId: string }
105
105
  * interface MyActions { triggerSave(): void }
@@ -325,6 +325,16 @@ export interface ToolsDockApi<TData = Record<string, unknown>, TActions extends
325
325
  readonly activeTool: string | null;
326
326
  readonly isOpen: boolean;
327
327
  readonly availableTools: ReadonlyArray<AvailableTool>;
328
+ /**
329
+ * The current context's latest `fetchAvailability` failure, or `null`
330
+ * before a failure, after a context change, and after the next successful
331
+ * refresh. A failure leaves `availableTools` on its last-known-good snapshot
332
+ * for the current context; a context change resets to registered-tool
333
+ * metadata before fetching so contextual labels and badges do not cross
334
+ * boundaries. Optional for structural compatibility with pre-existing
335
+ * `ToolsDockApi` adapters.
336
+ */
337
+ readonly availabilityError?: unknown;
328
338
  /**
329
339
  * The current dock context (route data, selection, etc.) as supplied via
330
340
  * `setContext()`. Typed against the factory's `<TData, TActions>` generics —
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/workspace/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/workspace/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-svelte",
3
- "version": "0.39.10",
3
+ "version": "0.39.12",
4
4
  "description": "Svelte 5 components for SMRT user management - auth, users, tenants, roles, permissions, groups",
5
5
  "type": "module",
6
6
  "smrtRawPrimitives": "strict",
@@ -37,6 +37,12 @@
37
37
  "import": "./dist/components/workspace/index.js",
38
38
  "default": "./dist/components/workspace/index.js"
39
39
  },
40
+ "./workspace/legacy": {
41
+ "types": "./dist/components/workspace/legacy.d.ts",
42
+ "svelte": "./dist/components/workspace/legacy.js",
43
+ "import": "./dist/components/workspace/legacy.js",
44
+ "default": "./dist/components/workspace/legacy.js"
45
+ },
40
46
  "./workspace/server": {
41
47
  "types": "./dist/components/workspace/server/index.d.ts",
42
48
  "import": "./dist/components/workspace/server/index.js",
@@ -94,14 +100,14 @@
94
100
  "access": "public"
95
101
  },
96
102
  "dependencies": {
97
- "@happyvertical/logger": "^0.78.0",
103
+ "@happyvertical/logger": "^0.78.1",
98
104
  "@tanstack/db": "^0.6.14",
99
105
  "@tanstack/svelte-db": "^0.1.91",
100
106
  "esm-env": "^1.2.2",
101
- "@happyvertical/smrt-languages": "0.39.10",
102
- "@happyvertical/smrt-types": "0.39.10",
103
- "@happyvertical/smrt-ui": "0.39.10",
104
- "@happyvertical/smrt-web": "0.39.10"
107
+ "@happyvertical/smrt-types": "0.39.12",
108
+ "@happyvertical/smrt-languages": "0.39.12",
109
+ "@happyvertical/smrt-web": "0.39.12",
110
+ "@happyvertical/smrt-ui": "0.39.12"
105
111
  },
106
112
  "peerDependencies": {
107
113
  "@huggingface/transformers": ">=3.8.1",