@plures/praxis 1.1.3 → 1.2.10

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 (74) hide show
  1. package/FRAMEWORK.md +106 -15
  2. package/README.md +194 -119
  3. package/dist/browser/adapter-CIMBGDC7.js +14 -0
  4. package/dist/browser/chunk-K377RW4V.js +230 -0
  5. package/dist/browser/chunk-MBVHLOU2.js +152 -0
  6. package/dist/browser/{chunk-R45WXWKH.js → chunk-VOMLVI6V.js} +1 -149
  7. package/dist/browser/engine-YJZV4SLD.js +8 -0
  8. package/dist/browser/index.d.ts +161 -5
  9. package/dist/browser/index.js +156 -141
  10. package/dist/browser/integrations/svelte.d.ts +2 -2
  11. package/dist/browser/integrations/svelte.js +2 -1
  12. package/dist/browser/{reactive-engine.svelte-C9OpcTHf.d.ts → reactive-engine.svelte-9aS0kTa8.d.ts} +136 -1
  13. package/dist/node/adapter-75ISSMWD.js +15 -0
  14. package/dist/node/chunk-5RH7UAQC.js +486 -0
  15. package/dist/node/chunk-MBVHLOU2.js +152 -0
  16. package/dist/node/chunk-PRPQO6R5.js +85 -0
  17. package/dist/node/chunk-R2PSBPKQ.js +150 -0
  18. package/dist/node/chunk-S54337I5.js +446 -0
  19. package/dist/node/{chunk-R45WXWKH.js → chunk-VOMLVI6V.js} +1 -149
  20. package/dist/node/chunk-WZ6B3LZ6.js +638 -0
  21. package/dist/node/cli/index.cjs +2936 -897
  22. package/dist/node/cli/index.js +27 -0
  23. package/dist/node/components/index.d.cts +3 -2
  24. package/dist/node/components/index.d.ts +3 -2
  25. package/dist/node/docs-JFNYTOJA.js +102 -0
  26. package/dist/node/engine-2DQBKBJC.js +9 -0
  27. package/dist/node/index.cjs +1114 -354
  28. package/dist/node/index.d.cts +388 -5
  29. package/dist/node/index.d.ts +388 -5
  30. package/dist/node/index.js +201 -640
  31. package/dist/node/integrations/svelte.cjs +76 -0
  32. package/dist/node/integrations/svelte.d.cts +2 -2
  33. package/dist/node/integrations/svelte.d.ts +2 -2
  34. package/dist/node/integrations/svelte.js +3 -1
  35. package/dist/node/{reactive-engine.svelte-1M4m_C_v.d.cts → reactive-engine.svelte-BFIZfawz.d.cts} +199 -1
  36. package/dist/node/{reactive-engine.svelte-ChNFn4Hj.d.ts → reactive-engine.svelte-CRNqHlbv.d.ts} +199 -1
  37. package/dist/node/reverse-W7THPV45.js +193 -0
  38. package/dist/node/{terminal-adapter-CWka-yL8.d.ts → terminal-adapter-B-UK_Vdz.d.ts} +28 -3
  39. package/dist/node/{terminal-adapter-CDzxoLKR.d.cts → terminal-adapter-BQSIF5bf.d.cts} +28 -3
  40. package/dist/node/validate-CNHUULQE.js +180 -0
  41. package/docs/core/pluresdb-integration.md +15 -15
  42. package/docs/decision-ledger/BEHAVIOR_LEDGER.md +225 -0
  43. package/docs/decision-ledger/DecisionLedger.tla +180 -0
  44. package/docs/decision-ledger/IMPLEMENTATION_SUMMARY.md +217 -0
  45. package/docs/decision-ledger/LATEST.md +166 -0
  46. package/docs/guides/cicd-pipeline.md +142 -0
  47. package/package.json +2 -2
  48. package/src/__tests__/cli-validate.test.ts +197 -0
  49. package/src/__tests__/decision-ledger.test.ts +485 -0
  50. package/src/__tests__/reverse-generator.test.ts +189 -0
  51. package/src/__tests__/scanner.test.ts +215 -0
  52. package/src/cli/commands/docs.ts +147 -0
  53. package/src/cli/commands/reverse.ts +289 -0
  54. package/src/cli/commands/validate.ts +264 -0
  55. package/src/cli/index.ts +68 -0
  56. package/src/core/pluresdb/adapter.ts +46 -3
  57. package/src/core/reactive-engine.svelte.ts +6 -1
  58. package/src/core/reactive-engine.ts +1 -1
  59. package/src/core/rules.ts +133 -0
  60. package/src/decision-ledger/README.md +400 -0
  61. package/src/decision-ledger/REVERSE_ENGINEERING.md +484 -0
  62. package/src/decision-ledger/facts-events.ts +121 -0
  63. package/src/decision-ledger/index.ts +70 -0
  64. package/src/decision-ledger/ledger.ts +246 -0
  65. package/src/decision-ledger/logic-ledger.ts +158 -0
  66. package/src/decision-ledger/reverse-generator.ts +426 -0
  67. package/src/decision-ledger/scanner.ts +506 -0
  68. package/src/decision-ledger/types.ts +247 -0
  69. package/src/decision-ledger/validation.ts +336 -0
  70. package/src/dsl/index.ts +13 -2
  71. package/src/index.browser.ts +6 -0
  72. package/src/index.ts +40 -0
  73. package/src/integrations/pluresdb.ts +14 -2
  74. package/src/integrations/unified.ts +350 -0
