@happyvertical/smrt-reports 0.55.24 → 0.56.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 (91) hide show
  1. package/AGENTS.md +26 -3
  2. package/README.md +11 -2
  3. package/dist/index.d.ts +4 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +476 -109
  6. package/dist/index.js.map +1 -1
  7. package/dist/manifest.json +174 -5
  8. package/dist/materialized-host.d.ts +72 -0
  9. package/dist/materialized-host.d.ts.map +1 -0
  10. package/dist/playground.d.ts +2 -0
  11. package/dist/playground.d.ts.map +1 -0
  12. package/dist/playground.js +154 -0
  13. package/dist/playground.js.map +1 -0
  14. package/dist/recipes.d.ts +55 -0
  15. package/dist/recipes.d.ts.map +1 -1
  16. package/dist/runtime-report.d.ts +9 -0
  17. package/dist/runtime-report.d.ts.map +1 -1
  18. package/dist/runtime-server.d.ts +77 -0
  19. package/dist/runtime-server.d.ts.map +1 -0
  20. package/dist/runtime-spec.d.ts +2 -1
  21. package/dist/runtime-spec.d.ts.map +1 -1
  22. package/dist/smrt-knowledge.json +203 -11
  23. package/dist/state.js +1 -1
  24. package/dist/state.js.map +1 -1
  25. package/dist/svelte/MaterializedReportTable.svelte +104 -0
  26. package/dist/svelte/MaterializedReportTable.svelte.d.ts +14 -0
  27. package/dist/svelte/MaterializedReportTable.svelte.d.ts.map +1 -0
  28. package/dist/svelte/ReportConfirmation.svelte +99 -0
  29. package/dist/svelte/ReportConfirmation.svelte.d.ts +15 -0
  30. package/dist/svelte/ReportConfirmation.svelte.d.ts.map +1 -0
  31. package/dist/svelte/ReportDetail.svelte +69 -0
  32. package/dist/svelte/ReportDetail.svelte.d.ts +11 -0
  33. package/dist/svelte/ReportDetail.svelte.d.ts.map +1 -0
  34. package/dist/svelte/ReportPicker.svelte +73 -0
  35. package/dist/svelte/ReportPicker.svelte.d.ts +16 -0
  36. package/dist/svelte/ReportPicker.svelte.d.ts.map +1 -0
  37. package/dist/svelte/ReportResult.svelte +69 -0
  38. package/dist/svelte/ReportResult.svelte.d.ts +10 -0
  39. package/dist/svelte/ReportResult.svelte.d.ts.map +1 -0
  40. package/dist/svelte/RuntimeReportChartWidget.svelte +20 -0
  41. package/dist/svelte/RuntimeReportChartWidget.svelte.d.ts +11 -0
  42. package/dist/svelte/RuntimeReportChartWidget.svelte.d.ts.map +1 -0
  43. package/dist/svelte/RuntimeReportDetailRoute.svelte +67 -0
  44. package/dist/svelte/RuntimeReportDetailRoute.svelte.d.ts +21 -0
  45. package/dist/svelte/RuntimeReportDetailRoute.svelte.d.ts.map +1 -0
  46. package/dist/svelte/RuntimeReportToolResult.svelte +26 -0
  47. package/dist/svelte/RuntimeReportToolResult.svelte.d.ts +8 -0
  48. package/dist/svelte/RuntimeReportToolResult.svelte.d.ts.map +1 -0
  49. package/dist/svelte/RuntimeReportWidgetOptions.svelte +58 -0
  50. package/dist/svelte/RuntimeReportWidgetOptions.svelte.d.ts +14 -0
  51. package/dist/svelte/RuntimeReportWidgetOptions.svelte.d.ts.map +1 -0
  52. package/dist/svelte/RuntimeReportsRoute.svelte +67 -0
  53. package/dist/svelte/RuntimeReportsRoute.svelte.d.ts +19 -0
  54. package/dist/svelte/RuntimeReportsRoute.svelte.d.ts.map +1 -0
  55. package/dist/svelte/SavedReports.svelte +114 -0
  56. package/dist/svelte/SavedReports.svelte.d.ts +11 -0
  57. package/dist/svelte/SavedReports.svelte.d.ts.map +1 -0
  58. package/dist/svelte/browser-client.d.ts +10 -0
  59. package/dist/svelte/browser-client.d.ts.map +1 -0
  60. package/dist/svelte/browser-client.js +16 -0
  61. package/dist/svelte/client.d.ts +15 -0
  62. package/dist/svelte/client.d.ts.map +1 -0
  63. package/dist/svelte/client.js +179 -0
  64. package/dist/svelte/index.d.ts +17 -0
  65. package/dist/svelte/index.d.ts.map +1 -0
  66. package/dist/svelte/index.js +14 -0
  67. package/dist/svelte/materialized.d.ts +19 -0
  68. package/dist/svelte/materialized.d.ts.map +1 -0
  69. package/dist/svelte/materialized.js +1 -0
  70. package/dist/svelte/messages.d.ts +72 -0
  71. package/dist/svelte/messages.d.ts.map +1 -0
  72. package/dist/svelte/messages.js +72 -0
  73. package/dist/svelte/playground.d.ts +132 -0
  74. package/dist/svelte/playground.d.ts.map +1 -0
  75. package/dist/svelte/playground.js +62 -0
  76. package/dist/svelte/preview-data.d.ts +7 -0
  77. package/dist/svelte/preview-data.d.ts.map +1 -0
  78. package/dist/svelte/preview-data.js +59 -0
  79. package/dist/svelte/result.d.ts +8 -0
  80. package/dist/svelte/result.d.ts.map +1 -0
  81. package/dist/svelte/result.js +99 -0
  82. package/dist/svelte/spec.d.ts +5 -0
  83. package/dist/svelte/spec.d.ts.map +1 -0
  84. package/dist/svelte/spec.js +282 -0
  85. package/dist/svelte/tool-result.d.ts +11 -0
  86. package/dist/svelte/tool-result.d.ts.map +1 -0
  87. package/dist/svelte/tool-result.js +19 -0
  88. package/dist/svelte/types.d.ts +38 -0
  89. package/dist/svelte/types.d.ts.map +1 -0
  90. package/dist/svelte/types.js +1 -0
  91. package/package.json +36 -12
