@plures/praxis 0.2.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.
Files changed (263) hide show
  1. package/FRAMEWORK.md +420 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1310 -0
  4. package/dist/adapters/cli.d.ts +43 -0
  5. package/dist/adapters/cli.d.ts.map +1 -0
  6. package/dist/adapters/cli.js +126 -0
  7. package/dist/adapters/cli.js.map +1 -0
  8. package/dist/cli/commands/auth.d.ts +26 -0
  9. package/dist/cli/commands/auth.d.ts.map +1 -0
  10. package/dist/cli/commands/auth.js +233 -0
  11. package/dist/cli/commands/auth.js.map +1 -0
  12. package/dist/cli/commands/cloud.d.ts +27 -0
  13. package/dist/cli/commands/cloud.d.ts.map +1 -0
  14. package/dist/cli/commands/cloud.js +232 -0
  15. package/dist/cli/commands/cloud.js.map +1 -0
  16. package/dist/cli/commands/generate.d.ts +25 -0
  17. package/dist/cli/commands/generate.d.ts.map +1 -0
  18. package/dist/cli/commands/generate.js +168 -0
  19. package/dist/cli/commands/generate.js.map +1 -0
  20. package/dist/cli/index.d.ts +8 -0
  21. package/dist/cli/index.d.ts.map +1 -0
  22. package/dist/cli/index.js +179 -0
  23. package/dist/cli/index.js.map +1 -0
  24. package/dist/cloud/auth.d.ts +51 -0
  25. package/dist/cloud/auth.d.ts.map +1 -0
  26. package/dist/cloud/auth.js +194 -0
  27. package/dist/cloud/auth.js.map +1 -0
  28. package/dist/cloud/billing.d.ts +184 -0
  29. package/dist/cloud/billing.d.ts.map +1 -0
  30. package/dist/cloud/billing.js +179 -0
  31. package/dist/cloud/billing.js.map +1 -0
  32. package/dist/cloud/client.d.ts +39 -0
  33. package/dist/cloud/client.d.ts.map +1 -0
  34. package/dist/cloud/client.js +176 -0
  35. package/dist/cloud/client.js.map +1 -0
  36. package/dist/cloud/index.d.ts +44 -0
  37. package/dist/cloud/index.d.ts.map +1 -0
  38. package/dist/cloud/index.js +44 -0
  39. package/dist/cloud/index.js.map +1 -0
  40. package/dist/cloud/marketplace.d.ts +166 -0
  41. package/dist/cloud/marketplace.d.ts.map +1 -0
  42. package/dist/cloud/marketplace.js +159 -0
  43. package/dist/cloud/marketplace.js.map +1 -0
  44. package/dist/cloud/provisioning.d.ts +110 -0
  45. package/dist/cloud/provisioning.d.ts.map +1 -0
  46. package/dist/cloud/provisioning.js +148 -0
  47. package/dist/cloud/provisioning.js.map +1 -0
  48. package/dist/cloud/relay/endpoints.d.ts +62 -0
  49. package/dist/cloud/relay/endpoints.d.ts.map +1 -0
  50. package/dist/cloud/relay/endpoints.js +217 -0
  51. package/dist/cloud/relay/endpoints.js.map +1 -0
  52. package/dist/cloud/relay/health/index.d.ts +5 -0
  53. package/dist/cloud/relay/health/index.d.ts.map +1 -0
  54. package/dist/cloud/relay/health/index.js +9 -0
  55. package/dist/cloud/relay/health/index.js.map +1 -0
  56. package/dist/cloud/relay/stats/index.d.ts +5 -0
  57. package/dist/cloud/relay/stats/index.d.ts.map +1 -0
  58. package/dist/cloud/relay/stats/index.js +9 -0
  59. package/dist/cloud/relay/stats/index.js.map +1 -0
  60. package/dist/cloud/relay/sync/index.d.ts +5 -0
  61. package/dist/cloud/relay/sync/index.d.ts.map +1 -0
  62. package/dist/cloud/relay/sync/index.js +9 -0
  63. package/dist/cloud/relay/sync/index.js.map +1 -0
  64. package/dist/cloud/relay/usage/index.d.ts +5 -0
  65. package/dist/cloud/relay/usage/index.d.ts.map +1 -0
  66. package/dist/cloud/relay/usage/index.js +9 -0
  67. package/dist/cloud/relay/usage/index.js.map +1 -0
  68. package/dist/cloud/sponsors.d.ts +81 -0
  69. package/dist/cloud/sponsors.d.ts.map +1 -0
  70. package/dist/cloud/sponsors.js +130 -0
  71. package/dist/cloud/sponsors.js.map +1 -0
  72. package/dist/cloud/types.d.ts +169 -0
  73. package/dist/cloud/types.d.ts.map +1 -0
  74. package/dist/cloud/types.js +7 -0
  75. package/dist/cloud/types.js.map +1 -0
  76. package/dist/components/index.d.ts +43 -0
  77. package/dist/components/index.d.ts.map +1 -0
  78. package/dist/components/index.js +17 -0
  79. package/dist/components/index.js.map +1 -0
  80. package/dist/core/actors.d.ts +95 -0
  81. package/dist/core/actors.d.ts.map +1 -0
  82. package/dist/core/actors.js +158 -0
  83. package/dist/core/actors.js.map +1 -0
  84. package/dist/core/component/generator.d.ts +122 -0
  85. package/dist/core/component/generator.d.ts.map +1 -0
  86. package/dist/core/component/generator.js +307 -0
  87. package/dist/core/component/generator.js.map +1 -0
  88. package/dist/core/engine.d.ts +92 -0
  89. package/dist/core/engine.d.ts.map +1 -0
  90. package/dist/core/engine.js +199 -0
  91. package/dist/core/engine.js.map +1 -0
  92. package/dist/core/introspection.d.ts +141 -0
  93. package/dist/core/introspection.d.ts.map +1 -0
  94. package/dist/core/introspection.js +208 -0
  95. package/dist/core/introspection.js.map +1 -0
  96. package/dist/core/logic/generator.d.ts +76 -0
  97. package/dist/core/logic/generator.d.ts.map +1 -0
  98. package/dist/core/logic/generator.js +339 -0
  99. package/dist/core/logic/generator.js.map +1 -0
  100. package/dist/core/pluresdb/generator.d.ts +58 -0
  101. package/dist/core/pluresdb/generator.d.ts.map +1 -0
  102. package/dist/core/pluresdb/generator.js +162 -0
  103. package/dist/core/pluresdb/generator.js.map +1 -0
  104. package/dist/core/protocol.d.ts +121 -0
  105. package/dist/core/protocol.d.ts.map +1 -0
  106. package/dist/core/protocol.js +46 -0
  107. package/dist/core/protocol.js.map +1 -0
  108. package/dist/core/rules.d.ts +120 -0
  109. package/dist/core/rules.d.ts.map +1 -0
  110. package/dist/core/rules.js +81 -0
  111. package/dist/core/rules.js.map +1 -0
  112. package/dist/core/schema/loader.d.ts +47 -0
  113. package/dist/core/schema/loader.d.ts.map +1 -0
  114. package/dist/core/schema/loader.js +189 -0
  115. package/dist/core/schema/loader.js.map +1 -0
  116. package/dist/core/schema/normalize.d.ts +72 -0
  117. package/dist/core/schema/normalize.d.ts.map +1 -0
  118. package/dist/core/schema/normalize.js +190 -0
  119. package/dist/core/schema/normalize.js.map +1 -0
  120. package/dist/core/schema/types.d.ts +370 -0
  121. package/dist/core/schema/types.d.ts.map +1 -0
  122. package/dist/core/schema/types.js +161 -0
  123. package/dist/core/schema/types.js.map +1 -0
  124. package/dist/dsl/index.d.ts +152 -0
  125. package/dist/dsl/index.d.ts.map +1 -0
  126. package/dist/dsl/index.js +132 -0
  127. package/dist/dsl/index.js.map +1 -0
  128. package/dist/dsl.d.ts +124 -0
  129. package/dist/dsl.d.ts.map +1 -0
  130. package/dist/dsl.js +130 -0
  131. package/dist/dsl.js.map +1 -0
  132. package/dist/examples/advanced-todo/index.d.ts +55 -0
  133. package/dist/examples/advanced-todo/index.d.ts.map +1 -0
  134. package/dist/examples/advanced-todo/index.js +222 -0
  135. package/dist/examples/advanced-todo/index.js.map +1 -0
  136. package/dist/examples/auth-basic/index.d.ts +17 -0
  137. package/dist/examples/auth-basic/index.d.ts.map +1 -0
  138. package/dist/examples/auth-basic/index.js +122 -0
  139. package/dist/examples/auth-basic/index.js.map +1 -0
  140. package/dist/examples/cart/index.d.ts +19 -0
  141. package/dist/examples/cart/index.d.ts.map +1 -0
  142. package/dist/examples/cart/index.js +202 -0
  143. package/dist/examples/cart/index.js.map +1 -0
  144. package/dist/examples/hero-ecommerce/index.d.ts +39 -0
  145. package/dist/examples/hero-ecommerce/index.d.ts.map +1 -0
  146. package/dist/examples/hero-ecommerce/index.js +506 -0
  147. package/dist/examples/hero-ecommerce/index.js.map +1 -0
  148. package/dist/examples/svelte-counter/index.d.ts +31 -0
  149. package/dist/examples/svelte-counter/index.d.ts.map +1 -0
  150. package/dist/examples/svelte-counter/index.js +123 -0
  151. package/dist/examples/svelte-counter/index.js.map +1 -0
  152. package/dist/flows.d.ts +125 -0
  153. package/dist/flows.d.ts.map +1 -0
  154. package/dist/flows.js +160 -0
  155. package/dist/flows.js.map +1 -0
  156. package/dist/index.d.ts +67 -0
  157. package/dist/index.d.ts.map +1 -0
  158. package/dist/index.js +59 -0
  159. package/dist/index.js.map +1 -0
  160. package/dist/integrations/pluresdb.d.ts +56 -0
  161. package/dist/integrations/pluresdb.d.ts.map +1 -0
  162. package/dist/integrations/pluresdb.js +46 -0
  163. package/dist/integrations/pluresdb.js.map +1 -0
  164. package/dist/integrations/svelte.d.ts +306 -0
  165. package/dist/integrations/svelte.d.ts.map +1 -0
  166. package/dist/integrations/svelte.js +447 -0
  167. package/dist/integrations/svelte.js.map +1 -0
  168. package/dist/registry.d.ts +94 -0
  169. package/dist/registry.d.ts.map +1 -0
  170. package/dist/registry.js +181 -0
  171. package/dist/registry.js.map +1 -0
  172. package/dist/runtime/terminal-adapter.d.ts +105 -0
  173. package/dist/runtime/terminal-adapter.d.ts.map +1 -0
  174. package/dist/runtime/terminal-adapter.js +113 -0
  175. package/dist/runtime/terminal-adapter.js.map +1 -0
  176. package/dist/step.d.ts +34 -0
  177. package/dist/step.d.ts.map +1 -0
  178. package/dist/step.js +111 -0
  179. package/dist/step.js.map +1 -0
  180. package/dist/types.d.ts +63 -0
  181. package/dist/types.d.ts.map +1 -0
  182. package/dist/types.js +6 -0
  183. package/dist/types.js.map +1 -0
  184. package/docs/MONETIZATION.md +394 -0
  185. package/docs/TERMINAL_NODE.md +588 -0
  186. package/docs/guides/canvas.md +389 -0
  187. package/docs/guides/getting-started.md +347 -0
  188. package/docs/guides/history-state-pattern.md +618 -0
  189. package/docs/guides/orchestration.md +617 -0
  190. package/docs/guides/parallel-state-pattern.md +767 -0
  191. package/docs/guides/svelte-integration.md +691 -0
  192. package/package.json +96 -0
  193. package/src/__tests__/actors.test.ts +270 -0
  194. package/src/__tests__/billing.test.ts +175 -0
  195. package/src/__tests__/cloud.test.ts +247 -0
  196. package/src/__tests__/dsl.test.ts +154 -0
  197. package/src/__tests__/edge-cases.test.ts +475 -0
  198. package/src/__tests__/engine.test.ts +137 -0
  199. package/src/__tests__/generators.test.ts +270 -0
  200. package/src/__tests__/introspection.test.ts +321 -0
  201. package/src/__tests__/protocol.test.ts +40 -0
  202. package/src/__tests__/provisioning.test.ts +162 -0
  203. package/src/__tests__/schema.test.ts +241 -0
  204. package/src/__tests__/svelte-integration.test.ts +431 -0
  205. package/src/__tests__/terminal-node.test.ts +352 -0
  206. package/src/adapters/cli.ts +175 -0
  207. package/src/cli/commands/auth.ts +271 -0
  208. package/src/cli/commands/cloud.ts +281 -0
  209. package/src/cli/commands/generate.ts +225 -0
  210. package/src/cli/index.ts +190 -0
  211. package/src/cloud/README.md +383 -0
  212. package/src/cloud/auth.ts +245 -0
  213. package/src/cloud/billing.ts +336 -0
  214. package/src/cloud/client.ts +221 -0
  215. package/src/cloud/index.ts +121 -0
  216. package/src/cloud/marketplace.ts +303 -0
  217. package/src/cloud/provisioning.ts +254 -0
  218. package/src/cloud/relay/endpoints.ts +307 -0
  219. package/src/cloud/relay/health/function.json +17 -0
  220. package/src/cloud/relay/health/index.ts +10 -0
  221. package/src/cloud/relay/host.json +15 -0
  222. package/src/cloud/relay/local.settings.json +8 -0
  223. package/src/cloud/relay/stats/function.json +17 -0
  224. package/src/cloud/relay/stats/index.ts +10 -0
  225. package/src/cloud/relay/sync/function.json +17 -0
  226. package/src/cloud/relay/sync/index.ts +10 -0
  227. package/src/cloud/relay/usage/function.json +17 -0
  228. package/src/cloud/relay/usage/index.ts +10 -0
  229. package/src/cloud/sponsors.ts +213 -0
  230. package/src/cloud/types.ts +198 -0
  231. package/src/components/README.md +125 -0
  232. package/src/components/TerminalNode.svelte +457 -0
  233. package/src/components/index.ts +46 -0
  234. package/src/core/actors.ts +205 -0
  235. package/src/core/component/generator.ts +432 -0
  236. package/src/core/engine.ts +243 -0
  237. package/src/core/introspection.ts +329 -0
  238. package/src/core/logic/generator.ts +420 -0
  239. package/src/core/pluresdb/generator.ts +229 -0
  240. package/src/core/protocol.ts +132 -0
  241. package/src/core/rules.ts +167 -0
  242. package/src/core/schema/loader.ts +247 -0
  243. package/src/core/schema/normalize.ts +322 -0
  244. package/src/core/schema/types.ts +557 -0
  245. package/src/dsl/index.ts +218 -0
  246. package/src/dsl.ts +214 -0
  247. package/src/examples/advanced-todo/App.svelte +506 -0
  248. package/src/examples/advanced-todo/README.md +371 -0
  249. package/src/examples/advanced-todo/index.ts +309 -0
  250. package/src/examples/auth-basic/index.ts +163 -0
  251. package/src/examples/cart/index.ts +259 -0
  252. package/src/examples/hero-ecommerce/index.ts +657 -0
  253. package/src/examples/svelte-counter/index.ts +168 -0
  254. package/src/flows.ts +268 -0
  255. package/src/index.ts +154 -0
  256. package/src/integrations/pluresdb.ts +93 -0
  257. package/src/integrations/svelte.ts +617 -0
  258. package/src/registry.ts +223 -0
  259. package/src/runtime/terminal-adapter.ts +175 -0
  260. package/src/step.ts +151 -0
  261. package/src/types.ts +70 -0
  262. package/templates/basic-app/README.md +147 -0
  263. package/templates/fullstack-app/README.md +279 -0
