@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,329 @@
1
+ /**
2
+ * Introspection and Visualization Utilities
3
+ *
4
+ * Provides APIs to introspect the registry, generate schemas,
5
+ * and export graph representations for external tools.
6
+ */
7
+
8
+ import type { PraxisRegistry, RuleDescriptor, ConstraintDescriptor } from "./rules.js";
9
+
10
+ /**
11
+ * Graph node representing a rule in the system
12
+ */
13
+ export interface RuleNode {
14
+ id: string;
15
+ type: "rule";
16
+ description: string;
17
+ meta?: Record<string, unknown>;
18
+ }
19
+
20
+ /**
21
+ * Graph node representing a constraint in the system
22
+ */
23
+ export interface ConstraintNode {
24
+ id: string;
25
+ type: "constraint";
26
+ description: string;
27
+ meta?: Record<string, unknown>;
28
+ }
29
+
30
+ /**
31
+ * Graph edge representing a dependency or relationship
32
+ */
33
+ export interface GraphEdge {
34
+ from: string;
35
+ to: string;
36
+ type: "triggers" | "constrains" | "depends-on";
37
+ }
38
+
39
+ /**
40
+ * Complete graph representation of the registry
41
+ */
42
+ export interface RegistryGraph {
43
+ nodes: (RuleNode | ConstraintNode)[];
44
+ edges: GraphEdge[];
45
+ meta: {
46
+ nodeCount: number;
47
+ ruleCount: number;
48
+ constraintCount: number;
49
+ };
50
+ }
51
+
52
+ /**
53
+ * JSON Schema-like representation of a rule
54
+ */
55
+ export interface RuleSchema {
56
+ id: string;
57
+ description: string;
58
+ type: "rule";
59
+ meta?: Record<string, unknown>;
60
+ }
61
+
62
+ /**
63
+ * JSON Schema-like representation of a constraint
64
+ */
65
+ export interface ConstraintSchema {
66
+ id: string;
67
+ description: string;
68
+ type: "constraint";
69
+ meta?: Record<string, unknown>;
70
+ }
71
+
72
+ /**
73
+ * Complete registry schema
74
+ */
75
+ export interface RegistrySchema {
76
+ protocolVersion: string;
77
+ rules: RuleSchema[];
78
+ constraints: ConstraintSchema[];
79
+ meta: {
80
+ ruleCount: number;
81
+ constraintCount: number;
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Statistics about the registry
87
+ */
88
+ export interface RegistryStats {
89
+ ruleCount: number;
90
+ constraintCount: number;
91
+ moduleCount: number;
92
+ rulesById: string[];
93
+ constraintsById: string[];
94
+ }
95
+
96
+ /**
97
+ * Introspection utilities for a Praxis registry
98
+ */
99
+ export class RegistryIntrospector<TContext = unknown> {
100
+ constructor(private registry: PraxisRegistry<TContext>) {}
101
+
102
+ /**
103
+ * Get basic statistics about the registry
104
+ */
105
+ getStats(): RegistryStats {
106
+ return {
107
+ ruleCount: this.registry.getRuleIds().length,
108
+ constraintCount: this.registry.getConstraintIds().length,
109
+ moduleCount: 0, // Modules are flattened in registry
110
+ rulesById: this.registry.getRuleIds(),
111
+ constraintsById: this.registry.getConstraintIds(),
112
+ };
113
+ }
114
+
115
+ /**
116
+ * Generate a JSON schema representation of the registry
117
+ */
118
+ generateSchema(protocolVersion: string): RegistrySchema {
119
+ const rules: RuleSchema[] = this.registry.getAllRules().map((rule) => ({
120
+ id: rule.id,
121
+ description: rule.description,
122
+ type: "rule" as const,
123
+ meta: rule.meta,
124
+ }));
125
+
126
+ const constraints: ConstraintSchema[] = this.registry.getAllConstraints().map((constraint) => ({
127
+ id: constraint.id,
128
+ description: constraint.description,
129
+ type: "constraint" as const,
130
+ meta: constraint.meta,
131
+ }));
132
+
133
+ return {
134
+ protocolVersion,
135
+ rules,
136
+ constraints,
137
+ meta: {
138
+ ruleCount: rules.length,
139
+ constraintCount: constraints.length,
140
+ },
141
+ };
142
+ }
143
+
144
+ /**
145
+ * Generate a graph representation of the registry
146
+ *
147
+ * This creates nodes for rules and constraints.
148
+ * Edges can be inferred from metadata if rules/constraints
149
+ * document their dependencies.
150
+ */
151
+ generateGraph(): RegistryGraph {
152
+ const nodes: (RuleNode | ConstraintNode)[] = [];
153
+ const edges: GraphEdge[] = [];
154
+
155
+ // Add rule nodes
156
+ for (const rule of this.registry.getAllRules()) {
157
+ nodes.push({
158
+ id: rule.id,
159
+ type: "rule",
160
+ description: rule.description,
161
+ meta: rule.meta,
162
+ });
163
+
164
+ // Check for dependency metadata
165
+ if (rule.meta?.dependsOn) {
166
+ const deps = Array.isArray(rule.meta.dependsOn)
167
+ ? rule.meta.dependsOn
168
+ : [rule.meta.dependsOn];
169
+ for (const dep of deps) {
170
+ edges.push({
171
+ from: String(dep),
172
+ to: rule.id,
173
+ type: "depends-on",
174
+ });
175
+ }
176
+ }
177
+ }
178
+
179
+ // Add constraint nodes
180
+ for (const constraint of this.registry.getAllConstraints()) {
181
+ nodes.push({
182
+ id: constraint.id,
183
+ type: "constraint",
184
+ description: constraint.description,
185
+ meta: constraint.meta,
186
+ });
187
+
188
+ // Check for constraint targets
189
+ if (constraint.meta?.constrains) {
190
+ const targets = Array.isArray(constraint.meta.constrains)
191
+ ? constraint.meta.constrains
192
+ : [constraint.meta.constrains];
193
+ for (const target of targets) {
194
+ edges.push({
195
+ from: constraint.id,
196
+ to: String(target),
197
+ type: "constrains",
198
+ });
199
+ }
200
+ }
201
+ }
202
+
203
+ return {
204
+ nodes,
205
+ edges,
206
+ meta: {
207
+ nodeCount: nodes.length,
208
+ ruleCount: nodes.filter((n) => n.type === "rule").length,
209
+ constraintCount: nodes.filter((n) => n.type === "constraint").length,
210
+ },
211
+ };
212
+ }
213
+
214
+ /**
215
+ * Export graph in DOT format (Graphviz)
216
+ *
217
+ * This can be rendered with Graphviz tools or online services.
218
+ */
219
+ exportDOT(): string {
220
+ const graph = this.generateGraph();
221
+ const lines: string[] = [];
222
+
223
+ lines.push("digraph PraxisRegistry {");
224
+ lines.push(" rankdir=TB;");
225
+ lines.push(" node [shape=box, style=rounded];");
226
+ lines.push("");
227
+
228
+ // Add nodes
229
+ for (const node of graph.nodes) {
230
+ const shape = node.type === "rule" ? "box" : "diamond";
231
+ const color = node.type === "rule" ? "lightblue" : "lightcoral";
232
+ const label = `${node.id}\\n${node.description}`;
233
+ lines.push(` "${node.id}" [label="${label}", shape=${shape}, style=filled, fillcolor=${color}];`);
234
+ }
235
+
236
+ lines.push("");
237
+
238
+ // Add edges
239
+ for (const edge of graph.edges) {
240
+ const style = edge.type === "constrains" ? "dashed" : "solid";
241
+ lines.push(` "${edge.from}" -> "${edge.to}" [label="${edge.type}", style=${style}];`);
242
+ }
243
+
244
+ lines.push("}");
245
+
246
+ return lines.join("\n");
247
+ }
248
+
249
+ /**
250
+ * Export graph in Mermaid format
251
+ *
252
+ * Mermaid is a markdown-friendly diagramming language.
253
+ */
254
+ exportMermaid(): string {
255
+ const graph = this.generateGraph();
256
+ const lines: string[] = [];
257
+
258
+ lines.push("graph TB");
259
+
260
+ // Add nodes
261
+ for (const node of graph.nodes) {
262
+ const shape = node.type === "rule" ? "[" : "{" ;
263
+ const endShape = node.type === "rule" ? "]" : "}";
264
+ const label = `${node.id}<br/>${node.description}`;
265
+ lines.push(` ${node.id}${shape}"${label}"${endShape}`);
266
+ }
267
+
268
+ lines.push("");
269
+
270
+ // Add edges
271
+ for (const edge of graph.edges) {
272
+ const arrow = edge.type === "constrains" ? "-.->|constrains|" : "-->|" + edge.type + "|";
273
+ lines.push(` ${edge.from} ${arrow} ${edge.to}`);
274
+ }
275
+
276
+ return lines.join("\n");
277
+ }
278
+
279
+ /**
280
+ * Get detailed information about a specific rule
281
+ */
282
+ getRuleInfo(ruleId: string): RuleDescriptor<TContext> | undefined {
283
+ return this.registry.getRule(ruleId);
284
+ }
285
+
286
+ /**
287
+ * Get detailed information about a specific constraint
288
+ */
289
+ getConstraintInfo(constraintId: string): ConstraintDescriptor<TContext> | undefined {
290
+ return this.registry.getConstraint(constraintId);
291
+ }
292
+
293
+ /**
294
+ * Search for rules by description text
295
+ */
296
+ searchRules(query: string): RuleDescriptor<TContext>[] {
297
+ const lowerQuery = query.toLowerCase();
298
+ return this.registry
299
+ .getAllRules()
300
+ .filter(
301
+ (rule) =>
302
+ rule.id.toLowerCase().includes(lowerQuery) ||
303
+ rule.description.toLowerCase().includes(lowerQuery)
304
+ );
305
+ }
306
+
307
+ /**
308
+ * Search for constraints by description text
309
+ */
310
+ searchConstraints(query: string): ConstraintDescriptor<TContext>[] {
311
+ const lowerQuery = query.toLowerCase();
312
+ return this.registry
313
+ .getAllConstraints()
314
+ .filter(
315
+ (constraint) =>
316
+ constraint.id.toLowerCase().includes(lowerQuery) ||
317
+ constraint.description.toLowerCase().includes(lowerQuery)
318
+ );
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Create a registry introspector
324
+ */
325
+ export function createIntrospector<TContext = unknown>(
326
+ registry: PraxisRegistry<TContext>
327
+ ): RegistryIntrospector<TContext> {
328
+ return new RegistryIntrospector(registry);
329
+ }