@@ -0,0 +1,282 @@
1
+ const IDENTIFIER = /^[A-Za-z][A-Za-z0-9_]*$/;
2
+ const ALIAS = /^[a-z][a-z0-9_]*$/;
3
+ const SOURCE = /^[A-Za-z@][A-Za-z0-9_@./:-]*$/;
4
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: mirrors the server grammar's printable-text guard
5
+ const CONTROL = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/;
6
+ const BUCKETS = new Set([
7
+ 'minute',
8
+ 'hour',
9
+ 'day',
10
+ 'week',
11
+ 'month',
12
+ 'quarter',
13
+ 'year',
14
+ ]);
15
+ const MEASURES = new Set([
16
+ 'count',
17
+ 'countDistinct',
18
+ 'sum',
19
+ 'avg',
20
+ 'min',
21
+ 'max',
22
+ ]);
23
+ const FILTERS = new Set([
24
+ 'eq',
25
+ 'ne',
26
+ 'gt',
27
+ 'gte',
28
+ 'lt',
29
+ 'lte',
30
+ 'in',
31
+ 'notIn',
32
+ 'contains',
33
+ 'isNull',
34
+ 'isNotNull',
35
+ ]);
36
+ const HAVING = new Set(['eq', 'ne', 'gt', 'gte', 'lt', 'lte']);
37
+ const CHARTS = new Set(['table', 'bar', 'line', 'pie', 'stat']);
38
+ const RESERVED = new Set([
39
+ 'all',
40
+ 'and',
41
+ 'as',
42
+ 'asc',
43
+ 'between',
44
+ 'by',
45
+ 'case',
46
+ 'cast',
47
+ 'check',
48
+ 'column',
49
+ 'constraint',
50
+ 'create',
51
+ 'cross',
52
+ 'default',
53
+ 'delete',
54
+ 'desc',
55
+ 'distinct',
56
+ 'drop',
57
+ 'else',
58
+ 'end',
59
+ 'except',
60
+ 'exists',
61
+ 'false',
62
+ 'for',
63
+ 'foreign',
64
+ 'from',
65
+ 'full',
66
+ 'group',
67
+ 'having',
68
+ 'in',
69
+ 'inner',
70
+ 'insert',
71
+ 'intersect',
72
+ 'into',
73
+ 'is',
74
+ 'join',
75
+ 'left',
76
+ 'like',
77
+ 'limit',
78
+ 'natural',
79
+ 'not',
80
+ 'null',
81
+ 'offset',
82
+ 'on',
83
+ 'or',
84
+ 'order',
85
+ 'outer',
86
+ 'primary',
87
+ 'references',
88
+ 'right',
89
+ 'select',
90
+ 'set',
91
+ 'table',
92
+ 'then',
93
+ 'to',
94
+ 'true',
95
+ 'union',
96
+ 'unique',
97
+ 'update',
98
+ 'user',
99
+ 'using',
100
+ 'values',
101
+ 'when',
102
+ 'where',
103
+ 'with',
104
+ ]);
105
+ function record(value) {
106
+ if (!value || typeof value !== 'object' || Array.isArray(value))
107
+ return null;
108
+ const prototype = Object.getPrototypeOf(value);
109
+ return prototype === Object.prototype || prototype === null
110
+ ? value
111
+ : null;
112
+ }
113
+ function keys(value, allowed) {
114
+ return Object.keys(value).every((key) => allowed.includes(key));
115
+ }
116
+ function text(value, max, optional = false) {
117
+ if (value === undefined)
118
+ return optional;
119
+ if (typeof value !== 'string')
120
+ return false;
121
+ const trimmed = value.trim();
122
+ return (trimmed.length > 0 &&
123
+ trimmed.length <= max &&
124
+ trimmed === value &&
125
+ !CONTROL.test(trimmed));
126
+ }
127
+ function field(value) {
128
+ return (typeof value === 'string' && value.length <= 64 && IDENTIFIER.test(value));
129
+ }
130
+ function alias(value) {
131
+ return (typeof value === 'string' &&
132
+ value.length <= 40 &&
133
+ ALIAS.test(value) &&
134
+ !RESERVED.has(value));
135
+ }
136
+ function scalar(value) {
137
+ return ((typeof value === 'string' &&
138
+ value.length <= 256 &&
139
+ !value.includes('\u0000')) ||
140
+ (typeof value === 'number' && Number.isFinite(value)) ||
141
+ typeof value === 'boolean');
142
+ }
143
+ /** Browser-safe validation of the server's already-normalized closed grammar. */
144
+ export function validRuntimeReportSpec(value) {
145
+ const spec = record(value);
146
+ if (!spec ||
147
+ !keys(spec, [
148
+ 'version',
149
+ 'title',
150
+ 'description',
151
+ 'source',
152
+ 'dimensions',
153
+ 'measures',
154
+ 'filters',
155
+ 'having',
156
+ 'sort',
157
+ 'limit',
158
+ 'chart',
159
+ ]) ||
160
+ spec.version !== 1 ||
161
+ !text(spec.title, 120) ||
162
+ !text(spec.description, 500, true) ||
163
+ typeof spec.source !== 'string' ||
164
+ spec.source.length === 0 ||
165
+ spec.source.length > 120 ||
166
+ !SOURCE.test(spec.source) ||
167
+ !Array.isArray(spec.dimensions) ||
168
+ spec.dimensions.length > 4 ||
169
+ !Array.isArray(spec.measures) ||
170
+ spec.measures.length < 1 ||
171
+ spec.measures.length > 6 ||
172
+ !Array.isArray(spec.filters) ||
173
+ spec.filters.length > 12 ||
174
+ !Array.isArray(spec.having) ||
175
+ spec.having.length > 4 ||
176
+ !Array.isArray(spec.sort) ||
177
+ spec.sort.length > 3 ||
178
+ !Number.isSafeInteger(spec.limit) ||
179
+ spec.limit < 1 ||
180
+ spec.limit > 1000)
181
+ return false;
182
+ const dimensions = new Set();
183
+ const measures = new Set();
184
+ const aliases = new Set();
185
+ for (const value of spec.dimensions) {
186
+ const item = record(value);
187
+ if (!item ||
188
+ !keys(item, ['field', 'as', 'bucket']) ||
189
+ !field(item.field) ||
190
+ !alias(item.as) ||
191
+ (item.bucket !== undefined &&
192
+ (typeof item.bucket !== 'string' || !BUCKETS.has(item.bucket))) ||
193
+ aliases.has(item.as))
194
+ return false;
195
+ aliases.add(item.as);
196
+ dimensions.add(item.as);
197
+ }
198
+ for (const value of spec.measures) {
199
+ const item = record(value);
200
+ if (!item ||
201
+ !keys(item, ['fn', 'field', 'as']) ||
202
+ typeof item.fn !== 'string' ||
203
+ !MEASURES.has(item.fn) ||
204
+ !alias(item.as) ||
205
+ aliases.has(item.as) ||
206
+ (item.field !== undefined && !field(item.field)) ||
207
+ (item.fn !== 'count' && item.field === undefined))
208
+ return false;
209
+ aliases.add(item.as);
210
+ measures.add(item.as);
211
+ }
212
+ for (const value of spec.filters) {
213
+ const item = record(value);
214
+ if (!item ||
215
+ !keys(item, ['field', 'op', 'value']) ||
216
+ !field(item.field) ||
217
+ typeof item.op !== 'string' ||
218
+ !FILTERS.has(item.op))
219
+ return false;
220
+ if (item.op === 'isNull' || item.op === 'isNotNull') {
221
+ if (item.value !== undefined)
222
+ return false;
223
+ }
224
+ else if (item.op === 'in' || item.op === 'notIn') {
225
+ if (!Array.isArray(item.value) ||
226
+ item.value.length < 1 ||
227
+ item.value.length > 100 ||
228
+ !item.value.every(scalar))
229
+ return false;
230
+ }
231
+ else if (!scalar(item.value) ||
232
+ (item.op === 'contains' && typeof item.value !== 'string'))
233
+ return false;
234
+ }
235
+ for (const value of spec.having) {
236
+ const item = record(value);
237
+ if (!item ||
238
+ !keys(item, ['measure', 'op', 'value']) ||
239
+ !alias(item.measure) ||
240
+ !measures.has(item.measure) ||
241
+ typeof item.op !== 'string' ||
242
+ !HAVING.has(item.op) ||
243
+ typeof item.value !== 'number' ||
244
+ !Number.isFinite(item.value))
245
+ return false;
246
+ }
247
+ for (const value of spec.sort) {
248
+ const item = record(value);
249
+ if (!item ||
250
+ !keys(item, ['by', 'direction']) ||
251
+ !alias(item.by) ||
252
+ !aliases.has(item.by) ||
253
+ (item.direction !== 'asc' && item.direction !== 'desc'))
254
+ return false;
255
+ }
256
+ const chart = record(spec.chart);
257
+ if (!chart ||
258
+ !keys(chart, ['type', 'x', 'y']) ||
259
+ typeof chart.type !== 'string' ||
260
+ !CHARTS.has(chart.type) ||
261
+ (chart.x !== undefined && (!alias(chart.x) || !dimensions.has(chart.x))) ||
262
+ (chart.y !== undefined &&
263
+ (!Array.isArray(chart.y) ||
264
+ chart.y.length > 6 ||
265
+ !chart.y.every((name) => alias(name) && measures.has(name)))))
266
+ return false;
267
+ return true;
268
+ }
269
+ export function runtimeReportSpecFromWire(value) {
270
+ let candidate = value;
271
+ if (typeof value === 'string') {
272
+ if (value.length > 64 * 1024)
273
+ return null;
274
+ try {
275
+ candidate = JSON.parse(value);
276
+ }
277
+ catch {
278
+ return null;
279
+ }
280
+ }
281
+ return validRuntimeReportSpec(candidate) ? candidate : null;
282
+ }
@@ -0,0 +1,11 @@
1
+ import type { Component } from 'svelte';
2
+ import type { RuntimeReportProposal } from './types.js';
3
+ export interface ToolResultMessage {
4
+ toolCallData?: unknown;
5
+ }
6
+ export declare function runtimeReportProposalFromMessage(message: ToolResultMessage): RuntimeReportProposal | null;
7
+ /** Host selector for AssistantDock's generic `toolResultComponent` seam. */
8
+ export declare function runtimeReportToolResultComponent(message: ToolResultMessage): Component<{
9
+ message: ToolResultMessage;
10
+ }> | undefined;
11
+ //# sourceMappingURL=tool-result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-result.d.ts","sourceRoot":"","sources":["../../src/svelte/tool-result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAGxC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,iBAAiB,GACzB,qBAAqB,GAAG,IAAI,CAc9B;AAED,4EAA4E;AAC5E,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,iBAAiB,GACzB,SAAS,CAAC;IAAE,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAAC,GAAG,SAAS,CAIvD"}
@@ -0,0 +1,19 @@
1
+ import RuntimeReportToolResult from './RuntimeReportToolResult.svelte';
2
+ import { validReportProposal } from './result.js';
3
+ export function runtimeReportProposalFromMessage(message) {
4
+ const data = message.toolCallData;
5
+ if (!data || typeof data !== 'object')
6
+ return null;
7
+ const value = data;
8
+ const toolName = value.name ?? value.tool ?? value.toolName;
9
+ return toolName === 'reports.runtime.define' &&
10
+ validReportProposal(value.result)
11
+ ? value.result
12
+ : null;
13
+ }
14
+ /** Host selector for AssistantDock's generic `toolResultComponent` seam. */
15
+ export function runtimeReportToolResultComponent(message) {
16
+ return runtimeReportProposalFromMessage(message)
17
+ ? RuntimeReportToolResult
18
+ : undefined;
19
+ }
@@ -0,0 +1,38 @@
1
+ import type { RuntimeReportResult } from '../runtime-compiler.js';
2
+ import type { RuntimeReportSpec } from '../runtime-spec.js';
3
+ /** Browser projection only: never includes persisted result rows. */
4
+ export interface SavedRuntimeReport {
5
+ id: string;
6
+ title: string;
7
+ description?: string;
8
+ sourceId: string;
9
+ createdByUserId: string;
10
+ status: 'active' | 'archived';
11
+ spec: RuntimeReportSpec;
12
+ /** Browser-session hint only. Runtime result rows and run history are not persisted. */
13
+ lastRunAt?: string;
14
+ /** Host permission hint. The archive endpoint authorizes every mutation again. */
15
+ canArchive: boolean;
16
+ }
17
+ /** A principal-scoped transport. Replace it when the tenant or viewer changes. */
18
+ export interface RuntimeReportsClient {
19
+ list(options: {
20
+ onlyMine: boolean;
21
+ includeArchived: boolean;
22
+ }): Promise<SavedRuntimeReport[]>;
23
+ get(id: string): Promise<SavedRuntimeReport>;
24
+ run(id: string): Promise<RuntimeReportResult>;
25
+ archive(id: string, archived: boolean): Promise<void>;
26
+ confirm(proposal: RuntimeReportProposal): Promise<SavedRuntimeReport>;
27
+ }
28
+ export type { RuntimeReportResult, RuntimeReportSpec };
29
+ /** Server-issued proposal projection; the server retains the canonical pending spec. */
30
+ export interface RuntimeReportProposal {
31
+ status: 'awaiting_confirmation';
32
+ specHash: string;
33
+ spec: RuntimeReportSpec;
34
+ sourceLabel: string;
35
+ confirmPath: string;
36
+ preview: RuntimeReportResult;
37
+ }
38
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/svelte/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC9B,IAAI,EAAE,iBAAiB,CAAC;IACxB,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,OAAO,EAAE;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,eAAe,EAAE,OAAO,CAAC;KAC1B,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAClC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC7C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,OAAO,CAAC,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACvE;AAED,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AAEvD,wFAAwF;AACxF,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,uBAAuB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,iBAAiB,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,mBAAmB,CAAC;CAC9B"}
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-reports",
3
- "version": "0.55.24",
3
+ "version": "0.56.1",
4
4
  "description": "Materialized aggregate report models for SMRT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -40,22 +40,38 @@