@@ -0,0 +1,557 @@
1
+ /**
2
+ * Praxis Schema System
3
+ *
4
+ * Declarative schema definitions for generating models, components, logic, and documentation.
5
+ */
6
+
7
+ /**
8
+ * Base schema definition
9
+ */
10
+ export interface PraxisSchema {
11
+ /** Schema version (semver) */
12
+ version: string;
13
+ /** Schema name/identifier */
14
+ name: string;
15
+ /** Human-readable description */
16
+ description?: string;
17
+ /** Data models */
18
+ models?: ModelDefinition[];
19
+ /** UI components */
20
+ components?: ComponentDefinition[];
21
+ /** Logic definitions */
22
+ logic?: LogicDefinition[];
23
+ /** Orchestration configuration */
24
+ orchestration?: OrchestrationDefinition;
25
+ /** Additional metadata */
26
+ metadata?: Record<string, unknown>;
27
+ }
28
+
29
+ /**
30
+ * Model definition for data structures
31
+ */
32
+ export interface ModelDefinition {
33
+ /** Model name */
34
+ name: string;
35
+ /** Model description */
36
+ description?: string;
37
+ /** Model fields */
38
+ fields: FieldDefinition[];
39
+ /** Validation constraints */
40
+ constraints?: ConstraintDefinition[];
41
+ /** Indexes for queries */
42
+ indexes?: IndexDefinition[];
43
+ /** Relationships to other models */
44
+ relationships?: RelationshipDefinition[];
45
+ }
46
+
47
+ /**
48
+ * Field definition within a model
49
+ */
50
+ export interface FieldDefinition {
51
+ /** Field name */
52
+ name: string;
53
+ /** Field type */
54
+ type: FieldType;
55
+ /** Optional field */
56
+ optional?: boolean;
57
+ /** Default value */
58
+ default?: unknown;
59
+ /** Field description */
60
+ description?: string;
61
+ /** Validation rules */
62
+ validation?: ValidationRule[];
63
+ }
64
+
65
+ /**
66
+ * Supported field types
67
+ */
68
+ export type FieldType =
69
+ | 'string'
70
+ | 'number'
71
+ | 'boolean'
72
+ | 'date'
73
+ | 'array'
74
+ | 'object'
75
+ | 'reference'
76
+ | { array: FieldType }
77
+ | { object: Record<string, FieldDefinition> }
78
+ | { reference: string };
79
+
80
+ /**
81
+ * Validation rule for a field
82
+ */
83
+ export interface ValidationRule {
84
+ /** Validation type */
85
+ type: 'required' | 'min' | 'max' | 'pattern' | 'custom';
86
+ /** Validation value */
87
+ value?: unknown;
88
+ /** Error message */
89
+ message?: string;
90
+ }
91
+
92
+ /**
93
+ * Constraint definition for models
94
+ */
95
+ export interface ConstraintDefinition {
96
+ /** Constraint identifier */
97
+ id: string;
98
+ /** Constraint description */
99
+ description: string;
100
+ /** Constraint type */
101
+ type: 'unique' | 'check' | 'foreign_key';
102
+ /** Constraint fields */
103
+ fields: string[];
104
+ /** Additional constraint options */
105
+ options?: Record<string, unknown>;
106
+ }
107
+
108
+ /**
109
+ * Index definition for queries
110
+ */
111
+ export interface IndexDefinition {
112
+ /** Index name */
113
+ name: string;
114
+ /** Indexed fields */
115
+ fields: string[];
116
+ /** Unique index */
117
+ unique?: boolean;
118
+ /** Index type */
119
+ type?: 'btree' | 'hash' | 'fulltext';
120
+ }
121
+
122
+ /**
123
+ * Relationship definition between models
124
+ */
125
+ export interface RelationshipDefinition {
126
+ /** Relationship name */
127
+ name: string;
128
+ /** Relationship type */
129
+ type: 'one-to-one' | 'one-to-many' | 'many-to-many';
130
+ /** Target model */
131
+ target: string;
132
+ /** Foreign key field */
133
+ foreignKey?: string;
134
+ /** Cascade delete */
135
+ cascadeDelete?: boolean;
136
+ }
137
+
138
+ /**
139
+ * Component definition for UI
140
+ */
141
+ export interface ComponentDefinition {
142
+ /** Component name */
143
+ name: string;
144
+ /** Component type */
145
+ type: 'form' | 'display' | 'list' | 'navigation' | 'custom';
146
+ /** Component description */
147
+ description?: string;
148
+ /** Model binding */
149
+ model?: string;
150
+ /** Component properties */
151
+ props?: ComponentProp[];
152
+ /** Component events */
153
+ events?: ComponentEvent[];
154
+ /** Component layout */
155
+ layout?: LayoutDefinition;
156
+ /** Component styling */
157
+ styling?: StylingDefinition;
158
+ }
159
+
160
+ /**
161
+ * Component property definition
162
+ */
163
+ export interface ComponentProp {
164
+ /** Property name */
165
+ name: string;
166
+ /** Property type */
167
+ type: string;
168
+ /** Required property */
169
+ required?: boolean;
170
+ /** Default value */
171
+ default?: unknown;
172
+ /** Property description */
173
+ description?: string;
174
+ }
175
+
176
+ /**
177
+ * Component event definition
178
+ */
179
+ export interface ComponentEvent {
180
+ /** Event name */
181
+ name: string;
182
+ /** Event payload type */
183
+ payload?: string;
184
+ /** Event description */
185
+ description?: string;
186
+ }
187
+
188
+ /**
189
+ * Layout definition for components
190
+ */
191
+ export interface LayoutDefinition {
192
+ /** Layout type */
193
+ type: 'stack' | 'grid' | 'flex' | 'absolute';
194
+ /** Layout direction */
195
+ direction?: 'horizontal' | 'vertical';
196
+ /** Layout gap */
197
+ gap?: number;
198
+ /** Layout padding */
199
+ padding?: number;
200
+ /** Layout alignment */
201
+ alignment?: string;
202
+ }
203
+
204
+ /**
205
+ * Styling definition for components
206
+ */
207
+ export interface StylingDefinition {
208
+ /** CSS classes */
209
+ classes?: string[];
210
+ /** Inline styles */
211
+ styles?: Record<string, string>;
212
+ /** Theme tokens */
213
+ theme?: Record<string, string>;
214
+ }
215
+
216
+ /**
217
+ * Logic definition for business rules
218
+ */
219
+ export interface LogicDefinition {
220
+ /** Logic identifier */
221
+ id: string;
222
+ /** Logic description */
223
+ description: string;
224
+ /** Facts definitions */
225
+ facts?: FactDefinition[];
226
+ /** Events definitions */
227
+ events?: EventDefinition[];
228
+ /** Rules definitions */
229
+ rules?: RuleDefinition[];
230
+ /** Constraints definitions */
231
+ constraints?: LogicConstraint[];
232
+ }
233
+
234
+ /**
235
+ * Fact definition
236
+ */
237
+ export interface FactDefinition {
238
+ /** Fact tag */
239
+ tag: string;
240
+ /** Fact payload type */
241
+ payload: Record<string, string>;
242
+ /** Fact description */
243
+ description?: string;
244
+ }
245
+
246
+ /**
247
+ * Event definition
248
+ */
249
+ export interface EventDefinition {
250
+ /** Event tag */
251
+ tag: string;
252
+ /** Event payload type */
253
+ payload: Record<string, string>;
254
+ /** Event description */
255
+ description?: string;
256
+ }
257
+
258
+ /**
259
+ * Rule definition
260
+ */
261
+ export interface RuleDefinition {
262
+ /** Rule identifier */
263
+ id: string;
264
+ /** Rule description */
265
+ description: string;
266
+ /** Input events */
267
+ on?: string[];
268
+ /** Rule condition */
269
+ when?: string;
270
+ /** Rule action */
271
+ then: string;
272
+ /** Rule priority */
273
+ priority?: number;
274
+ }
275
+
276
+ /**
277
+ * Logic constraint definition
278
+ */
279
+ export interface LogicConstraint {
280
+ /** Constraint identifier */
281
+ id: string;
282
+ /** Constraint description */
283
+ description: string;
284
+ /** Constraint check */
285
+ check: string;
286
+ /** Error message */
287
+ message: string;
288
+ }
289
+
290
+ /**
291
+ * Orchestration definition
292
+ */
293
+ export interface OrchestrationDefinition {
294
+ /** Orchestration type */
295
+ type: 'dsc' | 'mcp' | 'custom';
296
+ /** Node configurations */
297
+ nodes?: NodeDefinition[];
298
+ /** State synchronization */
299
+ sync?: SyncDefinition;
300
+ /** Health checks */
301
+ health?: HealthDefinition;
302
+ }
303
+
304
+ /**
305
+ * Node definition for orchestration
306
+ */
307
+ export interface NodeDefinition {
308
+ /** Node identifier */
309
+ id: string;
310
+ /** Node type */
311
+ type: string;
312
+ /** Node configuration */
313
+ config: Record<string, unknown>;
314
+ /** Node position (x, y coordinates for canvas) */
315
+ x?: number;
316
+ y?: number;
317
+ /** Node props (type-specific properties) */
318
+ props?: Record<string, unknown>;
319
+ /** Node bindings (connections to pluresdb paths) */
320
+ bindings?: NodeBindings;
321
+ }
322
+
323
+ /**
324
+ * Node bindings for pluresdb path connections
325
+ */
326
+ export interface NodeBindings {
327
+ /** Output binding to pluresdb path */
328
+ output?: string;
329
+ /** Input binding to pluresdb path */
330
+ input?: string;
331
+ /** Additional custom bindings */
332
+ [key: string]: string | undefined;
333
+ }
334
+
335
+ /**
336
+ * Terminal node specific configuration
337
+ */
338
+ export interface TerminalNodeProps {
339
+ /** Input mode: text input or widget-based */
340
+ inputMode: 'text' | 'widget';
341
+ /** Command history */
342
+ history: string[];
343
+ /** Last command output */
344
+ lastOutput: string | null;
345
+ }
346
+
347
+ /**
348
+ * Sync definition for state synchronization
349
+ */
350
+ export interface SyncDefinition {
351
+ /** Sync interval in ms */
352
+ interval: number;
353
+ /** Conflict resolution strategy */
354
+ conflictResolution: 'last-write-wins' | 'merge' | 'custom';
355
+ /** Sync targets */
356
+ targets: string[];
357
+ }
358
+
359
+ /**
360
+ * Health check definition
361
+ */
362
+ export interface HealthDefinition {
363
+ /** Check interval in ms */
364
+ interval: number;
365
+ /** Health check endpoints */
366
+ endpoints: string[];
367
+ /** Timeout in ms */
368
+ timeout: number;
369
+ }
370
+
371
+ /**
372
+ * Schema validation result
373
+ */
374
+ export interface ValidationResult {
375
+ /** Validation success */
376
+ valid: boolean;
377
+ /** Validation errors */
378
+ errors: ValidationError[];
379
+ }
380
+
381
+ /**
382
+ * Validation error
383
+ */
384
+ export interface ValidationError {
385
+ /** Error path in schema */
386
+ path: string;
387
+ /** Error message */
388
+ message: string;
389
+ /** Error code */
390
+ code?: string;
391
+ }
392
+
393
+ /**
394
+ * Validate a Praxis schema
395
+ */
396
+ export function validateSchema(schema: PraxisSchema): ValidationResult {
397
+ const errors: ValidationError[] = [];
398
+
399
+ // Basic validation
400
+ if (!schema.version) {
401
+ errors.push({ path: 'version', message: 'Schema version is required' });
402
+ }
403
+ if (!schema.name) {
404
+ errors.push({ path: 'name', message: 'Schema name is required' });
405
+ }
406
+
407
+ // Validate models
408
+ if (schema.models) {
409
+ schema.models.forEach((model, index) => {
410
+ if (!model.name) {
411
+ errors.push({
412
+ path: `models[${index}].name`,
413
+ message: 'Model name is required',
414
+ });
415
+ }
416
+ if (!model.fields || model.fields.length === 0) {
417
+ errors.push({
418
+ path: `models[${index}].fields`,
419
+ message: 'Model must have at least one field',
420
+ });
421
+ }
422
+ });
423
+ }
424
+
425
+ // Validate components
426
+ if (schema.components) {
427
+ schema.components.forEach((component, index) => {
428
+ if (!component.name) {
429
+ errors.push({
430
+ path: `components[${index}].name`,
431
+ message: 'Component name is required',
432
+ });
433
+ }
434
+ if (!component.type) {
435
+ errors.push({
436
+ path: `components[${index}].type`,
437
+ message: 'Component type is required',
438
+ });
439
+ }
440
+ });
441
+ }
442
+
443
+ // Validate logic definitions
444
+ if (schema.logic) {
445
+ schema.logic.forEach((logic, logicIndex) => {
446
+ // Validate fact tags
447
+ if (logic.facts) {
448
+ logic.facts.forEach((fact, factIndex) => {
449
+ if (!fact.tag) {
450
+ errors.push({
451
+ path: `logic[${logicIndex}].facts[${factIndex}].tag`,
452
+ message: 'Fact tag is required',
453
+ });
454
+ } else if (!isValidIdentifier(fact.tag)) {
455
+ errors.push({
456
+ path: `logic[${logicIndex}].facts[${factIndex}].tag`,
457
+ message: `Fact tag "${fact.tag}" is not a valid JavaScript identifier. Use only letters, numbers, underscores, and dollar signs, and do not start with a number.`,
458
+ });
459
+ }
460
+ });
461
+ }
462
+
463
+ // Validate event tags
464
+ if (logic.events) {
465
+ logic.events.forEach((event, eventIndex) => {
466
+ if (!event.tag) {
467
+ errors.push({
468
+ path: `logic[${logicIndex}].events[${eventIndex}].tag`,
469
+ message: 'Event tag is required',
470
+ });
471
+ } else if (!isValidIdentifier(event.tag)) {
472
+ errors.push({
473
+ path: `logic[${logicIndex}].events[${eventIndex}].tag`,
474
+ message: `Event tag "${event.tag}" is not a valid JavaScript identifier. Use only letters, numbers, underscores, and dollar signs, and do not start with a number.`,
475
+ });
476
+ }
477
+ });
478
+ }
479
+ });
480
+ }
481
+
482
+ // Validate orchestration nodes
483
+ if (schema.orchestration?.nodes) {
484
+ schema.orchestration.nodes.forEach((node, index) => {
485
+ if (!node.id) {
486
+ errors.push({
487
+ path: `orchestration.nodes[${index}].id`,
488
+ message: 'Node id is required',
489
+ });
490
+ }
491
+ if (!node.type) {
492
+ errors.push({
493
+ path: `orchestration.nodes[${index}].type`,
494
+ message: 'Node type is required',
495
+ });
496
+ }
497
+
498
+ // Validate terminal node specific props
499
+ if (node.type === 'terminal' && node.props) {
500
+ const props = node.props as Partial<TerminalNodeProps>;
501
+ if (props.inputMode && !['text', 'widget'].includes(props.inputMode)) {
502
+ errors.push({
503
+ path: `orchestration.nodes[${index}].props.inputMode`,
504
+ message: 'Terminal node inputMode must be "text" or "widget"',
505
+ });
506
+ }
507
+ if (props.history && !Array.isArray(props.history)) {
508
+ errors.push({
509
+ path: `orchestration.nodes[${index}].props.history`,
510
+ message: 'Terminal node history must be an array',
511
+ });
512
+ }
513
+ }
514
+ });
515
+ }
516
+
517
+ return {
518
+ valid: errors.length === 0,
519
+ errors,
520
+ };
521
+ }
522
+
523
+ /**
524
+ * Check if a string is a valid JavaScript identifier
525
+ */
526
+ function isValidIdentifier(str: string): boolean {
527
+ // JavaScript identifier must start with letter, $, or _
528
+ // and can contain letters, digits, $, or _
529
+ const identifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
530
+
531
+ // Also check that it's not a reserved keyword
532
+ const reservedKeywords = [
533
+ 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger',
534
+ 'default', 'delete', 'do', 'else', 'export', 'extends', 'finally',
535
+ 'for', 'function', 'if', 'import', 'in', 'instanceof', 'new',
536
+ 'return', 'super', 'switch', 'this', 'throw', 'try', 'typeof',
537
+ 'var', 'void', 'while', 'with', 'yield', 'let', 'static',
538
+ 'enum', 'await', 'implements', 'interface', 'package', 'private',
539
+ 'protected', 'public',
540
+ ];
541
+
542
+ return identifierRegex.test(str) && !reservedKeywords.includes(str);
543
+ }
544
+
545
+ /**
546
+ * Create a basic schema template
547
+ */
548
+ export function createSchemaTemplate(name: string): PraxisSchema {
549
+ return {
550
+ version: '1.0.0',
551
+ name,
552
+ description: `Schema for ${name}`,
553
+ models: [],
554
+ components: [],
555
+ logic: [],
556
+ };
557
+ }