package/src/index.ts CHANGED
@@ -121,6 +121,40 @@ export type {
121
121
  DefineModuleOptions,
122
122
  } from './dsl/index.js';
123
123
 
124
+ // Decision Ledger (Contract-based validation)
125
+ export {
126
+ defineContract,
127
+ getContract,
128
+ isContract,
129
+ validateContracts,
130
+ formatValidationReport,
131
+ formatValidationReportJSON,
132
+ formatValidationReportSARIF,
133
+ ContractMissing,
134
+ ContractValidated,
135
+ AcknowledgeContractGap,
136
+ ValidateContracts,
137
+ ContractGapAcknowledged,
138
+ ContractAdded,
139
+ ContractUpdated,
140
+ BehaviorLedger,
141
+ createBehaviorLedger,
142
+ } from './decision-ledger/index.js';
143
+ export type {
144
+ Assumption,
145
+ Reference,
146
+ Example,
147
+ Contract,
148
+ DefineContractOptions,
149
+ Severity,
150
+ MissingArtifact,
151
+ ContractGap,
152
+ ValidationReport,
153
+ ValidateOptions,
154
+ LedgerEntry,
155
+ LedgerEntryStatus,
156
+ } from './decision-ledger/index.js';
157
+
124
158
  // Terminal Node Runtime