40
40
  "import": "./dist/state.js"
41
41
  },
42
42
  "./manifest": "./dist/manifest.json",
43
- "./manifest.json": "./dist/manifest.json"
43
+ "./manifest.json": "./dist/manifest.json",
44
+ "./svelte": {
45
+ "types": "./dist/svelte/index.d.ts",
46
+ "svelte": "./dist/svelte/index.js",
47
+ "import": "./dist/svelte/index.js"
48
+ },
49
+ "./playground": {
50
+ "types": "./dist/playground.d.ts",
51
+ "import": "./dist/playground.js"
52
+ }
44
53
  },
45
54
  "dependencies": {
46
- "@happyvertical/smrt-core": "0.55.24",
47
- "@happyvertical/smrt-jobs": "0.55.24",
48
- "@happyvertical/smrt-types": "0.55.24",
49
- "@happyvertical/smrt-tenancy": "0.55.24",
50
- "@happyvertical/sql": "^0.103.6"
55
+ "@happyvertical/smrt-core": "0.56.1",
56
+ "@happyvertical/smrt-jobs": "0.56.1",
57
+ "@happyvertical/smrt-types": "0.56.1",
58
+ "@happyvertical/smrt-tenancy": "0.56.1",
59
+ "@happyvertical/sql": "^0.103.7",
60
+ "@happyvertical/smrt-config": "0.56.1",
61
+ "@happyvertical/smrt-ui": "0.56.1"
51
62
  },
