@plures/praxis 2.0.0 → 2.0.3

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 (31) hide show
  1. package/README.md +164 -1067
  2. package/dist/browser/{chunk-6MVRT7CK.js → chunk-IUEKGHQN.js} +13 -3
  3. package/dist/browser/index.js +1 -1
  4. package/dist/browser/unified/index.js +1 -1
  5. package/dist/node/{chunk-6MVRT7CK.js → chunk-IUEKGHQN.js} +13 -3
  6. package/dist/node/index.cjs +13 -3
  7. package/dist/node/index.js +1 -1
  8. package/dist/node/unified/index.cjs +13 -3
  9. package/dist/node/unified/index.js +1 -1
  10. package/docs/README.md +58 -102
  11. package/docs/archive/1.x/CONVERSATIONS_IMPLEMENTATION.md +207 -0
  12. package/docs/archive/1.x/DECISION_LEDGER_IMPLEMENTATION.md +109 -0
  13. package/docs/archive/1.x/DECISION_LEDGER_SUMMARY.md +424 -0
  14. package/docs/archive/1.x/ELEVATION_SUMMARY.md +249 -0
  15. package/docs/archive/1.x/FEATURE_SUMMARY.md +238 -0
  16. package/docs/archive/1.x/GOLDEN_PATH_IMPLEMENTATION.md +280 -0
  17. package/docs/archive/1.x/IMPLEMENTATION.md +166 -0
  18. package/docs/archive/1.x/IMPLEMENTATION_COMPLETE.md +389 -0
  19. package/docs/archive/1.x/IMPLEMENTATION_SUMMARY.md +59 -0
  20. package/docs/archive/1.x/INTEGRATION_ENHANCEMENT_SUMMARY.md +238 -0
  21. package/docs/archive/1.x/KNO_ENG_REFACTORING_SUMMARY.md +198 -0
  22. package/docs/archive/1.x/MONOREPO_SUMMARY.md +158 -0
  23. package/docs/archive/1.x/README.md +28 -0
  24. package/docs/archive/1.x/SVELTE_INTEGRATION_SUMMARY.md +415 -0
  25. package/docs/archive/1.x/TASK_1_COMPLETE.md +235 -0
  26. package/docs/archive/1.x/TASK_1_SUMMARY.md +281 -0
  27. package/docs/archive/1.x/VERSION_0.2.0_RELEASE_NOTES.md +288 -0
  28. package/docs/archive/1.x/ValidationChecklist.md +7 -0
  29. package/package.json +11 -5
  30. package/src/unified/__tests__/unified-qa.test.ts +761 -0
  31. package/src/unified/core.ts +19 -2
package/README.md CHANGED
@@ -1,45 +1,83 @@
1
1
  # Praxis
2
2
 