125
159
  export type {
126
160
  TerminalExecutionResult,
@@ -166,6 +200,7 @@ export type {
166
200
  UnsubscribeFn,
167
201
  PluresDBInstance,
168
202
  PluresDBAdapterConfig,
203
+ PraxisLocalFirstOptions,
169
204
  EventStreamEntry,
170
205
  PraxisDBStoreOptions,
171
206
  StoredSchema,
@@ -179,6 +214,7 @@ export {
179
214
  createInMemoryDB,
180
215
  PluresDBPraxisAdapter,
181
216
  createPluresDB,
217
+ createPraxisLocalFirst,
182
218
  PraxisDBStore,
183
219
  createPraxisDBStore,
184
220
  PRAXIS_PATHS,
@@ -268,3 +304,7 @@ export {
268
304
  attachTauriToEngine,
269
305
  generateTauriConfig,
270
306
  } from './integrations/tauri.js';
307
+
308
+ // Unified Integration Helpers
309
+ export type { UnifiedAppConfig, UnifiedApp } from './integrations/unified.js';
310
+ export { createUnifiedApp, attachAllIntegrations } from './integrations/unified.js';
@@ -17,8 +17,20 @@ import { PraxisDBStore, createPraxisDBStore } from '../core/pluresdb/store.js';
17
17
 
18
18
  // Re-export core pluresdb types and implementations
19
19
  // Note: Using explicit exports to avoid circular dependency issues
20
- export { InMemoryPraxisDB, createInMemoryDB, PluresDBPraxisAdapter, createPluresDB } from '../core/pluresdb/adapter.js';
21
- export type { PraxisDB, UnsubscribeFn, PluresDBInstance, PluresDBAdapterConfig } from '../core/pluresdb/adapter.js';
20
+ export {
21
+ InMemoryPraxisDB,
22
+ createInMemoryDB,
23
+ PluresDBPraxisAdapter,
24
+ createPluresDB,
25
+ createPraxisLocalFirst,
26
+ } from '../core/pluresdb/adapter.js';
27
+ export type {
28
+ PraxisDB,
29
+ UnsubscribeFn,
30
+ PluresDBInstance,
31
+ PluresDBAdapterConfig,
32
+ PraxisLocalFirstOptions,
33
+ } from '../core/pluresdb/adapter.js';
22
34
  export {
23
35
  PraxisDBStore,
24
36
  createPraxisDBStore,
@@ -0,0 +1,350 @@
1
+ /**
2
+ * Unified Integration Helpers
3
+ *
4
+ * Convenience functions for setting up Praxis with all ecosystem integrations
5
+ * (PluresDB, Unum, State-Docs, CodeCanvas) in a single call.
6
+ */
7
+
8
+ import type { LogicEngine } from '../core/engine.js';
9
+ import type { PraxisRegistry, PraxisModule } from '../core/rules.js';
10
+ import type { PraxisSchema } from '../core/schema/types.js';
11
+ import type { PraxisDB, UnsubscribeFn } from '../core/pluresdb/adapter.js';
12
+ import type { UnumIdentity } from './unum.js';
13
+ import {
14
+ createPluresDBAdapter,
15
+ generateId,
16
+ type PluresDBAdapter,
17
+ } from './pluresdb.js';
18
+ import {
19
+ createUnumAdapter,
20
+ attachUnumToEngine,
21
+ type UnumAdapter,
22
+ type UnumChannel,
23
+ } from './unum.js';
24
+ import {
25
+ createStateDocsGenerator,
26
+ type StateDocsGenerator,
27
+ type GeneratedDoc,
28
+ } from './state-docs.js';
29
+ import {
30
+ schemaToCanvas,
31
+ type CanvasDocument,
32
+ } from './code-canvas.js';
33
+
34
+ /**
35
+ * Configuration for unified Praxis application
36
+ */
37
+ export interface UnifiedAppConfig<TContext = unknown> {
38
+ /** Praxis registry with rules and constraints */
39
+ registry: PraxisRegistry<TContext>;
40
+
41
+ /** Initial context for the engine */
42
+ initialContext: TContext;
43
+
44
+ /** PluresDB instance (if not provided, creates in-memory DB) */
45
+ db?: PraxisDB;
46
+
47
+ /** Enable Unum for distributed communication */
48
+ enableUnum?: boolean;
49
+
50
+ /** Unum identity configuration (without id and createdAt which are auto-generated) */
51
+ unumIdentity?: Omit<UnumIdentity, 'id' | 'createdAt'>;
52
+
53
+ /** Enable State-Docs documentation generation */
54
+ enableDocs?: boolean;
55
+
56
+ /** State-Docs configuration */
57
+ docsConfig?: {
58
+ projectTitle: string;
59
+ target?: string;
60
+ };
61
+
62
+ /** Praxis schema for CodeCanvas integration */
63
+ schema?: PraxisSchema;
64
+ }
65
+
66
+ /**
67
+ * Unified application instance with all integrations
68
+ */
69
+ export interface UnifiedApp<TContext = unknown> {
70
+ /** Praxis logic engine */
71
+ engine: LogicEngine<TContext>;
72
+
73
+ /** PluresDB adapter for persistence */
74
+ pluresdb: PluresDBAdapter<TContext>;
75
+
76
+ /** Unum adapter for distributed communication (if enabled) */
77
+ unum?: UnumAdapter;
78
+
79
+ /** Default Unum channel (if Unum enabled) */
80
+ channel?: UnumChannel;
81
+
82
+ /** State-Docs generator (if enabled) */
83
+ docs?: StateDocsGenerator;
84
+
85
+ /** CodeCanvas document (if schema provided) */
86
+ canvas?: CanvasDocument;
87
+
88
+ /** Generate documentation from current state */
89
+ generateDocs?: () => GeneratedDoc[];
90
+
91
+ /** Cleanup function to dispose all integrations */
92
+ dispose: () => void;
93
+ }
94
+
95
+ /**
96
+ * Create a unified Praxis application with all integrations
97
+ *
98
+ * This is a convenience function that sets up:
99
+ * - Praxis logic engine
100
+ * - PluresDB for persistence (auto-attaches to engine)
101
+ * - Unum for distributed communication (optional)
102
+ * - State-Docs for documentation generation (optional)
103
+ * - CodeCanvas for visual schema editing (optional)
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * import { createUnifiedApp } from '@plures/praxis';
108
+ *
109
+ * const app = await createUnifiedApp({
110
+ * registry: myRegistry,
111
+ * initialContext: { count: 0 },
112
+ * enableUnum: true,
113
+ * unumIdentity: { name: 'node-1' },
114
+ * enableDocs: true,
115
+ * docsConfig: { projectTitle: 'My App' },
116
+ * schema: mySchema,
117
+ * });
118
+ *
119
+ * // Use the engine
120
+ * app.engine.step([myEvent]);
121
+ *
122
+ * // Broadcast to other nodes
123
+ * if (app.channel) {
124
+ * await app.unum?.broadcastEvent(app.channel.id, myEvent);
125
+ * }
126
+ *
127
+ * // Generate documentation
128
+ * const docs = app.generateDocs?.();
129
+ *
130
+ * // Cleanup
131
+ * app.dispose();
132
+ * ```
133
+ */
134
+ export async function createUnifiedApp<TContext = unknown>(
135
+ config: UnifiedAppConfig<TContext>
136
+ ): Promise<UnifiedApp<TContext>> {
137
+ const { createPraxisEngine } = await import('../core/engine.js');
138
+ const { createInMemoryDB } = await import('../core/pluresdb/adapter.js');
139
+
140
+ // Create database if not provided
141
+ const db = config.db || createInMemoryDB();
142
+
143
+ // Create PluresDB adapter
144
+ const pluresdb = createPluresDBAdapter({
145
+ db,
146
+ registry: config.registry,
147
+ initialContext: config.initialContext,
148
+ });
149
+
150
+ // Create Praxis engine
151
+ const engine = createPraxisEngine({
152
+ initialContext: config.initialContext,
153
+ registry: config.registry,
154
+ });
155
+
156
+ // Attach PluresDB to engine
157
+ pluresdb.attachEngine(engine);
158
+
159
+ const disposers: UnsubscribeFn[] = [];
160
+
161
+ // Setup Unum if enabled
162
+ let unum: UnumAdapter | undefined;
163
+ let channel: UnumChannel | undefined;
164
+ if (config.enableUnum) {
165
+ // Convert partial identity to full identity if provided
166
+ const fullIdentity: UnumIdentity | undefined = config.unumIdentity
167
+ ? {
168
+ ...config.unumIdentity,
169
+ id: generateId(),
170
+ createdAt: Date.now(),
171
+ }
172
+ : undefined;
173
+
174
+ unum = await createUnumAdapter({
175
+ db,
176
+ identity: fullIdentity,
177
+ realtime: true,
178
+ });
179
+
180
+ // Create default channel
181
+ channel = await unum.createChannel(
182
+ config.unumIdentity?.name || 'praxis-app',
183
+ []
184
+ );
185
+
186
+ // Attach Unum to engine
187
+ const unumDisposer = attachUnumToEngine(engine, unum, channel.id);
188
+ disposers.push(unumDisposer);
189
+ }
190
+
191
+ // Setup State-Docs if enabled
192
+ let docs: StateDocsGenerator | undefined;
193
+ let generateDocs: (() => GeneratedDoc[]) | undefined;
194
+ if (config.enableDocs && config.docsConfig) {
195
+ docs = createStateDocsGenerator({
196
+ projectTitle: config.docsConfig.projectTitle,
197
+ target: config.docsConfig.target || './docs',
198
+ });
199
+
200
+ generateDocs = () => {
201
+ // Get rules and constraints from registry
202
+ const module: PraxisModule<TContext> = {
203
+ rules: config.registry.getAllRules(),
204
+ constraints: config.registry.getAllConstraints(),
205
+ };
206
+ return docs!.generateFromModule(module);
207
+ };
208
+ }
209
+
210
+ // Setup CodeCanvas if schema provided
211
+ let canvas: CanvasDocument | undefined;
212
+ if (config.schema) {
213
+ // Convert PraxisSchema to PSFSchema format expected by schemaToCanvas
214
+ // Both types are structurally compatible, so we can safely cast
215
+ canvas = schemaToCanvas(config.schema as unknown as import('../../core/schema-engine/psf.js').PSFSchema, { layout: 'hierarchical' });
216
+ }
217
+
218
+ return {
219
+ engine,
220
+ pluresdb,
221
+ unum,
222
+ channel,
223
+ docs,
224
+ canvas,
225
+ generateDocs,
226
+ dispose: () => {
227
+ pluresdb.dispose();
228
+ if (unum) {
229
+ // Disconnect from Unum, log errors during cleanup
230
+ unum.disconnect().catch((err) => {
231
+ console.warn('Warning: Error during Unum disconnect:', err);
232
+ });
233
+ }
234
+ for (const disposer of disposers) {
235
+ disposer();
236
+ }
237
+ },
238
+ };
239
+ }
240
+
241
+ /**
242
+ * Attach all available integrations to an existing Praxis engine
243
+ *
244
+ * This is useful when you already have an engine and want to add integrations.
245
+ *
246
+ * @example
247
+ * ```typescript
248
+ * import { createPraxisEngine, attachAllIntegrations } from '@plures/praxis';
249
+ *
250
+ * const engine = createPraxisEngine({ initialContext: {}, registry });
251
+ *
252
+ * const integrations = await attachAllIntegrations(engine, registry, {
253
+ * enableUnum: true,
254
+ * enableDocs: true,
255
+ * });
256
+ *
257
+ * // Later cleanup
258
+ * integrations.dispose();
259
+ * ```
260
+ */
261
+ export async function attachAllIntegrations<TContext = unknown>(
262
+ engine: LogicEngine<TContext>,
263
+ registry: PraxisRegistry<TContext>,
264
+ options: {
265
+ db?: PraxisDB;
266
+ enableUnum?: boolean;
267
+ unumIdentity?: Omit<UnumIdentity, 'id' | 'createdAt'>;
268
+ enableDocs?: boolean;
269
+ docsConfig?: { projectTitle: string; target?: string };
270
+ } = {}
271
+ ): Promise<{
272
+ pluresdb: PluresDBAdapter<TContext>;
273
+ unum?: UnumAdapter;
274
+ channel?: UnumChannel;
275
+ docs?: StateDocsGenerator;
276
+ dispose: () => void;
277
+ }> {
278
+ const { createInMemoryDB } = await import('../core/pluresdb/adapter.js');
279
+
280
+ // Create database if not provided
281
+ const db = options.db || createInMemoryDB();
282
+
283
+ // Create PluresDB adapter
284
+ const pluresdb = createPluresDBAdapter({
285
+ db,
286
+ registry,
287
+ initialContext: engine.getContext(),
288
+ });
289
+
290
+ // Attach PluresDB to engine
291
+ pluresdb.attachEngine(engine);
292
+
293
+ const disposers: UnsubscribeFn[] = [];
294
+
295
+ // Setup Unum if enabled
296
+ let unum: UnumAdapter | undefined;
297
+ let channel: UnumChannel | undefined;
298
+ if (options.enableUnum) {
299
+ // Convert partial identity to full identity if provided
300
+ const fullIdentity: UnumIdentity | undefined = options.unumIdentity
301
+ ? {
302
+ ...options.unumIdentity,
303
+ id: generateId(),
304
+ createdAt: Date.now(),
305
+ }
306
+ : undefined;
307
+
308
+ unum = await createUnumAdapter({
309
+ db,
310
+ identity: fullIdentity,
311
+ realtime: true,
312
+ });
313
+
314
+ channel = await unum.createChannel(
315
+ options.unumIdentity?.name || 'praxis-app',
316
+ []
317
+ );
318
+
319
+ const unumDisposer = attachUnumToEngine(engine, unum, channel.id);
320
+ disposers.push(unumDisposer);
321
+ }
322
+
323
+ // Setup State-Docs if enabled
324
+ let docs: StateDocsGenerator | undefined;
325
+ if (options.enableDocs && options.docsConfig) {
326
+ docs = createStateDocsGenerator({
327
+ projectTitle: options.docsConfig.projectTitle,
328
+ target: options.docsConfig.target || './docs',
329
+ });
330
+ }
331
+
332
+ return {
333
+ pluresdb,
334
+ unum,
335
+ channel,
336
+ docs,
337
+ dispose: () => {
338
+ pluresdb.dispose();
339
+ if (unum) {
340
+ // Disconnect from Unum, log errors during cleanup
341
+ unum.disconnect().catch((err) => {
342
+ console.warn('Warning: Error during Unum disconnect:', err);
343
+ });
344
+ }
345
+ for (const disposer of disposers) {
346
+ disposer();
347
+ }
348
+ },
349
+ };
350
+ }