52
63
  "devDependencies": {
53
- "@happyvertical/smrt-scanner": "0.55.24",
54
- "@happyvertical/smrt-vitest": "0.55.24",
64
+ "@happyvertical/smrt-scanner": "0.56.1",
65
+ "@happyvertical/smrt-vitest": "0.56.1",
55
66
  "@types/node": "24.13.6",
56
67
  "typescript": "6.0.3",
57
68
  "vite": "8.1.4",
58
- "vitest": "4.1.10"
69
+ "vitest": "4.1.10",
70
+ "@sveltejs/package": "^2.5.8",
71
+ "@sveltejs/vite-plugin-svelte": "^7.3.0",
72
+ "@testing-library/svelte": "^5.4.2",
73
+ "svelte-check": "^4.7.6",
74
+ "svelte": "^5.57.1"
59
75
  },
60
76
  "keywords": [
61
77
  "ai",
@@ -75,8 +91,16 @@
75
91
  "url": "https://github.com/happyvertical/smrt.git",
76
92
  "directory": "packages/reports"
77
93
  },
94
+ "peerDependencies": {
95
+ "svelte": "^5.57.0"
96
+ },
97
+ "peerDependenciesMeta": {
98
+ "svelte": {
99
+ "optional": true
100
+ }
101
+ },
78
102
  "scripts": {
79
- "build": "vite build --mode library",
103
+ "build": "vite build --mode library && svelte-package -i src/svelte -o dist/svelte --tsconfig tsconfig.svelte.json && node ../../scripts/prune-svelte-package-artifacts.js dist",
80
104
  "build:watch": "vite build --mode library --watch",
81
105
  "clean": "rm -rf dist",
82
106
  "dev": "vite dev",
@@ -84,7 +108,7 @@
84
108
  "test": "vitest run",
85
109
  "test:postgres": "node ../../scripts/run-with-ci-postgres.mjs -- pnpm exec vitest run optional.test.ts",
86
110
  "test:watch": "vitest",
87
- "typecheck": "tsc --noEmit -p tsconfig.json",
111
+ "typecheck": "tsc --noEmit -p tsconfig.json && node ../../scripts/svelte-check-a11y.mjs --tsconfig ./tsconfig.svelte.json",
88
112
  "verify:pack": "node ../../scripts/verify-package-types-exports.js ."
89
113
  }
90
114
  }