@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.
- package/FRAMEWORK.md +420 -0
- package/LICENSE +21 -0
- package/README.md +1310 -0
- package/dist/adapters/cli.d.ts +43 -0
- package/dist/adapters/cli.d.ts.map +1 -0
- package/dist/adapters/cli.js +126 -0
- package/dist/adapters/cli.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +26 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +233 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/cloud.d.ts +27 -0
- package/dist/cli/commands/cloud.d.ts.map +1 -0
- package/dist/cli/commands/cloud.js +232 -0
- package/dist/cli/commands/cloud.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +25 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +168 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +179 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cloud/auth.d.ts +51 -0
- package/dist/cloud/auth.d.ts.map +1 -0
- package/dist/cloud/auth.js +194 -0
- package/dist/cloud/auth.js.map +1 -0
- package/dist/cloud/billing.d.ts +184 -0
- package/dist/cloud/billing.d.ts.map +1 -0
- package/dist/cloud/billing.js +179 -0
- package/dist/cloud/billing.js.map +1 -0
- package/dist/cloud/client.d.ts +39 -0
- package/dist/cloud/client.d.ts.map +1 -0
- package/dist/cloud/client.js +176 -0
- package/dist/cloud/client.js.map +1 -0
- package/dist/cloud/index.d.ts +44 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +44 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/marketplace.d.ts +166 -0
- package/dist/cloud/marketplace.d.ts.map +1 -0
- package/dist/cloud/marketplace.js +159 -0
- package/dist/cloud/marketplace.js.map +1 -0
- package/dist/cloud/provisioning.d.ts +110 -0
- package/dist/cloud/provisioning.d.ts.map +1 -0
- package/dist/cloud/provisioning.js +148 -0
- package/dist/cloud/provisioning.js.map +1 -0
- package/dist/cloud/relay/endpoints.d.ts +62 -0
- package/dist/cloud/relay/endpoints.d.ts.map +1 -0
- package/dist/cloud/relay/endpoints.js +217 -0
- package/dist/cloud/relay/endpoints.js.map +1 -0
- package/dist/cloud/relay/health/index.d.ts +5 -0
- package/dist/cloud/relay/health/index.d.ts.map +1 -0
- package/dist/cloud/relay/health/index.js +9 -0
- package/dist/cloud/relay/health/index.js.map +1 -0
- package/dist/cloud/relay/stats/index.d.ts +5 -0
- package/dist/cloud/relay/stats/index.d.ts.map +1 -0
- package/dist/cloud/relay/stats/index.js +9 -0
- package/dist/cloud/relay/stats/index.js.map +1 -0
- package/dist/cloud/relay/sync/index.d.ts +5 -0
- package/dist/cloud/relay/sync/index.d.ts.map +1 -0
- package/dist/cloud/relay/sync/index.js +9 -0
- package/dist/cloud/relay/sync/index.js.map +1 -0
- package/dist/cloud/relay/usage/index.d.ts +5 -0
- package/dist/cloud/relay/usage/index.d.ts.map +1 -0
- package/dist/cloud/relay/usage/index.js +9 -0
- package/dist/cloud/relay/usage/index.js.map +1 -0
- package/dist/cloud/sponsors.d.ts +81 -0
- package/dist/cloud/sponsors.d.ts.map +1 -0
- package/dist/cloud/sponsors.js +130 -0
- package/dist/cloud/sponsors.js.map +1 -0
- package/dist/cloud/types.d.ts +169 -0
- package/dist/cloud/types.d.ts.map +1 -0
- package/dist/cloud/types.js +7 -0
- package/dist/cloud/types.js.map +1 -0
- package/dist/components/index.d.ts +43 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +17 -0
- package/dist/components/index.js.map +1 -0
- package/dist/core/actors.d.ts +95 -0
- package/dist/core/actors.d.ts.map +1 -0
- package/dist/core/actors.js +158 -0
- package/dist/core/actors.js.map +1 -0
- package/dist/core/component/generator.d.ts +122 -0
- package/dist/core/component/generator.d.ts.map +1 -0
- package/dist/core/component/generator.js +307 -0
- package/dist/core/component/generator.js.map +1 -0
- package/dist/core/engine.d.ts +92 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +199 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/introspection.d.ts +141 -0
- package/dist/core/introspection.d.ts.map +1 -0
- package/dist/core/introspection.js +208 -0
- package/dist/core/introspection.js.map +1 -0
- package/dist/core/logic/generator.d.ts +76 -0
- package/dist/core/logic/generator.d.ts.map +1 -0
- package/dist/core/logic/generator.js +339 -0
- package/dist/core/logic/generator.js.map +1 -0
- package/dist/core/pluresdb/generator.d.ts +58 -0
- package/dist/core/pluresdb/generator.d.ts.map +1 -0
- package/dist/core/pluresdb/generator.js +162 -0
- package/dist/core/pluresdb/generator.js.map +1 -0
- package/dist/core/protocol.d.ts +121 -0
- package/dist/core/protocol.d.ts.map +1 -0
- package/dist/core/protocol.js +46 -0
- package/dist/core/protocol.js.map +1 -0
- package/dist/core/rules.d.ts +120 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +81 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/schema/loader.d.ts +47 -0
- package/dist/core/schema/loader.d.ts.map +1 -0
- package/dist/core/schema/loader.js +189 -0
- package/dist/core/schema/loader.js.map +1 -0
- package/dist/core/schema/normalize.d.ts +72 -0
- package/dist/core/schema/normalize.d.ts.map +1 -0
- package/dist/core/schema/normalize.js +190 -0
- package/dist/core/schema/normalize.js.map +1 -0
- package/dist/core/schema/types.d.ts +370 -0
- package/dist/core/schema/types.d.ts.map +1 -0
- package/dist/core/schema/types.js +161 -0
- package/dist/core/schema/types.js.map +1 -0
- package/dist/dsl/index.d.ts +152 -0
- package/dist/dsl/index.d.ts.map +1 -0
- package/dist/dsl/index.js +132 -0
- package/dist/dsl/index.js.map +1 -0
- package/dist/dsl.d.ts +124 -0
- package/dist/dsl.d.ts.map +1 -0
- package/dist/dsl.js +130 -0
- package/dist/dsl.js.map +1 -0
- package/dist/examples/advanced-todo/index.d.ts +55 -0
- package/dist/examples/advanced-todo/index.d.ts.map +1 -0
- package/dist/examples/advanced-todo/index.js +222 -0
- package/dist/examples/advanced-todo/index.js.map +1 -0
- package/dist/examples/auth-basic/index.d.ts +17 -0
- package/dist/examples/auth-basic/index.d.ts.map +1 -0
- package/dist/examples/auth-basic/index.js +122 -0
- package/dist/examples/auth-basic/index.js.map +1 -0
- package/dist/examples/cart/index.d.ts +19 -0
- package/dist/examples/cart/index.d.ts.map +1 -0
- package/dist/examples/cart/index.js +202 -0
- package/dist/examples/cart/index.js.map +1 -0
- package/dist/examples/hero-ecommerce/index.d.ts +39 -0
- package/dist/examples/hero-ecommerce/index.d.ts.map +1 -0
- package/dist/examples/hero-ecommerce/index.js +506 -0
- package/dist/examples/hero-ecommerce/index.js.map +1 -0
- package/dist/examples/svelte-counter/index.d.ts +31 -0
- package/dist/examples/svelte-counter/index.d.ts.map +1 -0
- package/dist/examples/svelte-counter/index.js +123 -0
- package/dist/examples/svelte-counter/index.js.map +1 -0
- package/dist/flows.d.ts +125 -0
- package/dist/flows.d.ts.map +1 -0
- package/dist/flows.js +160 -0
- package/dist/flows.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/pluresdb.d.ts +56 -0
- package/dist/integrations/pluresdb.d.ts.map +1 -0
- package/dist/integrations/pluresdb.js +46 -0
- package/dist/integrations/pluresdb.js.map +1 -0
- package/dist/integrations/svelte.d.ts +306 -0
- package/dist/integrations/svelte.d.ts.map +1 -0
- package/dist/integrations/svelte.js +447 -0
- package/dist/integrations/svelte.js.map +1 -0
- package/dist/registry.d.ts +94 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +181 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime/terminal-adapter.d.ts +105 -0
- package/dist/runtime/terminal-adapter.d.ts.map +1 -0
- package/dist/runtime/terminal-adapter.js +113 -0
- package/dist/runtime/terminal-adapter.js.map +1 -0
- package/dist/step.d.ts +34 -0
- package/dist/step.d.ts.map +1 -0
- package/dist/step.js +111 -0
- package/dist/step.js.map +1 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/docs/MONETIZATION.md +394 -0
- package/docs/TERMINAL_NODE.md +588 -0
- package/docs/guides/canvas.md +389 -0
- package/docs/guides/getting-started.md +347 -0
- package/docs/guides/history-state-pattern.md +618 -0
- package/docs/guides/orchestration.md +617 -0
- package/docs/guides/parallel-state-pattern.md +767 -0
- package/docs/guides/svelte-integration.md +691 -0
- package/package.json +96 -0
- package/src/__tests__/actors.test.ts +270 -0
- package/src/__tests__/billing.test.ts +175 -0
- package/src/__tests__/cloud.test.ts +247 -0
- package/src/__tests__/dsl.test.ts +154 -0
- package/src/__tests__/edge-cases.test.ts +475 -0
- package/src/__tests__/engine.test.ts +137 -0
- package/src/__tests__/generators.test.ts +270 -0
- package/src/__tests__/introspection.test.ts +321 -0
- package/src/__tests__/protocol.test.ts +40 -0
- package/src/__tests__/provisioning.test.ts +162 -0
- package/src/__tests__/schema.test.ts +241 -0
- package/src/__tests__/svelte-integration.test.ts +431 -0
- package/src/__tests__/terminal-node.test.ts +352 -0
- package/src/adapters/cli.ts +175 -0
- package/src/cli/commands/auth.ts +271 -0
- package/src/cli/commands/cloud.ts +281 -0
- package/src/cli/commands/generate.ts +225 -0
- package/src/cli/index.ts +190 -0
- package/src/cloud/README.md +383 -0
- package/src/cloud/auth.ts +245 -0
- package/src/cloud/billing.ts +336 -0
- package/src/cloud/client.ts +221 -0
- package/src/cloud/index.ts +121 -0
- package/src/cloud/marketplace.ts +303 -0
- package/src/cloud/provisioning.ts +254 -0
- package/src/cloud/relay/endpoints.ts +307 -0
- package/src/cloud/relay/health/function.json +17 -0
- package/src/cloud/relay/health/index.ts +10 -0
- package/src/cloud/relay/host.json +15 -0
- package/src/cloud/relay/local.settings.json +8 -0
- package/src/cloud/relay/stats/function.json +17 -0
- package/src/cloud/relay/stats/index.ts +10 -0
- package/src/cloud/relay/sync/function.json +17 -0
- package/src/cloud/relay/sync/index.ts +10 -0
- package/src/cloud/relay/usage/function.json +17 -0
- package/src/cloud/relay/usage/index.ts +10 -0
- package/src/cloud/sponsors.ts +213 -0
- package/src/cloud/types.ts +198 -0
- package/src/components/README.md +125 -0
- package/src/components/TerminalNode.svelte +457 -0
- package/src/components/index.ts +46 -0
- package/src/core/actors.ts +205 -0
- package/src/core/component/generator.ts +432 -0
- package/src/core/engine.ts +243 -0
- package/src/core/introspection.ts +329 -0
- package/src/core/logic/generator.ts +420 -0
- package/src/core/pluresdb/generator.ts +229 -0
- package/src/core/protocol.ts +132 -0
- package/src/core/rules.ts +167 -0
- package/src/core/schema/loader.ts +247 -0
- package/src/core/schema/normalize.ts +322 -0
- package/src/core/schema/types.ts +557 -0
- package/src/dsl/index.ts +218 -0
- package/src/dsl.ts +214 -0
- package/src/examples/advanced-todo/App.svelte +506 -0
- package/src/examples/advanced-todo/README.md +371 -0
- package/src/examples/advanced-todo/index.ts +309 -0
- package/src/examples/auth-basic/index.ts +163 -0
- package/src/examples/cart/index.ts +259 -0
- package/src/examples/hero-ecommerce/index.ts +657 -0
- package/src/examples/svelte-counter/index.ts +168 -0
- package/src/flows.ts +268 -0
- package/src/index.ts +154 -0
- package/src/integrations/pluresdb.ts +93 -0
- package/src/integrations/svelte.ts +617 -0
- package/src/registry.ts +223 -0
- package/src/runtime/terminal-adapter.ts +175 -0
- package/src/step.ts +151 -0
- package/src/types.ts +70 -0
- package/templates/basic-app/README.md +147 -0
- 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
|
+
}
|