3
- <!-- plures-readme-banner -->
4
3
  [![CI](https://github.com/plures/praxis/actions/workflows/ci.yml/badge.svg)](https://github.com/plures/praxis/actions/workflows/ci.yml)
5
4
  [![npm](https://img.shields.io/npm/v/%40plures%2Fpraxis.svg)](https://www.npmjs.com/package/@plures/praxis)
5
+ [![JSR](https://jsr.io/badges/@plures/praxis)](https://jsr.io/@plures/praxis)
6
6
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
7
 
8
+ **The full-stack declarative application framework — typed logic, reactive state, local-first data, and visual tooling for Svelte, Node, and the browser.**
8
9
 
9
- **Typed, visual-first application logic for Svelte, Node, and the browser.**
10
+ Praxis 2.0 gives you a single `createApp()` call that wires reactive state, constraint validation, rule evaluation, and an immutable timeline — zero boilerplate. When you need deeper control, drop down to the classic engine with registries, typed events/facts, and undo/redo history.
10
11
 
11
- [![npm version](https://img.shields.io/npm/v/@plures/praxis.svg)](https://www.npmjs.com/package/@plures/praxis)
12
- [![JSR](https://jsr.io/badges/@plures/praxis)](https://jsr.io/@plures/praxis)
13
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
14
- [![Node.js Version](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org/)
15
- [![Deno Compatible](https://img.shields.io/badge/deno-compatible-brightgreen)](https://deno.land/)
12
+ ## Install
16
13
 
17
- Praxis is a unified solution for declarative application development. The framework combines typed logic modeling (facts, events, rules, constraints), component generation (Svelte 5), and local-first data persistence (PluresDB). It includes visual tools (CodeCanvas, State-Docs), distributed system support (Unum), optional cloud relay, and a CLI for scaffolding and generation.
14
+ Node 18+ recommended.
18
15
 
19
- The library delivers unified ESM/CJS builds with curated subpath exports (`./`, `./svelte`, `./schema`, `./component`, `./cloud`, `./components`), Svelte 5 runes support, and publish-ready packages for npm and JSR.
16
+ ```bash
17
+ npm install @plures/praxis # or: pnpm add @plures/praxis
18
+ ```
20
19
 
20
+ ## Quick Start — Unified App (v2.0)
21
21
 
22
- ## Install
23
- Node 18+ recommended.
22
+ The fastest way to build with Praxis. Define paths (state), rules, and constraints — Praxis handles the rest.
24
23
 
25
- ```bash
26
- # npm
27
- npm install @plures/praxis
24
+ ```ts
25
+ import {
26
+ createApp,
27
+ definePath,
28
+ defineRule,
29
+ defineConstraint,
30
+ RuleResult,
31
+ fact,
32
+ } from '@plures/praxis/unified';
33
+
34
+ // 1. Declare your state shape
35
+ const Count = definePath<number>('count', 0);
36
+ const Max = definePath<number>('max', 10);
37
+
38
+ // 2. Add constraints
39
+ const notNegative = defineConstraint({
40
+ id: 'count.not-negative',
41
+ description: 'Count must never go below zero',
42
+ watch: ['count'],
43
+ validate: (values) => values['count'] >= 0 || 'Count cannot be negative',
44
+ });
28
45
 
29
- # pnpm
30
- pnpm add @plures/praxis
31
- ```
46
+ // 3. Add rules
47
+ const capAtMax = defineRule({
48
+ id: 'count.cap',
49
+ watch: ['count', 'max'],
50
+ evaluate: (values) => {
51
+ if (values['count'] > values['max']) {
52
+ return RuleResult.emit([fact('count.capped', { at: values['max'] })]);
53
+ }
54
+ return RuleResult.noop();
55
+ },
56
+ });
32
57
 
33
- JSR (Deno):
34
- ```bash
35
- deno add @plures/praxis
36
- # or via import map pointing to npm:
37
- # {
38
- # "imports": { "@plures/praxis": "npm:@plures/praxis@^1.1.2" }
39
- # }
58
+ // 4. Create the app
59
+ const app = createApp({
60
+ name: 'counter',
61
+ schema: [Count, Max],
62
+ rules: [capAtMax],
63
+ constraints: [notNegative],
64
+ });
65
+
66
+ // 5. Query & mutate
67
+ const count = app.query<number>('count');
68
+ console.log(count.current); // 0
69
+
70
+ app.mutate('count', 5);
71
+ console.log(count.current); // 5
72
+
73
+ const result = app.mutate('count', -1);
74
+ console.log(result.accepted); // false — constraint rejected
40
75
  ```
41
76
 
42
- ## Quick start (logic engine)
77
+ ## Classic Engine (full control)
78
+
79
+ For complex scenarios that need typed events, facts, actors, and undo/redo:
80
+
43
81
  ```ts
44
82
  import {
45
83
  createPraxisEngine,
@@ -68,1129 +106,188 @@ registry.registerRule(loginRule);
68
106
 
69
107
  const engine = createPraxisEngine({ initialContext: { currentUser: null }, registry });
70
108
  engine.step([Login.create({ username: 'alex' })]);
109
+ console.log(engine.getContext()); // { currentUser: 'alex' }
71
110
  ```
72
111
 
73
- ## Unified workflow example
74
-
75
- See all Praxis integrations working together - from schema definition to persistence, documentation, and distributed communication:
76
-
77
- ```ts
78
- import {
79
- createPraxisEngine,
80
- PraxisRegistry,
81
- defineRule,
82
- createInMemoryDB,
83
- createPluresDBAdapter,
84
- createUnumAdapter,
85
- createStateDocsGenerator,
86
- schemaToCanvas,
87
- } from '@plures/praxis';
88
-
89
- // 1. Define logic with Praxis engine
90
- const registry = new PraxisRegistry();
91
- registry.registerRule(/* your rules */);
92
- const engine = createPraxisEngine({ initialContext: {}, registry });
93
-
94
- // 2. Add PluresDB for local-first persistence
95
- const db = createInMemoryDB();
96
- const pluresAdapter = createPluresDBAdapter({ db, registry });
97
- pluresAdapter.attachEngine(engine);
98
-
99
- // 3. Add Unum for distributed communication
100
- const unum = await createUnumAdapter({
101
- db,
102
- identity: { name: 'node-1' },
103
- realtime: true,
104
- });
105
- const channel = await unum.createChannel('app-sync');
112
+ ## Svelte 5 Integration
106
113
 
107
- // Subscribe to distribute events across nodes
108
- unum.subscribeToEvents(channel.id, (event) => {
109
- engine.step([event]);
110
- });
114
+ ### Runes API
111
115
 
112
- // 4. Generate documentation with State-Docs
113
- const docsGenerator = createStateDocsGenerator({
114
- projectTitle: 'My App',
115
- target: './docs',
116
- });
117
- const docs = docsGenerator.generateFromModule(registry.module);
118
-
119
- // 5. Export schema to CodeCanvas for visual editing
120
- const canvas = schemaToCanvas(mySchema);
121
- // Canvas can be edited visually and converted back to schema
122
-
123
- // Now you have:
124
- // ✅ Logic engine running
125
- // ✅ Auto-persisting to PluresDB
126
- // ✅ Distributing events across nodes via Unum
127
- // ✅ Auto-generated documentation
128
- // ✅ Visual schema representation
129
- ```
130
-
131
- ## Svelte integration (runes-ready)
132
116
  ```svelte
133
117
  <script lang="ts">
134
- import { createReactiveEngine, defineEvent, defineRule, PraxisRegistry } from '@plures/praxis/svelte';
135
-
136
- const Increment = defineEvent<'INCREMENT', { amount: number }>('INCREMENT');
137
- const counterRule = defineRule<{ count: number }>({
138
- id: 'counter.increment',
139
- description: 'Add to count',
140
- impl: (state, events) => {
141
- const evt = events.find(Increment.is);
142
- if (evt) state.context.count += evt.payload.amount;
143
- return [];
144
- },
145
- });
146
-
147
- const registry = new PraxisRegistry();
148
- registry.registerRule(counterRule);
149
-
150
- const engine = createReactiveEngine({ initialContext: { count: 0 }, registry });
151
-
152
- // Use Svelte's $derived with the reactive engine state
153
- const count = $derived(engine.context.count);
118
+ import { usePraxisEngine } from '@plures/praxis/svelte';
119
+ import { createMyEngine, Login } from './my-engine';
154
120
 
155
- function addOne() {
156
- engine.step([Increment.create({ amount: 1 })]);
157
- }
121
+ const engine = createMyEngine();
122
+ const { context, dispatch, undo, redo, canUndo, canRedo } = usePraxisEngine(engine, {
123
+ enableHistory: true,
124
+ maxHistorySize: 50,
125
+ });
158
126
  </script>
159
127
 
160
- <button on:click={addOne}>Count is {count}</button>
161
- ```
162
-
163
- ## Framework-agnostic reactive engine
164
- For non-Svelte environments, use the framework-agnostic reactive engine with Proxy-based reactivity:
165
-
166
- ```typescript
167
- import { createFrameworkAgnosticReactiveEngine } from '@plures/praxis';
168
-
169
- const engine = createFrameworkAgnosticReactiveEngine({
170
- initialContext: { count: 0 },
171
- });
172
-
173
- // Subscribe to state changes
174
- engine.subscribe((state) => {
175
- console.log('Count:', state.context.count);
176
- });
177
-
178
- // Create derived/computed values
179
- const doubled = engine.$derived((state) => state.context.count * 2);
180
- doubled.subscribe((value) => {
181
- console.log('Doubled:', value);
182
- });
183
-
184
- // Apply mutations (batched for performance)
185
- engine.apply((state) => {
186
- state.context.count += 1;
187
- });
128
+ <p>User: {context.currentUser || 'Guest'}</p>
129
+ <button onclick={() => dispatch([Login.create({ username: 'alice' })])}>Login</button>
130
+ <button onclick={undo} disabled={!canUndo}>⟲ Undo</button>
131
+ <button onclick={redo} disabled={!canRedo}>⟳ Redo</button>
188
132
  ```
189
133
 
190
- See the [reactive counter example](./examples/reactive-counter/README.md) for a complete demonstration.
134
+ ### Store API
191
135
 
192
- ## Cloud relay (optional)
193
136
  ```ts
194
- import { connectRelay } from '@plures/praxis/cloud';
195
-
196
- const relay = await connectRelay('https://my-relay.example.com', {
197
- appId: 'my-app',
198
- authToken: process.env.GITHUB_TOKEN,
199
- autoSync: true,
200
- });
201
-
202
- await relay.sync({
203
- type: 'delta',
204
- appId: 'my-app',
205
- clock: {},
206
- facts: [],
207
- timestamp: Date.now(),
208
- });
209
- ```
210
-
211
- ## PluresDB integration
212
- ```ts
213
- import { PluresNode } from 'pluresdb';
214
- import { createPluresDB, createPraxisDBStore } from '@plures/praxis';
215
- import { PraxisRegistry } from '@plures/praxis';
216
-
217
- // Initialize the official PluresDB from npm
218
- const pluresdb = new PluresNode({
219
- config: {
220
- port: 34567,
221
- dataDir: './data',
222
- },
223
- autoStart: true,
224
- });
225
-
226
- // Wrap it with the Praxis adapter
227
- const db = createPluresDB(pluresdb);
228
-
229
- // Use with Praxis store for local-first reactive data
230
- const registry = new PraxisRegistry();
231
- const store = createPraxisDBStore(db, registry);
137
+ import { createPraxisStore, createDerivedStore } from '@plures/praxis/svelte';
232
138
 
233
- // Or use in-memory database for development/testing
234
- import { createInMemoryDB } from '@plures/praxis';
235
- const devDb = createInMemoryDB();
139
+ const stateStore = createPraxisStore(engine);
140
+ const userStore = createDerivedStore(engine, (ctx) => ctx.currentUser);
236
141
  ```
237
142
 
238
- > **Note:** Praxis now uses the official [PluresDB package from NPM](https://www.npmjs.com/package/pluresdb), which provides P2P sync, CRDT conflict resolution, SQLite compatibility, and more. The `createPluresDB()` function wraps PluresDB to provide the `PraxisDB` interface used by Praxis.
239
-
240
- ## CLI (npx-friendly)
241
- ```bash
242
- npx praxis --help
243
- npx praxis create app my-app
244
- npx praxis generate --schema src/schemas/app.schema.ts
245
- npx praxis canvas src/schemas/app.schema.ts
246
- ```
143
+ See [Svelte Integration Guide](./docs/guides/svelte-integration.md) for the full API including reactive engine, history patterns, and keyboard shortcuts.
247
144
 
248
145
  ## Decision Ledger (Behavior Contracts)
249
146
 
250
- Document, validate, and track the evolution of your rules and constraints with explicit behavioral contracts.
147
+ Attach explicit contracts to every rule and constraint with Given/When/Then examples, invariants, and assumption tracking.
251
148
 
252
- ```typescript
149
+ ```ts
253
150
  import { defineContract, defineRule } from '@plures/praxis';
254
151
 
255
- // Define a contract with explicit behavior, examples, and invariants
256
152
  const loginContract = defineContract({
257
153
  ruleId: 'auth.login',
258
154
  behavior: 'Process login events and create user session facts',
259
155
  examples: [
260
- {
261
- given: 'User provides valid credentials',
262
- when: 'LOGIN event is received',
263
- then: 'UserSessionCreated fact is emitted'
264
- }
156
+ { given: 'Valid credentials', when: 'LOGIN event', then: 'UserSessionCreated fact emitted' }
265
157
  ],
266
158
  invariants: ['Session must have unique ID'],
267
- assumptions: [
268
- {
269
- id: 'assume-unique-username',
270
- statement: 'Usernames are unique across the system',
271
- confidence: 0.9,
272
- justification: 'Standard authentication practice',
273
- impacts: ['spec', 'tests', 'code'],
274
- status: 'active'
275
- }
276
- ]
277
159
  });
278
160
 
279
- // Attach contract to rule
280
161
  const loginRule = defineRule({
281
162
  id: 'auth.login',
282
163
  description: 'Process login events',
283
164
  impl: (state, events) => { /* ... */ },
284
- contract: loginContract
165
+ contract: loginContract,
285
166
  });
286
167
  ```
287
168
 
288
- **Validate contracts in CI/CD:**
289
169
  ```bash
290
- # Validate all contracts
291
- npx praxis validate --strict
292
-
293
- # Generate SARIF for GitHub Actions
294
- npx praxis validate --output sarif > results.sarif
295
-
296
- # Reverse engineer contracts from existing code
297
- npx praxis reverse --interactive
298
- ```
299
-
300
- **Key features:**
301
- - ✅ Explicit behavior documentation with Given/When/Then examples
302
- - ✅ Assumption tracking with confidence levels
303
- - ✅ Immutable ledger for change history
304
- - ✅ Build-time validation and CI/CD integration
305
- - ✅ Auto-generation from existing code
306
-
307
- See [src/decision-ledger/README.md](./src/decision-ledger/README.md) for complete documentation.
308
-
309
- ## Exports map
310
- - `@plures/praxis` → main engine (ESM/CJS/types)
311
- - `@plures/praxis/svelte` → Svelte 5 integrations
312
- - `@plures/praxis/schema` → Schema types
313
- - `@plures/praxis/component` → Component generator
314
- - `@plures/praxis/cloud` → Cloud relay APIs
315
- - `@plures/praxis/components` → TS props for Svelte components (e.g., TerminalNode)
316
- - `praxis` (bin) → CLI entrypoint
317
-
318
- ## Documentation
319
- - [Getting Started](./GETTING_STARTED.md)
320
- - [Framework Guide](./FRAMEWORK.md)
321
- - [Praxis-Core API](./docs/core/praxis-core-api.md) - Stable API surface & guarantees
322
- - [Extending Praxis-Core](./docs/core/extending-praxis-core.md) - Extension guidelines
323
- - [Decision Ledger Guide](./src/decision-ledger/README.md)
324
- - [Examples](./examples/)
325
-
326
- ## Decision Ledger
327
-
328
- Praxis dogfoods its Decision Ledger to keep rule/constraint behavior explicit and enforceable.
329
-
330
- - [Behavior Ledger](./docs/decision-ledger/BEHAVIOR_LEDGER.md)
331
- - [Dogfooding Guide](./docs/decision-ledger/DOGFOODING.md)
332
-
333
- ## Contributing
334
- PRs and discussions welcome. Please see [CONTRIBUTING.md](./CONTRIBUTING.md) and [SECURITY.md](./SECURITY.md).
335
- console.log(result.state.facts); // [{ tag: "UserLoggedIn", payload: { userId: "alice" } }]
336
- console.log(engine.getContext()); // { currentUser: "alice" }
170
+ npm run scan:rules # Index all rules/constraints
171
+ npm run validate:contracts # Validate all contracts
172
+ npx praxis validate --strict # CI/CD enforcement
337
173
  ```
338
174
 
339
- ### With Constraints
175
+ See [Decision Ledger Guide](./docs/decision-ledger/DOGFOODING.md) for the full dogfooding workflow.
340
176
 
341
- ```typescript
342
- import { defineConstraint } from '@plures/praxis';
177
+ ## PluresDB — Local-First Persistence
343
178
 
344
- const maxSessionsConstraint = defineConstraint<AuthContext>({
345
- id: 'auth.maxSessions',
346
- description: 'Only one user can be logged in at a time',
347
- impl: (state) => {
348
- return state.context.currentUser === null || 'User already logged in';
349
- },
350
- });
179
+ ```ts
180
+ import { createInMemoryDB, createPluresDBAdapter } from '@plures/praxis';
351
181
 
352
- registry.registerConstraint(maxSessionsConstraint);
182
+ const db = createInMemoryDB();
183
+ const adapter = createPluresDBAdapter({ db, registry });
184
+ adapter.attachEngine(engine); // auto-persist facts & events
353
185
  ```
354
186
 
355
- ### Svelte 5 Integration
356
-
357
- #### Store API (Svelte 4/5 Compatible)
187
+ For production, use the official [@plures/pluresdb](https://www.npmjs.com/package/@plures/pluresdb) package with P2P sync and CRDT conflict resolution:
358
188
 
359
- ```typescript
360
- import { createPraxisStore, createDerivedStore } from '@plures/praxis/svelte';
361
-
362
- const stateStore = createPraxisStore(engine);
363
- const userStore = createDerivedStore(engine, (ctx) => ctx.currentUser);
189
+ ```ts
190
+ import { PluresNode } from '@plures/pluresdb';
191
+ import { createPluresDB } from '@plures/praxis';
364
192
 
365
- // In Svelte component:
366
- // $: currentUser = $userStore;
367
- // <button on:click={() => stateStore.dispatch([Login.create({ username: "alice" })])}>
368
- // Login
369
- // </button>
193
+ const db = createPluresDB(new PluresNode({ config: { port: 34567, dataDir: './data' }, autoStart: true }));
370
194
  ```
371
195
 
372
- #### Runes API (Svelte 5 Only)
196
+ ## CLI
373
197
 
374
- ```svelte
375
- <script lang="ts">
376
- import { usePraxisEngine } from '@plures/praxis/svelte';
377
- import { createMyEngine, Login } from './my-engine';
378
-
379
- const engine = createMyEngine();
380
- const {
381
- context, // Reactive context
382
- dispatch, // Dispatch events
383
- undo, // Undo last action
384
- redo, // Redo action
385
- canUndo, // Boolean: can undo?
386
- canRedo, // Boolean: can redo?
387
- } = usePraxisEngine(engine, {
388
- enableHistory: true, // Enable undo/redo
389
- maxHistorySize: 50, // Keep last 50 snapshots
390
- });
391
- </script>
392
-
393
- <div>
394
- <p>User: {context.currentUser || 'Guest'}</p>
395
-
396
- <button onclick={() => dispatch([Login.create({ username: 'alice' })])}>
397
- Login
398
- </button>
399
-
400
- <button onclick={undo} disabled={!canUndo}>
401
- ⟲ Undo
402
- </button>
403
-
404
- <button onclick={redo} disabled={!canRedo}>
405
- ⟳ Redo
406
- </button>
407
- </div>
198
+ ```bash
199
+ npx praxis --help
200
+ npx praxis create app my-app
201
+ npx praxis generate --schema src/schemas/app.schema.ts
202
+ npx praxis canvas src/schemas/app.schema.ts
408
203
  ```
409
204
 
410
- See the [Advanced Todo Example](src/examples/advanced-todo/) for a complete demo with:
411
-
412
- - Undo/redo functionality
413
- - Time-travel debugging
414
- - Keyboard shortcuts
415
- - Beautiful UI
205
+ ## Exports
416
206
 
417
- For comprehensive guides:
418
-
419
- - [Svelte Integration Guide](docs/guides/svelte-integration.md)
420
- - [History State Pattern](docs/guides/history-state-pattern.md)
421
- - [Parallel State Pattern](docs/guides/parallel-state-pattern.md)
207
+ | Import path | Description |
208
+ |---|---|
209
+ | `@plures/praxis` | Core engine, DSL, protocol types, integrations |
210
+ | `@plures/praxis/unified` | `createApp()` unified reactive layer |
211
+ | `@plures/praxis/svelte` | Svelte 5 runes + store APIs |
212
+ | `@plures/praxis/schema` | Schema types and loaders |
213
+ | `@plures/praxis/component` | Svelte component generator |
214
+ | `@plures/praxis/cloud` | Cloud relay sync |
215
+ | `@plures/praxis/components` | Built-in Svelte components |
216
+ | `@plures/praxis/mcp` | Model Context Protocol tools |
217
+ | `@plures/praxis/expectations` | Behavior expectation DSL |
218
+ | `@plures/praxis/factory` | Pre-built UI rule modules |
219
+ | `@plures/praxis/project` | Project gates and lifecycle |
220
+ | `praxis` (bin) | CLI entrypoint |
422
221
 
423
222
  ## Core Protocol
424
223
 
425
- The language-neutral core protocol forms the foundation of Praxis:
426
-
427
- ```typescript
428
- // Facts and Events
429
- interface PraxisFact {
430
- tag: string;
431
- payload: unknown;
432
- }
433
-
434
- interface PraxisEvent {
435
- tag: string;
436
- payload: unknown;
437
- }
438
-
439
- // State
440
- interface PraxisState {
441
- context: unknown;
442
- facts: PraxisFact[];
443
- meta?: Record<string, unknown>;
444
- }
445
-
446
- // Step Function (the conceptual core)
447
- type PraxisStepFn = (
448
- state: PraxisState,
449
- events: PraxisEvent[],
450
- config: PraxisStepConfig
451
- ) => PraxisStepResult;
452
- ```
453
-
454
- This protocol is:
455
-
456
- - Pure and deterministic (data in → data out)
457
- - No side effects, no global state
458
- - JSON-friendly for cross-language compatibility
459
- - The foundation for all higher-level TypeScript APIs
460
-
461
- ## Framework Architecture
462
-
463
- Praxis is organized as a **monorepo** with clearly separated packages. See [MONOREPO.md](./MONOREPO.md) for the complete organization plan.
464
-
465
- ### Target Monorepo Structure
466
-
467
- ```
468
- praxis/
469
- ├── packages/ # Published npm packages
470
- │ ├── praxis-core/ # Core logic library (zero dependencies)
471
- │ │ └── src/
472
- │ │ ├── logic/ # Facts, events, rules, constraints, engine
473
- │ │ ├── schema/ # Schema definitions and validation
474
- │ │ ├── decision-ledger/ # Contracts and behavior specifications
475
- │ │ └── protocol/ # Core protocol types
476
- │ ├── praxis-cli/ # Command-line interface
477
- │ │ └── src/
478
- │ │ ├── commands/ # CLI commands
479
- │ │ └── generators/ # Code generators
480
- │ ├── praxis-svelte/ # Svelte 5 integration
481
- │ │ └── src/
482
- │ │ ├── components/ # Reactive Svelte components
483
- │ │ ├── generators/ # Component generators
484
- │ │ └── runtime/ # Svelte runtime integration
485
- │ ├── praxis-cloud/ # Cloud sync and relay
486
- │ │ └── src/
487
- │ │ ├── relay/ # Cloud relay server
488
- │ │ └── sync/ # Sync protocol
489
- │ └── praxis/ # Main package (re-exports all)
490
- ├── apps/ # Example applications
491
- ├── tools/ # Development tools
492
- ├── ui/ # UI components and tools
493
- ├── docs/ # Documentation
494
- └── examples/ # Simple examples and demos
495
- ```
496
-
497
- ### Current Structure (In Transition)
224
+ All Praxis APIs build on a language-neutral, pure-function protocol:
498
225
 
499
- The existing code is currently located in:
226
+ ```ts
227
+ interface PraxisFact { tag: string; payload: unknown }
228
+ interface PraxisEvent { tag: string; payload: unknown }
229
+ interface PraxisState { context: unknown; facts: PraxisFact[]; meta?: Record<string, unknown> }
500
230
 
501
- ```
502
- /praxis
503
- ├── core/ # Core framework
504
- │ ├── schema/ # Schema system
505
- │ │ └── types.ts # Schema type definitions
506
- │ ├── logic/ # Logic engine (existing src/core/)
507
- │ │ ├── protocol.ts # Language-neutral protocol
508
- │ │ ├── rules.ts # Rules, constraints, and registry
509
- │ │ ├── engine.ts # LogicEngine implementation
510
- │ │ ├── actors.ts # Actor system
511
- │ │ └── introspection.ts # Introspection and visualization
512
- │ ├── component/ # Component generation
513
- │ │ └── generator.ts # Svelte component generator
514
- │ ├── pluresdb/ # PluresDB integration core
515
- │ │ ├── adapter.ts # Database adapter interface
516
- │ │ ├── store.ts # Reactive store implementation
517
- │ │ ├── schema-registry.ts # Schema registry for PluresDB
518
- │ │ └── generator.ts # PluresDB config generator
519
- │ └── runtime/ # Runtime abstractions
520
- ├── cloud/ # Praxis Cloud integration
521
- │ ├── auth.ts # GitHub OAuth authentication
522
- │ ├── billing.ts # Tier-based billing
523
- │ ├── provisioning.ts # Tenant provisioning
524
- │ └── relay/ # Azure relay service
525
- ├── integrations/ # Ecosystem integrations
526
- │ ├── pluresdb.ts # PluresDB integration exports
527
- │ ├── svelte.ts # Svelte 5 integration
528
- │ ├── unum/ # Unum identity and channels
529
- │ ├── adp/ # Architectural Decision Protocol
530
- │ ├── state-docs/ # State-Docs documentation
531
- │ └── canvas/ # CodeCanvas visual editor
532
- ├── components/ # Svelte components
533
- │ └── TerminalNode.svelte # Terminal node component
534
- ├── cli/ # Command-line interface
535
- │ ├── index.ts # CLI entry point
536
- │ └── commands/ # Command implementations
537
- ├── templates/ # Project templates
538
- │ ├── basic-app/ # Basic application template
539
- │ └── fullstack-app/ # Full-stack template
540
- ├── examples/ # Example applications
541
- │ ├── offline-chat/ # Offline-first chat demo
542
- │ ├── knowledge-canvas/ # Knowledge management with Canvas
543
- │ ├── distributed-node/ # Self-orchestrating node demo
544
- │ ├── terminal-node/ # Terminal node demo
545
- │ ├── terminal-canvas/ # Terminal + canvas demo
546
- │ ├── cloud-sync/ # Cloud sync demo
547
- │ ├── github-monetization/ # GitHub monetization demo
548
- │ ├── simple-app/ # Simple app demo
549
- │ ├── auth-basic/ # Login/logout example
550
- │ ├── cart/ # Shopping cart example
551
- │ ├── svelte-counter/ # Svelte integration example
552
- │ └── hero-ecommerce/ # Comprehensive e-commerce demo
553
- └── docs/ # Framework documentation
554
- ├── guides/ # User guides
555
- │ ├── getting-started.md # Getting started guide
556
- │ ├── canvas.md # CodeCanvas guide
557
- │ └── orchestration.md # Orchestration guide
558
- ├── api/ # API reference
559
- └── architecture/ # Architecture documentation
231
+ // The conceptual core — pure, deterministic, no side effects
232
+ type PraxisStepFn = (state: PraxisState, events: PraxisEvent[], config: PraxisStepConfig) => PraxisStepResult;
560
233
  ```
561
234
 
562
- See [FRAMEWORK.md](./FRAMEWORK.md) for complete architecture documentation.
235
+ Implemented in TypeScript (npm), C# (.NET 8+, NuGet: `Plures.Praxis`), and PowerShell. All share the same JSON wire format. See [CROSS_LANGUAGE_SYNC.md](./CROSS_LANGUAGE_SYNC.md) and [PROTOCOL_VERSIONING.md](./PROTOCOL_VERSIONING.md).
563
236
 
564
237
  ## Examples
565
238
 
566
- The repository includes multiple complete examples:
567
-
568
- ### 1. Hero E-Commerce (`src/examples/hero-ecommerce`)
569
-
570
- Comprehensive example demonstrating all Praxis features in a single application:
571
-
572
- - Authentication with session management
573
- - Shopping cart with discount rules
574
- - Feature flags for A/B testing
575
- - Loyalty program with points
576
- - Actors for logging and analytics
577
- - Constraints enforcing business rules
578
-
579
- ```bash
580
- npm run build
581
- node dist/examples/hero-ecommerce/index.js
582
- ```
583
-
584
- ### 2. Offline-First Chat (`examples/offline-chat`)
585
-
586
- Demonstrates local-first architecture with PluresDB:
587
-
588
- - Offline message composition and storage
589
- - Automatic sync when connected
590
- - Message queue for offline messages
591
- - Conflict resolution for concurrent edits
592
- - Real-time features (typing indicators, read receipts)
593
-
594
- See [examples/offline-chat/README.md](./examples/offline-chat/README.md)
595
-
596
- ### 3. Knowledge Canvas (`examples/knowledge-canvas`)
597
-
598
- Showcases CodeCanvas integration for visual knowledge management:
599
-
600
- - Visual knowledge graph editing
601
- - Schema-driven content types
602
- - Generated UI components
603
- - State-Docs integration
604
- - Collaborative editing
605
-
606
- See [examples/knowledge-canvas/README.md](./examples/knowledge-canvas/README.md)
607
-
608
- ### 4. Self-Orchestrating Node (`examples/distributed-node`)
609
-
610
- Demonstrates distributed orchestration with DSC/MCP:
611
-
612
- - Automatic node discovery
613
- - Self-healing behavior
614
- - State synchronization across nodes
615
- - Health monitoring and auto-scaling
616
- - Failover and recovery
617
-
618
- See [examples/distributed-node/README.md](./examples/distributed-node/README.md)
619
-
620
- ### 5. Terminal Node (`examples/terminal-node`)
621
-
622
- Demonstrates the terminal node feature for command execution:
623
-
624
- - Terminal adapter creation and configuration
625
- - Command execution and history tracking
626
- - YAML schema loading with terminal nodes
627
- - PluresDB binding configuration
628
- - Both text and widget input modes
629
-
630
- ```bash
631
- npm run build
632
- node examples/terminal-node/index.js
633
- ```
634
-
635
- See [examples/terminal-node/README.md](./examples/terminal-node/README.md) and [docs/TERMINAL_NODE.md](./docs/TERMINAL_NODE.md)
636
-
637
- ### 6. Auth Basic (`src/examples/auth-basic`)
638
-
639
- Login/logout with facts, rules, and constraints.
640
-
641
- ```bash
642
- npm run build
643
- node dist/examples/auth-basic/index.js
644
- ```
645
-
646
- ### 7. Cart (`src/examples/cart`)
647
-
648
- Shopping cart with multiple rules, constraints, and complex state management.
649
-
650
- ```bash
651
- npm run build
652
- node dist/examples/cart/index.js
653
- ```
654
-
655
- ### 8. Svelte Counter (`src/examples/svelte-counter`)
656
-
657
- Counter example showing Svelte v5 integration with reactive stores.
658
-
659
- ```bash
660
- npm run build
661
- node dist/examples/svelte-counter/index.js
662
- ```
663
-
664
- ### 9. Terminal Canvas (`examples/terminal-canvas`)
665
-
666
- Combines terminal nodes with visual canvas features in a Svelte app.
239
+ | Example | Description | Location |
240
+ |---|---|---|
241
+ | Hero E-Commerce | Full-stack: auth, cart, discounts, loyalty, actors | `src/examples/hero-ecommerce/` |
242
+ | Decision Ledger | Contracts, validation, SARIF output | `examples/decision-ledger/` |
243
+ | Offline Chat | Local-first messaging with PluresDB | `examples/offline-chat/` |
244
+ | Terminal Node | Command execution with YAML schemas | `examples/terminal-node/` |
245
+ | Unified App | `createApp()` + rules + Mermaid docs | `examples/unified-app/` |
246
+ | Cloud Sync | Real-time relay synchronization | `examples/cloud-sync/` |
247
+ | Simple App | Minimal schema usage | `examples/simple-app/` |
248
+ | Reactive Counter | Framework-agnostic reactive engine | `examples/reactive-counter/` |
667
249
 
668
- See [examples/terminal-canvas/README.md](./examples/terminal-canvas/README.md)
250
+ Browse all examples in [`examples/`](./examples/) and [`src/examples/`](./src/examples/).
669
251
 
670
- ### 10. GitHub Monetization (`examples/github-monetization`)
671
-
672
- Example of GitHub-based monetization integration with Praxis Cloud.
673
-
674
- See [examples/github-monetization/README.md](./examples/github-monetization/README.md)
675
-
676
- ### 11. Simple App (`examples/simple-app`)
677
-
678
- A minimal example demonstrating basic Praxis schema usage.
679
-
680
- See [examples/simple-app/README.md](./examples/simple-app/README.md)
681
-
682
- ### 12. Cloud Sync (`examples/cloud-sync`)
683
-
684
- Demonstrates real-time synchronization with Praxis Cloud relay service.
685
-
686
- See [examples/cloud-sync/README.md](./examples/cloud-sync/README.md)
687
-
688
- ### 13. Decision Ledger (`examples/decision-ledger`)
689
-
690
- Demonstrates behavior contracts for rules and constraints with validation and immutable ledger tracking.
691
-
692
- Features:
693
- - Contract definition with behavior, examples, and invariants
694
- - Assumption tracking with confidence levels
695
- - Validation and reporting (console, JSON, SARIF)
696
- - Immutable logic ledger for change history
697
- - CLI integration for CI/CD pipelines
698
-
699
- ```bash
700
- npm run build
701
- node examples/decision-ledger/index.js
702
-
703
- # Validate contracts
704
- npx praxis validate --registry examples/sample-registry.js
705
- ```
706
-
707
- See [examples/decision-ledger/README.md](./examples/decision-ledger/README.md)
708
-
709
- ## API Reference
710
-
711
- ### Core Types
712
-
713
- - `PraxisFact`, `PraxisEvent`, `PraxisState` - Protocol types
714
- - `LogicEngine<TContext>` - Main engine class
715
- - `PraxisRegistry<TContext>` - Rule and constraint registry
716
- - `Actor<TContext>` - Actor interface
717
- - `ActorManager<TContext>` - Actor lifecycle management
718
-
719
- ### DSL Functions
720
-
721
- - `defineFact<TTag, TPayload>(tag)` - Define a typed fact
722
- - `defineEvent<TTag, TPayload>(tag)` - Define a typed event
723
- - `defineRule<TContext>(options)` - Define a rule
724
- - `defineConstraint<TContext>(options)` - Define a constraint
725
- - `defineModule<TContext>(options)` - Bundle rules and constraints
726
-
727
- ### Helpers
728
-
729
- - `findEvent(events, definition)` - Find first matching event
730
- - `findFact(facts, definition)` - Find first matching fact
731
- - `filterEvents(events, definition)` - Filter events by type
732
- - `filterFacts(facts, definition)` - Filter facts by type
733
-
734
- ### Introspection & Visualization
735
-
736
- Tools for examining and visualizing your Praxis logic:
737
-
738
- ```typescript
739
- import { createIntrospector, PRAXIS_PROTOCOL_VERSION } from '@plures/praxis';
740
-
741
- const introspector = createIntrospector(registry);
742
-
743
- // Get statistics
744
- const stats = introspector.getStats();
745
- console.log(`Rules: ${stats.ruleCount}, Constraints: ${stats.constraintCount}`);
746
-
747
- // Generate JSON schema
748
- const schema = introspector.generateSchema(PRAXIS_PROTOCOL_VERSION);
749
-
750
- // Generate graph visualization
751
- const graph = introspector.generateGraph();
752
-
753
- // Export to Graphviz DOT format
754
- const dot = introspector.exportDOT();
755
- fs.writeFileSync('registry.dot', dot);
756
-
757
- // Export to Mermaid format
758
- const mermaid = introspector.exportMermaid();
759
-
760
- // Search rules and constraints
761
- const authRules = introspector.searchRules('auth');
762
- const maxConstraints = introspector.searchConstraints('max');
763
- ```
764
-
765
- **Available methods:**
766
-
767
- - `getStats()` - Get registry statistics
768
- - `generateSchema(protocolVersion)` - Generate JSON schema
769
- - `generateGraph()` - Generate graph representation
770
- - `exportDOT()` - Export to Graphviz DOT format
771
- - `exportMermaid()` - Export to Mermaid diagram format
772
- - `getRuleInfo(id)` - Get detailed rule information
773
- - `getConstraintInfo(id)` - Get detailed constraint information
774
- - `searchRules(query)` - Search rules by text
775
- - `searchConstraints(query)` - Search constraints by text
776
-
777
- ## Ecosystem Integration
778
-
779
- Praxis integrates with the full Plures ecosystem:
780
-
781
- ### PluresDB Integration
782
-
783
- Local-first reactive datastore for offline-capable applications. Fully implemented with 32 tests covering all features.
784
-
785
- ```typescript
786
- import {
787
- createInMemoryDB,
788
- createPraxisDBStore,
789
- createPluresDBAdapter,
790
- attachToEngine,
791
- } from '@plures/praxis/pluresdb';
792
-
793
- // Create an in-memory database
794
- const db = createInMemoryDB();
795
-
796
- // Create a PraxisDB store for facts and events
797
- const store = createPraxisDBStore({ db });
798
-
799
- // Or create an adapter to attach to an engine
800
- const adapter = createPluresDBAdapter({
801
- db,
802
- registry,
803
- initialContext: {},
804
- });
805
-
806
- // Attach adapter to engine for automatic persistence
807
- adapter.attachEngine(engine);
808
-
809
- // Persist facts and events
810
- await adapter.persistFacts([{ tag: 'UserLoggedIn', payload: { userId: 'alice' } }]);
811
- await adapter.persistEvents([{ tag: 'LOGIN', payload: { username: 'alice' } }]);
812
-
813
- // Subscribe to changes
814
- adapter.subscribeToEvents((events) => {
815
- console.log('New events:', events);
816
- });
817
- ```
818
-
819
- **Features:**
820
-
821
- - **In-memory adapter**: Ready-to-use implementation for development and testing
822
- - **Reactive store**: Watch for changes with callbacks
823
- - **Schema registry**: Store and retrieve schemas in PluresDB
824
- - **Config generator**: Generate PluresDB configuration from Praxis schemas
825
- - **Engine integration**: Automatic fact/event persistence
826
-
827
- **Status**: ✅ Available (`src/core/pluresdb/`, `src/integrations/pluresdb.ts`)
828
- **Tests**: 32 tests covering adapter, store, registry, and engine integration
829
-
830
- ### Unum Integration
831
-
832
- Identity and channels for distributed systems. Fully implemented with comprehensive channel and identity management.
833
-
834
- ```typescript
835
- import {
836
- createUnumAdapter,
837
- attachUnumToEngine,
838
- } from '@plures/praxis';
839
-
840
- // Create Unum adapter with identity
841
- const unum = await createUnumAdapter({
842
- db: pluresDB,
843
- identity: {
844
- name: 'my-app-node',
845
- metadata: { role: 'coordinator' },
846
- },
847
- realtime: true,
848
- });
849
-
850
- // Create a channel for messaging
851
- const channel = await unum.createChannel('app-events', ['member-1', 'member-2']);
852
-
853
- // Broadcast Praxis events to channel
854
- await unum.broadcastEvent(channel.id, {
855
- tag: 'USER_JOINED',
856
- payload: { userId: 'alice' },
857
- });
858
-
859
- // Subscribe to events from channel
860
- const unsubscribe = unum.subscribeToEvents(channel.id, (event) => {
861
- console.log('Received event:', event);
862
- // Feed into local Praxis engine
863
- engine.step([event]);
864
- });
865
-
866
- // Attach to engine for automatic event broadcasting
867
- attachUnumToEngine(engine, unum, channel.id);
868
- ```
869
-
870
- **Features:**
871
-
872
- - **Identity Management**: Create and manage user/node identities
873
- - **Channel Communication**: Real-time messaging between distributed nodes
874
- - **Event Broadcasting**: Share Praxis events across channels
875
- - **Fact Synchronization**: Distribute facts to connected participants
876
- - **PluresDB Integration**: Persists identities and messages
877
-
878
- **Status**: ✅ Available (`src/integrations/unum.ts`)
879
- **Tests**: Comprehensive integration tests
880
- **Use Cases**: Distributed messaging, identity management, multi-user collaboration
881
-
882
-
883
- ### State-Docs Integration
884
-
885
- Living documentation generated from Praxis schemas. Fully implemented with Markdown and Mermaid diagram generation.
886
-
887
- ```typescript
888
- import {
889
- createStateDocsGenerator,
890
- generateDocs,
891
- } from '@plures/praxis';
892
-
893
- // Create generator
894
- const generator = createStateDocsGenerator({
895
- projectTitle: 'My Praxis App',
896
- target: './docs',
897
- visualization: {
898
- format: 'mermaid',
899
- theme: 'default',
900
- },
901
- template: {
902
- toc: true,
903
- timestamp: true,
904
- },
905
- });
906
-
907
- // Generate docs from schema
908
- const docs = generator.generateFromSchema(appSchema);
909
-
910
- // Or from registry
911
- const registryDocs = generator.generateFromModule(myModule);
912
-
913
- // Write generated docs
914
- for (const doc of docs) {
915
- await writeFile(doc.path, doc.content);
916
- }
917
-
918
- // Quick helper
919
- const allDocs = generateDocs(appSchema, {
920
- projectTitle: 'My App',
921
- target: './docs',
922
- });
923
- ```
924
-
925
- **Features:**
926
-
927
- - **Schema Documentation**: Auto-generate docs from Praxis schemas
928
- - **Mermaid Diagrams**: Visual state machine and flow diagrams
929
- - **Markdown Output**: GitHub-ready documentation
930
- - **Model & Component Docs**: Detailed API documentation
931
- - **Logic Flow Visualization**: Event → Rule → Fact diagrams
932
- - **Table of Contents**: Automatic ToC generation
933
-
934
- **Status**: ✅ Available (`src/integrations/state-docs.ts`)
935
- **Documentation**: Auto-generates README, models.md, logic diagrams
936
-
937
- ### CodeCanvas Integration
938
-
939
- Visual IDE for schema and logic editing. Fully implemented with schema visualization and canvas export.
940
-
941
- ```typescript
942
- import {
943
- schemaToCanvas,
944
- canvasToSchema,
945
- canvasToMermaid,
946
- createCanvasEditor,
947
- } from '@plures/praxis';
948
-
949
- // Convert schema to canvas document
950
- const canvas = schemaToCanvas(mySchema, {
951
- layout: 'hierarchical',
952
- });
953
-
954
- // Export to YAML (Obsidian Canvas compatible)
955
- const yaml = canvasToYaml(canvas);
956
- await writeFile('./schema.canvas.yaml', yaml);
957
-
958
- // Export to Mermaid diagram
959
- const mermaid = canvasToMermaid(canvas);
960
-
961
- // Create canvas editor instance
962
- const editor = createCanvasEditor({
963
- schema: mySchema,
964
- enableFSM: true,
965
- layout: 'hierarchical',
966
- });
967
-
968
- // Add nodes programmatically
969
- editor.addNode({
970
- type: 'model',
971
- label: 'User',
972
- x: 100,
973
- y: 100,
974
- width: 150,
975
- height: 60,
976
- data: userModel,
977
- });
978
-
979
- // Convert back to schema
980
- const updatedSchema = editor.toSchema();
981
- ```
982
-
983
- **Features:**
984
-
985
- - **Visual Schema Design**: Node-based schema editor
986
- - **Canvas Export**: YAML and Mermaid diagram formats
987
- - **Obsidian Compatible**: Works with Obsidian Canvas format
988
- - **FSM Visualization**: State machine and flow diagrams
989
- - **Bi-directional Sync**: Canvas ↔ Schema round-tripping
990
- - **Guardian Validation**: Pre-commit lifecycle checks
991
-
992
- **Status**: ✅ Available (`src/integrations/code-canvas.ts`)
993
- **Documentation**: [docs/guides/canvas.md](./docs/guides/canvas.md)
994
-
995
- ### Svelte Integration
996
-
997
- Svelte v5 integration with reactive stores.
998
-
999
- ```typescript
1000
- import { createPraxisStore } from '@plures/praxis/svelte';
1001
-
1002
- const stateStore = createPraxisStore(engine);
1003
- const userStore = createDerivedStore(engine, (ctx) => ctx.currentUser);
1004
-
1005
- // In Svelte component:
1006
- // $: currentUser = $userStore;
1007
- ```
1008
-
1009
- ## Cross-Language Usage
1010
-
1011
- ### PowerShell
1012
-
1013
- Full PowerShell adapter for using Praxis from PowerShell scripts:
1014
-
1015
- ```powershell
1016
- # Import module
1017
- Import-Module ./powershell/Praxis.psm1
1018
-
1019
- # Initialize adapter
1020
- Initialize-PraxisAdapter -EnginePath "./dist/adapters/cli.js"
1021
-
1022
- # Create state and events
1023
- $state = New-PraxisState -Context @{ count = 0 }
1024
- $event = New-PraxisEvent -Tag "INCREMENT" -Payload @{}
1025
-
1026
- # Process step
1027
- $result = Invoke-PraxisStep -State $state -Events @($event) -ConfigPath "./config.json"
1028
-
1029
- # Use result
1030
- Write-Host "Count: $($result.state.context.count)"
1031
- ```
1032
-
1033
- See [powershell/README.md](./powershell/README.md) for complete documentation and examples.
1034
-
1035
- ### C# (.NET 8+)
1036
-
1037
- Full C# implementation with functional, immutable design:
1038
-
1039
- ```csharp
1040
- using Praxis.Core;
1041
- using Praxis.Dsl;
1042
-
1043
- // Define facts and events
1044
- var UserLoggedIn = PraxisDsl.DefineFact<UserPayload>("UserLoggedIn");
1045
- var Login = PraxisDsl.DefineEvent<LoginPayload>("LOGIN");
1046
-
1047
- record UserPayload(string UserId);
1048
- record LoginPayload(string Username);
1049
-
1050
- // Define rules
1051
- var loginRule = PraxisDsl.DefineRule<AuthContext>(
1052
- id: "auth.login",
1053
- description: "Process login event",
1054
- impl: (state, context, events) =>
1055
- {
1056
- var loginEvent = events.FindEvent(Login);
1057
- if (loginEvent != null)
1058
- {
1059
- var payload = Login.GetPayload(loginEvent);
1060
- return [UserLoggedIn.Create(new UserPayload(payload?.Username ?? "unknown"))];
1061
- }
1062
- return [];
1063
- });
1064
-
1065
- // Create engine
1066
- var registry = new PraxisRegistry<AuthContext>();
1067
- registry.RegisterRule(loginRule);
1068
-
1069
- var engine = PraxisEngine.Create(new PraxisEngineOptions<AuthContext>
1070
- {
1071
- InitialContext = new AuthContext(null),
1072
- Registry = registry
1073
- });
1074
-
1075
- // Dispatch events
1076
- var result = engine.Step([Login.Create(new LoginPayload("alice"))]);
1077
- Console.WriteLine($"Facts: {result.State.Facts.Count}"); // Facts: 1
1078
- ```
1079
-
1080
- See [csharp/Praxis/README.md](./csharp/Praxis/README.md) for complete documentation.
1081
-
1082
-
1083
- ## Cross-Language Support
1084
-
1085
- The core protocol is implemented across multiple languages:
1086
-
1087
- **TypeScript** (Primary, npm: `@plures/praxis`)
1088
-
1089
- ```typescript
1090
- import { createPraxisEngine, PraxisRegistry } from '@plures/praxis';
1091
-
1092
- const engine = createPraxisEngine({
1093
- initialContext: {},
1094
- registry: new PraxisRegistry(),
1095
- });
1096
- const result = engine.step(events);
1097
- ```
1098
-
1099
- **C#** (.NET 8+, NuGet: `Plures.Praxis`)
1100
-
1101
- ```csharp
1102
- var engine = PraxisEngine.Create(new PraxisEngineOptions<TContext> { ... });
1103
- var result = engine.Step(events);
1104
- ```
1105
-
1106
- See [csharp/Praxis/README.md](./csharp/Praxis/README.md) for full documentation.
1107
-
1108
- **PowerShell** (GitHub: `Praxis.psm1`)
1109
-
1110
- ```powershell
1111
- $newState = Invoke-PraxisStep -State $state -Events $events
1112
- ```
1113
-
1114
- See [powershell/README.md](./powershell/README.md) for full documentation.
252
+ ## Documentation
1115
253
 
1116
- All implementations share the same protocol version and JSON format for interoperability.
1117
- See [CROSS_LANGUAGE_SYNC.md](./CROSS_LANGUAGE_SYNC.md) for details on keeping implementations in sync.
254
+ | Resource | Link |
255
+ |---|---|
256
+ | Getting Started | [GETTING_STARTED.md](./GETTING_STARTED.md) |
257
+ | Framework Architecture | [FRAMEWORK.md](./FRAMEWORK.md) |
258
+ | Core API Reference | [docs/core/praxis-core-api.md](./docs/core/praxis-core-api.md) |
259
+ | Extending Praxis | [docs/core/extending-praxis-core.md](./docs/core/extending-praxis-core.md) |
260
+ | Svelte Integration | [docs/guides/svelte-integration.md](./docs/guides/svelte-integration.md) |
261
+ | CodeCanvas Guide | [docs/guides/canvas.md](./docs/guides/canvas.md) |
262
+ | Decision Ledger | [docs/decision-ledger/DOGFOODING.md](./docs/decision-ledger/DOGFOODING.md) |
263
+ | Tutorials | [docs/tutorials/](./docs/tutorials/) |
264
+ | Migration from 1.x | [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) |
265
+ | Roadmap | [ROADMAP.md](./ROADMAP.md) |
266
+ | 1.x Archive | [docs/archive/1.x/](./docs/archive/1.x/) |
1118
267
 
1119
268
  ## Development
1120
269
 
1121
270
  ```bash
1122
- # Install dependencies
1123
- npm install
1124
-
1125
- # Build
1126
- npm run build
1127
-
1128
- # Run tests
1129
- npm test
1130
-
1131
- # Type check
1132
- npm run typecheck
1133
- ```
1134
-
1135
- ### Deno Development
1136
-
1137
- ```bash
1138
- # Run with Deno
1139
- deno task dev
1140
-
1141
- # Run tests
1142
- deno task test
1143
-
1144
- # Lint and format
1145
- deno task lint
1146
- deno task fmt
271
+ npm install # Install dependencies
272
+ npm run build # Build (ESM + CJS via tsup)
273
+ npm test # Run tests (Vitest)
274
+ npm run typecheck # Type-check
1147
275
  ```
1148
276
 
1149
- For more detailed development information, see [CONTRIBUTING.md](./CONTRIBUTING.md).
1150
-
1151
- ## License
1152
-
1153
- MIT License - see [LICENSE](./LICENSE) for details.
1154
-
1155
277
  ## Contributing
1156
278
 
1157
- Contributions are welcome! Please read our [Contributing Guide](./CONTRIBUTING.md) to get started.
1158
-
1159
- **Automated Updates**: This repository uses batched bot updates to reduce commit churn. Dependency updates are grouped weekly and include audit trails. See the [Bot Update Policy](./docs/BOT_UPDATE_POLICY.md) for details.
1160
-
1161
- **Dogfooding Plures Tools**: We actively dogfood all Plures tools during development. If you encounter friction while using any tool, please file a [Dogfooding Friction Report](https://github.com/plures/praxis/issues/new/choose). See the [Dogfooding Quick Start](./docs/DOGFOODING_QUICK_START.md) for details.
279
+ PRs and discussions welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md).
1162
280
 
1163
281
  - 🐛 [Report a bug](https://github.com/plures/praxis/issues/new?template=bug_report.yml)
1164
282
  - 💡 [Request a feature](https://github.com/plures/praxis/issues/new?template=enhancement.yml)
1165
- - 📖 [Improve documentation](https://github.com/plures/praxis/issues/new?template=bug_report.yml)
1166
283
  - 🔒 [Report a security issue](./SECURITY.md)
1167
284
 
1168
- Please review our [Code of Conduct](./CODE_OF_CONDUCT.md) before participating.
1169
-
1170
- ## Support
1171
-
1172
- - 📚 [Documentation](./docs/)
1173
- - 💬 [GitHub Discussions](https://github.com/plures/praxis/discussions)
1174
- - 🐛 [Issue Tracker](https://github.com/plures/praxis/issues)
1175
- - 🌐 [Plures Organization](https://github.com/plures)
1176
-
1177
- ---
1178
-
1179
- **Praxis** – Because application logic should be practical, provable, and portable.
1180
-
1181
- ---
285
+ ## License
1182
286
 
1183
- Built with ❤️ by the plures team
287
+ [MIT](./LICENSE)
1184
288
 
1185
289
  ---
1186
290
 
1187
- <!-- plures-readme-standard-sections -->
1188
- ## Overview
1189
-
1190
- ## Install
291
+ **Praxis** practical, provable, portable application logic.
1191
292
 
1192
- ## Development
1193
-
1194
- ## Contributing
1195
-
1196
- ## License
293
+ Built with ❤️ by the [Plures](https://github.com/plures) team