@ultrst-armada/floks 1.0.1 → 1.1.0

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/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './packages/ui/dist/index.d.ts';
2
2
  export * from './packages/canvas-ui/dist/index.d.ts';
3
+ export * from './packages/contracts/dist/index.d.ts';
package/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './packages/ui/dist/index.js';
2
2
  export * from './packages/canvas-ui/dist/index.js';
3
+ export * from './packages/contracts/dist/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultrst-armada/floks",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -37,6 +37,11 @@
37
37
  "types": "./packages/canvas-ui/dist/index.d.ts",
38
38
  "import": "./packages/canvas-ui/dist/index.js",
39
39
  "default": "./packages/canvas-ui/dist/index.js"
40
+ },
41
+ "./contracts": {
42
+ "types": "./packages/contracts/dist/index.d.ts",
43
+ "import": "./packages/contracts/dist/index.js",
44
+ "default": "./packages/contracts/dist/index.js"
40
45
  }
41
46
  },
42
47
  "scripts": {
@@ -0,0 +1,394 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * @file schemas.ts
5
+ * @description Zod Schemas for Floks Component Theme Contracts & ThemePacks.
6
+ * Enforces docs/04_THETA_COMPONENT_CONTRACTS.md:
7
+ * - ComponentThemeContract
8
+ * - VisualSlot
9
+ * - VisualState
10
+ * - VisualParameter
11
+ * - ThemeTarget
12
+ * - ThemePack
13
+ */
14
+
15
+ declare const VisualSlotSchema: z.ZodObject<{
16
+ id: z.ZodString;
17
+ acceptedElementTypes: z.ZodArray<z.ZodString, "many">;
18
+ required: z.ZodDefault<z.ZodBoolean>;
19
+ constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ id?: string;
22
+ acceptedElementTypes?: string[];
23
+ required?: boolean;
24
+ constraints?: Record<string, unknown>;
25
+ }, {
26
+ id?: string;
27
+ acceptedElementTypes?: string[];
28
+ required?: boolean;
29
+ constraints?: Record<string, unknown>;
30
+ }>;
31
+ type VisualSlot = z.infer<typeof VisualSlotSchema>;
32
+ declare const VisualParameterSchema: z.ZodObject<{
33
+ id: z.ZodString;
34
+ type: z.ZodEnum<["color", "dimension", "number", "string", "boolean", "gradient", "shadow"]>;
35
+ default: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>;
36
+ constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
37
+ }, "strip", z.ZodTypeAny, {
38
+ id?: string;
39
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
40
+ constraints?: Record<string, unknown>;
41
+ default?: string | number | boolean;
42
+ }, {
43
+ id?: string;
44
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
45
+ constraints?: Record<string, unknown>;
46
+ default?: string | number | boolean;
47
+ }>;
48
+ type VisualParameter = z.infer<typeof VisualParameterSchema>;
49
+ declare const VisualStateSchema: z.ZodObject<{
50
+ id: z.ZodString;
51
+ parameters: z.ZodArray<z.ZodObject<{
52
+ id: z.ZodString;
53
+ type: z.ZodEnum<["color", "dimension", "number", "string", "boolean", "gradient", "shadow"]>;
54
+ default: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>;
55
+ constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
56
+ }, "strip", z.ZodTypeAny, {
57
+ id?: string;
58
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
59
+ constraints?: Record<string, unknown>;
60
+ default?: string | number | boolean;
61
+ }, {
62
+ id?: string;
63
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
64
+ constraints?: Record<string, unknown>;
65
+ default?: string | number | boolean;
66
+ }>, "many">;
67
+ transitions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
68
+ }, "strip", z.ZodTypeAny, {
69
+ id?: string;
70
+ parameters?: {
71
+ id?: string;
72
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
73
+ constraints?: Record<string, unknown>;
74
+ default?: string | number | boolean;
75
+ }[];
76
+ transitions?: Record<string, string>;
77
+ }, {
78
+ id?: string;
79
+ parameters?: {
80
+ id?: string;
81
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
82
+ constraints?: Record<string, unknown>;
83
+ default?: string | number | boolean;
84
+ }[];
85
+ transitions?: Record<string, string>;
86
+ }>;
87
+ type VisualState = z.infer<typeof VisualStateSchema>;
88
+ declare const ThemeTargetSchema: z.ZodObject<{
89
+ library: z.ZodLiteral<"@ultrst-armada/floks">;
90
+ componentId: z.ZodString;
91
+ componentVersion: z.ZodString;
92
+ contractVersion: z.ZodDefault<z.ZodString>;
93
+ }, "strip", z.ZodTypeAny, {
94
+ library?: "@ultrst-armada/floks";
95
+ componentId?: string;
96
+ componentVersion?: string;
97
+ contractVersion?: string;
98
+ }, {
99
+ library?: "@ultrst-armada/floks";
100
+ componentId?: string;
101
+ componentVersion?: string;
102
+ contractVersion?: string;
103
+ }>;
104
+ type ThemeTarget = z.infer<typeof ThemeTargetSchema>;
105
+ declare const ComponentThemeContractSchema: z.ZodObject<{
106
+ componentId: z.ZodString;
107
+ componentVersion: z.ZodString;
108
+ displayName: z.ZodOptional<z.ZodString>;
109
+ slots: z.ZodArray<z.ZodObject<{
110
+ id: z.ZodString;
111
+ acceptedElementTypes: z.ZodArray<z.ZodString, "many">;
112
+ required: z.ZodDefault<z.ZodBoolean>;
113
+ constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
114
+ }, "strip", z.ZodTypeAny, {
115
+ id?: string;
116
+ acceptedElementTypes?: string[];
117
+ required?: boolean;
118
+ constraints?: Record<string, unknown>;
119
+ }, {
120
+ id?: string;
121
+ acceptedElementTypes?: string[];
122
+ required?: boolean;
123
+ constraints?: Record<string, unknown>;
124
+ }>, "many">;
125
+ states: z.ZodArray<z.ZodObject<{
126
+ id: z.ZodString;
127
+ parameters: z.ZodArray<z.ZodObject<{
128
+ id: z.ZodString;
129
+ type: z.ZodEnum<["color", "dimension", "number", "string", "boolean", "gradient", "shadow"]>;
130
+ default: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>;
131
+ constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
132
+ }, "strip", z.ZodTypeAny, {
133
+ id?: string;
134
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
135
+ constraints?: Record<string, unknown>;
136
+ default?: string | number | boolean;
137
+ }, {
138
+ id?: string;
139
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
140
+ constraints?: Record<string, unknown>;
141
+ default?: string | number | boolean;
142
+ }>, "many">;
143
+ transitions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
144
+ }, "strip", z.ZodTypeAny, {
145
+ id?: string;
146
+ parameters?: {
147
+ id?: string;
148
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
149
+ constraints?: Record<string, unknown>;
150
+ default?: string | number | boolean;
151
+ }[];
152
+ transitions?: Record<string, string>;
153
+ }, {
154
+ id?: string;
155
+ parameters?: {
156
+ id?: string;
157
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
158
+ constraints?: Record<string, unknown>;
159
+ default?: string | number | boolean;
160
+ }[];
161
+ transitions?: Record<string, string>;
162
+ }>, "many">;
163
+ parameters: z.ZodArray<z.ZodObject<{
164
+ id: z.ZodString;
165
+ type: z.ZodEnum<["color", "dimension", "number", "string", "boolean", "gradient", "shadow"]>;
166
+ default: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>;
167
+ constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
168
+ }, "strip", z.ZodTypeAny, {
169
+ id?: string;
170
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
171
+ constraints?: Record<string, unknown>;
172
+ default?: string | number | boolean;
173
+ }, {
174
+ id?: string;
175
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
176
+ constraints?: Record<string, unknown>;
177
+ default?: string | number | boolean;
178
+ }>, "many">;
179
+ assets: z.ZodArray<z.ZodString, "many">;
180
+ }, "strip", z.ZodTypeAny, {
181
+ parameters?: {
182
+ id?: string;
183
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
184
+ constraints?: Record<string, unknown>;
185
+ default?: string | number | boolean;
186
+ }[];
187
+ componentId?: string;
188
+ componentVersion?: string;
189
+ displayName?: string;
190
+ slots?: {
191
+ id?: string;
192
+ acceptedElementTypes?: string[];
193
+ required?: boolean;
194
+ constraints?: Record<string, unknown>;
195
+ }[];
196
+ states?: {
197
+ id?: string;
198
+ parameters?: {
199
+ id?: string;
200
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
201
+ constraints?: Record<string, unknown>;
202
+ default?: string | number | boolean;
203
+ }[];
204
+ transitions?: Record<string, string>;
205
+ }[];
206
+ assets?: string[];
207
+ }, {
208
+ parameters?: {
209
+ id?: string;
210
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
211
+ constraints?: Record<string, unknown>;
212
+ default?: string | number | boolean;
213
+ }[];
214
+ componentId?: string;
215
+ componentVersion?: string;
216
+ displayName?: string;
217
+ slots?: {
218
+ id?: string;
219
+ acceptedElementTypes?: string[];
220
+ required?: boolean;
221
+ constraints?: Record<string, unknown>;
222
+ }[];
223
+ states?: {
224
+ id?: string;
225
+ parameters?: {
226
+ id?: string;
227
+ type?: "string" | "number" | "boolean" | "color" | "dimension" | "gradient" | "shadow";
228
+ constraints?: Record<string, unknown>;
229
+ default?: string | number | boolean;
230
+ }[];
231
+ transitions?: Record<string, string>;
232
+ }[];
233
+ assets?: string[];
234
+ }>;
235
+ type ComponentThemeContract = z.infer<typeof ComponentThemeContractSchema>;
236
+ declare const ThemePackSlotBindingSchema: z.ZodObject<{
237
+ slotId: z.ZodString;
238
+ elementType: z.ZodString;
239
+ assetRef: z.ZodOptional<z.ZodString>;
240
+ styles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
241
+ }, "strip", z.ZodTypeAny, {
242
+ slotId?: string;
243
+ elementType?: string;
244
+ assetRef?: string;
245
+ styles?: Record<string, string>;
246
+ }, {
247
+ slotId?: string;
248
+ elementType?: string;
249
+ assetRef?: string;
250
+ styles?: Record<string, string>;
251
+ }>;
252
+ type ThemePackSlotBinding = z.infer<typeof ThemePackSlotBindingSchema>;
253
+ declare const ThemePackStateMappingSchema: z.ZodObject<{
254
+ stateId: z.ZodString;
255
+ parameterOverrides: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
256
+ }, "strip", z.ZodTypeAny, {
257
+ stateId?: string;
258
+ parameterOverrides?: Record<string, string | number | boolean>;
259
+ }, {
260
+ stateId?: string;
261
+ parameterOverrides?: Record<string, string | number | boolean>;
262
+ }>;
263
+ type ThemePackStateMapping = z.infer<typeof ThemePackStateMappingSchema>;
264
+ declare const ThemePackSchema: z.ZodObject<{
265
+ themeId: z.ZodString;
266
+ name: z.ZodString;
267
+ version: z.ZodString;
268
+ target: z.ZodObject<{
269
+ library: z.ZodLiteral<"@ultrst-armada/floks">;
270
+ componentId: z.ZodString;
271
+ componentVersion: z.ZodString;
272
+ contractVersion: z.ZodDefault<z.ZodString>;
273
+ }, "strip", z.ZodTypeAny, {
274
+ library?: "@ultrst-armada/floks";
275
+ componentId?: string;
276
+ componentVersion?: string;
277
+ contractVersion?: string;
278
+ }, {
279
+ library?: "@ultrst-armada/floks";
280
+ componentId?: string;
281
+ componentVersion?: string;
282
+ contractVersion?: string;
283
+ }>;
284
+ slots: z.ZodArray<z.ZodObject<{
285
+ slotId: z.ZodString;
286
+ elementType: z.ZodString;
287
+ assetRef: z.ZodOptional<z.ZodString>;
288
+ styles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
289
+ }, "strip", z.ZodTypeAny, {
290
+ slotId?: string;
291
+ elementType?: string;
292
+ assetRef?: string;
293
+ styles?: Record<string, string>;
294
+ }, {
295
+ slotId?: string;
296
+ elementType?: string;
297
+ assetRef?: string;
298
+ styles?: Record<string, string>;
299
+ }>, "many">;
300
+ states: z.ZodArray<z.ZodObject<{
301
+ stateId: z.ZodString;
302
+ parameterOverrides: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
303
+ }, "strip", z.ZodTypeAny, {
304
+ stateId?: string;
305
+ parameterOverrides?: Record<string, string | number | boolean>;
306
+ }, {
307
+ stateId?: string;
308
+ parameterOverrides?: Record<string, string | number | boolean>;
309
+ }>, "many">;
310
+ parameters: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
311
+ assetTypes: z.ZodArray<z.ZodString, "many">;
312
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
313
+ }, "strip", z.ZodTypeAny, {
314
+ parameters?: Record<string, string | number | boolean>;
315
+ slots?: {
316
+ slotId?: string;
317
+ elementType?: string;
318
+ assetRef?: string;
319
+ styles?: Record<string, string>;
320
+ }[];
321
+ states?: {
322
+ stateId?: string;
323
+ parameterOverrides?: Record<string, string | number | boolean>;
324
+ }[];
325
+ themeId?: string;
326
+ name?: string;
327
+ version?: string;
328
+ target?: {
329
+ library?: "@ultrst-armada/floks";
330
+ componentId?: string;
331
+ componentVersion?: string;
332
+ contractVersion?: string;
333
+ };
334
+ assetTypes?: string[];
335
+ metadata?: Record<string, unknown>;
336
+ }, {
337
+ parameters?: Record<string, string | number | boolean>;
338
+ slots?: {
339
+ slotId?: string;
340
+ elementType?: string;
341
+ assetRef?: string;
342
+ styles?: Record<string, string>;
343
+ }[];
344
+ states?: {
345
+ stateId?: string;
346
+ parameterOverrides?: Record<string, string | number | boolean>;
347
+ }[];
348
+ themeId?: string;
349
+ name?: string;
350
+ version?: string;
351
+ target?: {
352
+ library?: "@ultrst-armada/floks";
353
+ componentId?: string;
354
+ componentVersion?: string;
355
+ contractVersion?: string;
356
+ };
357
+ assetTypes?: string[];
358
+ metadata?: Record<string, unknown>;
359
+ }>;
360
+ type ThemePack = z.infer<typeof ThemePackSchema>;
361
+
362
+ /**
363
+ * @file registry.ts
364
+ * @description Canonical Floks Component Theme Contract Registry.
365
+ * Supplies explicit visual contracts for Button, Panel, SliderInput, Badge, Socket2D, Wire2D, Node2DBase.
366
+ */
367
+
368
+ declare const FLOKS_COMPONENT_REGISTRY: Record<string, ComponentThemeContract>;
369
+ declare function getComponentContract(componentId: string): ComponentThemeContract | undefined;
370
+ declare function listComponentContracts(): ComponentThemeContract[];
371
+
372
+ /**
373
+ * @file validator.ts
374
+ * @description Deterministic ThemePack compatibility validator.
375
+ * Enforces docs/04_THETA_COMPONENT_CONTRACTS.md:
376
+ * Validate(theme, component)
377
+ * <=>
378
+ * Target(theme) = component
379
+ * ^ theme.slots ⊆ component.slots
380
+ * ^ theme.states ⊆ component.states
381
+ * ^ theme.parameters ⊆ component.parameters
382
+ * ^ theme.assetTypes ⊆ component.acceptedAssetTypes
383
+ */
384
+
385
+ interface ThemeValidationResult {
386
+ valid: boolean;
387
+ errors: string[];
388
+ warnings: string[];
389
+ targetComponentId: string;
390
+ }
391
+ declare function validateThemePackAgainstContract(themePack: ThemePack, contract?: ComponentThemeContract): ThemeValidationResult;
392
+ declare function loadThemePack(raw: unknown): ThemePack;
393
+
394
+ export { type ComponentThemeContract, ComponentThemeContractSchema, FLOKS_COMPONENT_REGISTRY, type ThemePack, ThemePackSchema, type ThemePackSlotBinding, ThemePackSlotBindingSchema, type ThemePackStateMapping, ThemePackStateMappingSchema, type ThemeTarget, ThemeTargetSchema, type ThemeValidationResult, type VisualParameter, VisualParameterSchema, type VisualSlot, VisualSlotSchema, type VisualState, VisualStateSchema, getComponentContract, listComponentContracts, loadThemePack, validateThemePackAgainstContract };
@@ -0,0 +1,324 @@
1
+ // src/schemas.ts
2
+ import { z } from "zod";
3
+ var VisualSlotSchema = z.object({
4
+ id: z.string(),
5
+ acceptedElementTypes: z.array(z.string()),
6
+ required: z.boolean().default(false),
7
+ constraints: z.record(z.unknown()).optional()
8
+ });
9
+ var VisualParameterSchema = z.object({
10
+ id: z.string(),
11
+ type: z.enum(["color", "dimension", "number", "string", "boolean", "gradient", "shadow"]),
12
+ default: z.union([z.string(), z.number(), z.boolean()]),
13
+ constraints: z.record(z.unknown()).optional()
14
+ });
15
+ var VisualStateSchema = z.object({
16
+ id: z.string(),
17
+ parameters: z.array(VisualParameterSchema),
18
+ transitions: z.record(z.string()).optional()
19
+ });
20
+ var ThemeTargetSchema = z.object({
21
+ library: z.literal("@ultrst-armada/floks"),
22
+ componentId: z.string(),
23
+ componentVersion: z.string(),
24
+ contractVersion: z.string().default("1.0.0")
25
+ });
26
+ var ComponentThemeContractSchema = z.object({
27
+ componentId: z.string(),
28
+ componentVersion: z.string(),
29
+ displayName: z.string().optional(),
30
+ slots: z.array(VisualSlotSchema),
31
+ states: z.array(VisualStateSchema),
32
+ parameters: z.array(VisualParameterSchema),
33
+ assets: z.array(z.string())
34
+ });
35
+ var ThemePackSlotBindingSchema = z.object({
36
+ slotId: z.string(),
37
+ elementType: z.string(),
38
+ assetRef: z.string().optional(),
39
+ styles: z.record(z.string()).optional()
40
+ });
41
+ var ThemePackStateMappingSchema = z.object({
42
+ stateId: z.string(),
43
+ parameterOverrides: z.record(z.union([z.string(), z.number(), z.boolean()]))
44
+ });
45
+ var ThemePackSchema = z.object({
46
+ themeId: z.string(),
47
+ name: z.string(),
48
+ version: z.string(),
49
+ target: ThemeTargetSchema,
50
+ slots: z.array(ThemePackSlotBindingSchema),
51
+ states: z.array(ThemePackStateMappingSchema),
52
+ parameters: z.record(z.union([z.string(), z.number(), z.boolean()])),
53
+ assetTypes: z.array(z.string()),
54
+ metadata: z.record(z.unknown()).optional()
55
+ });
56
+
57
+ // src/registry.ts
58
+ var FLOKS_COMPONENT_REGISTRY = {
59
+ // 1. Button Parent
60
+ "floks.button": ComponentThemeContractSchema.parse({
61
+ componentId: "floks.button",
62
+ componentVersion: "1.0.0",
63
+ displayName: "Button Component",
64
+ slots: [
65
+ { id: "container", acceptedElementTypes: ["shape", "frame", "mesh"], required: true },
66
+ { id: "icon", acceptedElementTypes: ["icon", "svg", "glyph"], required: false },
67
+ { id: "label", acceptedElementTypes: ["text", "typography"], required: true },
68
+ { id: "indicator", acceptedElementTypes: ["badge", "dot", "counter"], required: false }
69
+ ],
70
+ states: [
71
+ { id: "idle", parameters: [] },
72
+ { id: "hover", parameters: [] },
73
+ { id: "active", parameters: [] },
74
+ { id: "disabled", parameters: [] },
75
+ { id: "focus", parameters: [] }
76
+ ],
77
+ parameters: [
78
+ { id: "background", type: "color", default: "var(--skipo-surface-2)" },
79
+ { id: "textColor", type: "color", default: "var(--skipo-text-primary)" },
80
+ { id: "borderColor", type: "color", default: "var(--skipo-border)" },
81
+ { id: "borderWidth", type: "dimension", default: "1px" },
82
+ { id: "borderRadius", type: "dimension", default: "6px" },
83
+ { id: "padding", type: "dimension", default: "8px 16px" },
84
+ { id: "fontSize", type: "dimension", default: "13px" }
85
+ ],
86
+ assets: ["svg", "bitmap"]
87
+ }),
88
+ // 2. Panel Parent
89
+ "floks.panel": ComponentThemeContractSchema.parse({
90
+ componentId: "floks.panel",
91
+ componentVersion: "1.0.0",
92
+ displayName: "Panel Component",
93
+ slots: [
94
+ { id: "header", acceptedElementTypes: ["frame", "strip"], required: false },
95
+ { id: "content", acceptedElementTypes: ["container", "layout"], required: true },
96
+ { id: "footer", acceptedElementTypes: ["strip", "action-bar"], required: false },
97
+ { id: "border-frame", acceptedElementTypes: ["frame", "shape"], required: false }
98
+ ],
99
+ states: [
100
+ { id: "default", parameters: [] },
101
+ { id: "expanded", parameters: [] },
102
+ { id: "collapsed", parameters: [] },
103
+ { id: "minimized", parameters: [] }
104
+ ],
105
+ parameters: [
106
+ { id: "background", type: "color", default: "var(--skipo-surface-1)" },
107
+ { id: "borderColor", type: "color", default: "var(--skipo-border)" },
108
+ { id: "borderRadius", type: "dimension", default: "8px" },
109
+ { id: "elevation", type: "shadow", default: "0 4px 12px rgba(0,0,0,0.4)" },
110
+ { id: "padding", type: "dimension", default: "12px" }
111
+ ],
112
+ assets: ["svg", "bitmap", "shader"]
113
+ }),
114
+ // 3. Slider Input
115
+ "floks.input.slider": ComponentThemeContractSchema.parse({
116
+ componentId: "floks.input.slider",
117
+ componentVersion: "1.0.0",
118
+ displayName: "Slider Input Component",
119
+ slots: [
120
+ { id: "track", acceptedElementTypes: ["bar", "curve"], required: true },
121
+ { id: "fill", acceptedElementTypes: ["bar", "gradient"], required: true },
122
+ { id: "thumb", acceptedElementTypes: ["handle", "circle", "icon"], required: true },
123
+ { id: "value-label", acceptedElementTypes: ["text", "bubble"], required: false }
124
+ ],
125
+ states: [
126
+ { id: "idle", parameters: [] },
127
+ { id: "hover", parameters: [] },
128
+ { id: "dragging", parameters: [] },
129
+ { id: "disabled", parameters: [] }
130
+ ],
131
+ parameters: [
132
+ { id: "trackColor", type: "color", default: "var(--skipo-surface-3)" },
133
+ { id: "fillColor", type: "color", default: "var(--skipo-accent)" },
134
+ { id: "thumbColor", type: "color", default: "var(--skipo-surface-1)" },
135
+ { id: "thumbSize", type: "dimension", default: "14px" },
136
+ { id: "height", type: "dimension", default: "6px" }
137
+ ],
138
+ assets: ["svg", "bitmap"]
139
+ }),
140
+ // 4. Badge
141
+ "floks.badge": ComponentThemeContractSchema.parse({
142
+ componentId: "floks.badge",
143
+ componentVersion: "1.0.0",
144
+ displayName: "Badge Component",
145
+ slots: [
146
+ { id: "pill", acceptedElementTypes: ["shape", "pill"], required: true },
147
+ { id: "indicator-dot", acceptedElementTypes: ["dot", "icon"], required: false },
148
+ { id: "text", acceptedElementTypes: ["typography"], required: true }
149
+ ],
150
+ states: [
151
+ { id: "default", parameters: [] },
152
+ { id: "pulse", parameters: [] }
153
+ ],
154
+ parameters: [
155
+ { id: "background", type: "color", default: "var(--skipo-surface-2)" },
156
+ { id: "textColor", type: "color", default: "var(--skipo-text-secondary)" },
157
+ { id: "dotColor", type: "color", default: "var(--skipo-accent)" }
158
+ ],
159
+ assets: ["svg"]
160
+ }),
161
+ // 5. 2D Graph Socket
162
+ "floks.socket2d": ComponentThemeContractSchema.parse({
163
+ componentId: "floks.socket2d",
164
+ componentVersion: "1.0.0",
165
+ displayName: "2D Graph Socket",
166
+ slots: [
167
+ { id: "ring", acceptedElementTypes: ["circle", "ring"], required: true },
168
+ { id: "indicator-dot", acceptedElementTypes: ["circle", "dot"], required: false },
169
+ { id: "glow", acceptedElementTypes: ["radial-glow"], required: false }
170
+ ],
171
+ states: [
172
+ { id: "idle", parameters: [] },
173
+ { id: "hover", parameters: [] },
174
+ { id: "connected", parameters: [] },
175
+ { id: "compatible-hover", parameters: [] }
176
+ ],
177
+ parameters: [
178
+ { id: "color", type: "color", default: "#ffaa00" },
179
+ { id: "radius", type: "dimension", default: "6px" },
180
+ { id: "glowRadius", type: "dimension", default: "12px" }
181
+ ],
182
+ assets: ["svg"]
183
+ }),
184
+ // 6. 2D Graph Wire
185
+ "floks.wire2d": ComponentThemeContractSchema.parse({
186
+ componentId: "floks.wire2d",
187
+ componentVersion: "1.0.0",
188
+ displayName: "2D Graph Wire",
189
+ slots: [
190
+ { id: "trace", acceptedElementTypes: ["path", "spline"], required: true },
191
+ { id: "pulse-particle", acceptedElementTypes: ["particle", "pulse"], required: false },
192
+ { id: "endpoint", acceptedElementTypes: ["handle", "arrow"], required: false }
193
+ ],
194
+ states: [
195
+ { id: "idle", parameters: [] },
196
+ { id: "active", parameters: [] },
197
+ { id: "selected", parameters: [] },
198
+ { id: "error", parameters: [] }
199
+ ],
200
+ parameters: [
201
+ { id: "strokeColor", type: "color", default: "#00ffff" },
202
+ { id: "strokeWidth", type: "dimension", default: "2px" },
203
+ { id: "opacity", type: "number", default: 1 }
204
+ ],
205
+ assets: ["svg", "particle"]
206
+ }),
207
+ // 7. 2D Node Base
208
+ "floks.node2d": ComponentThemeContractSchema.parse({
209
+ componentId: "floks.node2d",
210
+ componentVersion: "1.0.0",
211
+ displayName: "2D Graph Node Card",
212
+ slots: [
213
+ { id: "header", acceptedElementTypes: ["strip", "banner"], required: true },
214
+ { id: "body", acceptedElementTypes: ["container", "surface"], required: true },
215
+ { id: "footer", acceptedElementTypes: ["strip"], required: false },
216
+ { id: "socket-strip", acceptedElementTypes: ["column", "row"], required: true }
217
+ ],
218
+ states: [
219
+ { id: "idle", parameters: [] },
220
+ { id: "selected", parameters: [] },
221
+ { id: "running", parameters: [] },
222
+ { id: "bypassed", parameters: [] },
223
+ { id: "minimized", parameters: [] }
224
+ ],
225
+ parameters: [
226
+ { id: "headerColor", type: "color", default: "var(--skipo-surface-2)" },
227
+ { id: "bodyColor", type: "color", default: "var(--skipo-surface-1)" },
228
+ { id: "borderColor", type: "color", default: "var(--skipo-border)" },
229
+ { id: "cornerRadius", type: "dimension", default: "8px" }
230
+ ],
231
+ assets: ["svg", "bitmap"]
232
+ })
233
+ };
234
+ function getComponentContract(componentId) {
235
+ return FLOKS_COMPONENT_REGISTRY[componentId];
236
+ }
237
+ function listComponentContracts() {
238
+ return Object.values(FLOKS_COMPONENT_REGISTRY);
239
+ }
240
+
241
+ // src/validator.ts
242
+ function validateThemePackAgainstContract(themePack, contract) {
243
+ const errors = [];
244
+ const warnings = [];
245
+ const targetCompId = themePack.target.componentId;
246
+ const targetContract = contract ?? FLOKS_COMPONENT_REGISTRY[targetCompId];
247
+ if (!targetContract) {
248
+ return {
249
+ valid: false,
250
+ errors: [`Target component '${targetCompId}' is not registered in Floks ComponentThemeContract registry.`],
251
+ warnings: [],
252
+ targetComponentId: targetCompId
253
+ };
254
+ }
255
+ if (themePack.target.library !== "@ultrst-armada/floks") {
256
+ errors.push(`Invalid target library '${themePack.target.library}'. Must be '@ultrst-armada/floks'.`);
257
+ }
258
+ const allowedSlotIds = new Set(targetContract.slots.map((s) => s.id));
259
+ for (const s of themePack.slots) {
260
+ if (!allowedSlotIds.has(s.slotId)) {
261
+ errors.push(`Slot '${s.slotId}' is not defined in contract for '${targetCompId}'.`);
262
+ } else {
263
+ const slotDef = targetContract.slots.find((slot) => slot.id === s.slotId);
264
+ if (slotDef && !slotDef.acceptedElementTypes.includes(s.elementType)) {
265
+ errors.push(
266
+ `Slot '${s.slotId}' rejects element type '${s.elementType}'. Accepted types: [${slotDef.acceptedElementTypes.join(", ")}]`
267
+ );
268
+ }
269
+ }
270
+ }
271
+ const presentSlotIds = new Set(themePack.slots.map((s) => s.slotId));
272
+ for (const requiredSlot of targetContract.slots.filter((s) => s.required)) {
273
+ if (!presentSlotIds.has(requiredSlot.id)) {
274
+ warnings.push(`Required slot '${requiredSlot.id}' is not explicitly bound in theme.`);
275
+ }
276
+ }
277
+ const allowedStateIds = new Set(targetContract.states.map((st) => st.id));
278
+ for (const st of themePack.states) {
279
+ if (!allowedStateIds.has(st.stateId)) {
280
+ errors.push(`State '${st.stateId}' is not recognized by contract for '${targetCompId}'.`);
281
+ }
282
+ }
283
+ const allowedParamIds = new Set(targetContract.parameters.map((p) => p.id));
284
+ for (const paramKey of Object.keys(themePack.parameters)) {
285
+ if (!allowedParamIds.has(paramKey)) {
286
+ warnings.push(`Unknown visual parameter '${paramKey}' ignored by '${targetCompId}'.`);
287
+ }
288
+ }
289
+ const allowedAssets = new Set(targetContract.assets);
290
+ for (const asset of themePack.assetTypes) {
291
+ if (!allowedAssets.has(asset)) {
292
+ errors.push(`Asset type '${asset}' is not accepted by '${targetCompId}'. Allowed: [${targetContract.assets.join(", ")}]`);
293
+ }
294
+ }
295
+ return {
296
+ valid: errors.length === 0,
297
+ errors,
298
+ warnings,
299
+ targetComponentId: targetCompId
300
+ };
301
+ }
302
+ function loadThemePack(raw) {
303
+ const parsed = ThemePackSchema.parse(raw);
304
+ const result = validateThemePackAgainstContract(parsed);
305
+ if (!result.valid) {
306
+ throw new Error(`Invalid Floks ThemePack: ${result.errors.join("; ")}`);
307
+ }
308
+ return parsed;
309
+ }
310
+ export {
311
+ ComponentThemeContractSchema,
312
+ FLOKS_COMPONENT_REGISTRY,
313
+ ThemePackSchema,
314
+ ThemePackSlotBindingSchema,
315
+ ThemePackStateMappingSchema,
316
+ ThemeTargetSchema,
317
+ VisualParameterSchema,
318
+ VisualSlotSchema,
319
+ VisualStateSchema,
320
+ getComponentContract,
321
+ listComponentContracts,
322
+ loadThemePack,
323
+ validateThemePackAgainstContract
324
+ };
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@floks/contracts",
3
+ "version": "1.0.0",
4
+ "description": "Floks Canonical Component Theme Contracts, Visual Slots, States, Parameters, and Compatibility Validation for Theta Engine",
5
+ "type": "module",
6
+ "private": false,
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "registry": "https://registry.npmjs.org/"
10
+ },
11
+ "skipoManifest": "./floks.manifest.json",
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "import": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ }
21
+ },
22
+ "scripts": {
23
+ "build": "tsup src/index.ts --format esm --dts --clean --external zod",
24
+ "typecheck": "tsc --noEmit",
25
+ "clean": "rm -rf dist"
26
+ },
27
+ "dependencies": {
28
+ "zod": "^3.24.1"
29
+ }
30
+ }
@@ -1,9 +1,3 @@
1
- import {
2
- AppShell,
3
- BreadcrumbNav,
4
- HeaderBar,
5
- TopToolbar
6
- } from "./chunk-GWW3BGOB.js";
7
1
  import {
8
2
  DEFAULT_PANEL_GEOMETRY,
9
3
  DrawerContainer,
@@ -18,6 +12,12 @@ import {
18
12
  usePanelGeometry,
19
13
  usePanelInteraction
20
14
  } from "./chunk-TXKLROFC.js";
15
+ import {
16
+ AppShell,
17
+ BreadcrumbNav,
18
+ HeaderBar,
19
+ TopToolbar
20
+ } from "./chunk-GWW3BGOB.js";
21
21
  import {
22
22
  SettingsTab,
23
23
  ThemeSettingsSection
@@ -129,13 +129,6 @@ import {
129
129
  import {
130
130
  LoginModal
131
131
  } from "./chunk-S227WJ5E.js";
132
- import {
133
- BaseSelect,
134
- BaseTextarea,
135
- BaseToggle,
136
- CredentialField,
137
- KNOWN_CREDENTIAL_URLS
138
- } from "./chunk-KIFQA7L6.js";
139
132
  import "./chunk-5ZMXFCD4.js";
140
133
  import {
141
134
  ApiCallIndicator,
@@ -144,6 +137,13 @@ import {
144
137
  StatusLight,
145
138
  SystemMessageDisplay
146
139
  } from "./chunk-C3L53YN4.js";
140
+ import {
141
+ BaseSelect,
142
+ BaseTextarea,
143
+ BaseToggle,
144
+ CredentialField,
145
+ KNOWN_CREDENTIAL_URLS
146
+ } from "./chunk-KIFQA7L6.js";
147
147
  import {
148
148
  ConfirmDialog,
149
149
  CopyableErrorAlert,