@plures/praxis 1.3.0 → 1.4.4

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/dist/browser/{chunk-N63K4KWS.js → chunk-4IRUGWR3.js} +1 -1
  2. package/dist/browser/chunk-6SJ44Q64.js +473 -0
  3. package/dist/browser/chunk-BQOYZBWA.js +282 -0
  4. package/dist/browser/chunk-IG5BJ2MT.js +91 -0
  5. package/dist/browser/{chunk-MJK3IYTJ.js → chunk-JZDJU2DO.js} +4 -84
  6. package/dist/browser/chunk-ZEW4LJAJ.js +353 -0
  7. package/dist/browser/{engine-YIEGSX7U.js → engine-3B5WJPGT.js} +2 -1
  8. package/dist/browser/expectations/index.d.ts +180 -0
  9. package/dist/browser/expectations/index.js +14 -0
  10. package/dist/browser/factory/index.d.ts +149 -0
  11. package/dist/browser/factory/index.js +15 -0
  12. package/dist/browser/index.d.ts +274 -3
  13. package/dist/browser/index.js +407 -54
  14. package/dist/browser/integrations/svelte.d.ts +3 -2
  15. package/dist/browser/integrations/svelte.js +3 -2
  16. package/dist/browser/project/index.d.ts +176 -0
  17. package/dist/browser/project/index.js +19 -0
  18. package/dist/browser/reactive-engine.svelte-DgVTqHLc.d.ts +223 -0
  19. package/dist/browser/{reactive-engine.svelte-DjynI82A.d.ts → rules-i1LHpnGd.d.ts} +13 -221
  20. package/dist/node/chunk-2IUFZBH3.js +87 -0
  21. package/dist/node/{chunk-WZ6B3LZ6.js → chunk-7CSWBDFL.js} +3 -56
  22. package/dist/node/chunk-AZLNISFI.js +1690 -0
  23. package/dist/node/chunk-IG5BJ2MT.js +91 -0
  24. package/dist/node/{chunk-KMJWAFZV.js → chunk-JZDJU2DO.js} +4 -89
  25. package/dist/node/chunk-PGVSB6NR.js +59 -0
  26. package/dist/node/{chunk-5JQJZADT.js → chunk-ZO2LU4G4.js} +4 -4
  27. package/dist/node/cli/index.cjs +1126 -211
  28. package/dist/node/cli/index.js +21 -2
  29. package/dist/node/{engine-FEN5IYZ5.js → engine-VFHCIEM4.js} +2 -1
  30. package/dist/node/index.cjs +5623 -2765
  31. package/dist/node/index.d.cts +1181 -1
  32. package/dist/node/index.d.ts +1181 -1
  33. package/dist/node/index.js +1646 -79
  34. package/dist/node/integrations/svelte.js +4 -3
  35. package/dist/node/{reverse-W7THPV45.js → reverse-YD3CWIGM.js} +3 -2
  36. package/dist/node/rules-4DAJ4Z4N.js +7 -0
  37. package/dist/node/server-FKLVY57V.js +363 -0
  38. package/dist/node/{validate-EN3M4FUR.js → validate-5PSWJTIC.js} +5 -3
  39. package/package.json +50 -3
  40. package/src/__tests__/chronos-project.test.ts +799 -0
  41. package/src/__tests__/decision-ledger.test.ts +857 -402
  42. package/src/__tests__/expectations.test.ts +364 -0
  43. package/src/__tests__/factory.test.ts +426 -0
  44. package/src/__tests__/mcp-server.test.ts +310 -0
  45. package/src/__tests__/project.test.ts +396 -0
  46. package/src/chronos/diff.ts +336 -0
  47. package/src/chronos/hooks.ts +227 -0
  48. package/src/chronos/index.ts +83 -0
  49. package/src/chronos/project-chronicle.ts +198 -0
  50. package/src/chronos/timeline.ts +152 -0
  51. package/src/cli/index.ts +28 -0
  52. package/src/decision-ledger/analyzer-types.ts +280 -0
  53. package/src/decision-ledger/analyzer.ts +518 -0
  54. package/src/decision-ledger/contract-verification.ts +456 -0
  55. package/src/decision-ledger/derivation.ts +158 -0
  56. package/src/decision-ledger/index.ts +59 -0
  57. package/src/decision-ledger/report.ts +378 -0
  58. package/src/decision-ledger/suggestions.ts +287 -0
  59. package/src/expectations/expectations.ts +471 -0
  60. package/src/expectations/index.ts +29 -0
  61. package/src/expectations/types.ts +95 -0
  62. package/src/factory/factory.ts +634 -0
  63. package/src/factory/index.ts +27 -0
  64. package/src/factory/types.ts +64 -0
  65. package/src/index.browser.ts +83 -0
  66. package/src/index.ts +134 -0
  67. package/src/mcp/index.ts +33 -0
  68. package/src/mcp/server.ts +485 -0
  69. package/src/mcp/types.ts +161 -0
  70. package/src/project/index.ts +31 -0
  71. package/src/project/project.ts +423 -0
  72. package/src/project/types.ts +87 -0
  73. package/dist/node/chunk-PTH6MD6P.js +0 -487
  74. /package/dist/node/{chunk-R2PSBPKQ.js → chunk-TEMFJOIH.js} +0 -0
@@ -1,487 +0,0 @@
1
- import {
2
- getContractFromDescriptor
3
- } from "./chunk-WZ6B3LZ6.js";
4
-
5
- // src/dsl/index.ts
6
- function defineFact(tag) {
7
- return {
8
- tag,
9
- create(payload) {
10
- return { tag, payload };
11
- },
12
- is(fact) {
13
- return fact.tag === tag;
14
- }
15
- };
16
- }
17
- function defineEvent(tag) {
18
- return {
19
- tag,
20
- create(payload) {
21
- return { tag, payload };
22
- },
23
- is(event) {
24
- return event.tag === tag;
25
- }
26
- };
27
- }
28
- function defineRule(options) {
29
- const contract = options.contract ?? options.meta?.contract;
30
- const meta = contract ? { ...options.meta ?? {}, contract } : options.meta;
31
- return {
32
- id: options.id,
33
- description: options.description,
34
- impl: options.impl,
35
- eventTypes: options.eventTypes,
36
- contract,
37
- meta
38
- };
39
- }
40
- function defineConstraint(options) {
41
- const contract = options.contract ?? options.meta?.contract;
42
- const meta = contract ? { ...options.meta ?? {}, contract } : options.meta;
43
- return {
44
- id: options.id,
45
- description: options.description,
46
- impl: options.impl,
47
- contract,
48
- meta
49
- };
50
- }
51
- function defineModule(options) {
52
- return {
53
- rules: options.rules ?? [],
54
- constraints: options.constraints ?? [],
55
- meta: options.meta
56
- };
57
- }
58
- function filterEvents(events, definition) {
59
- return events.filter(definition.is);
60
- }
61
- function filterFacts(facts, definition) {
62
- return facts.filter(definition.is);
63
- }
64
- function findEvent(events, definition) {
65
- return events.find(definition.is);
66
- }
67
- function findFact(facts, definition) {
68
- return facts.find(definition.is);
69
- }
70
-
71
- // src/decision-ledger/facts-events.ts
72
- var ContractMissing = defineFact("ContractMissing");
73
- var ContractValidated = defineFact("ContractValidated");
74
- var AcknowledgeContractGap = defineEvent("ACKNOWLEDGE_CONTRACT_GAP");
75
- var ValidateContracts = defineEvent("VALIDATE_CONTRACTS");
76
- var ContractGapAcknowledged = defineFact("ContractGapAcknowledged");
77
- var ContractAdded = defineEvent("CONTRACT_ADDED");
78
- var ContractUpdated = defineEvent("CONTRACT_UPDATED");
79
- var ContractGapEmitted = defineEvent("CONTRACT_GAP_EMITTED");
80
-
81
- // src/decision-ledger/validation.ts
82
- function validateContracts(registry, options = {}) {
83
- const {
84
- incompleteSeverity = "warning",
85
- requiredFields = ["behavior", "examples"],
86
- artifactIndex
87
- } = options;
88
- const complete = [];
89
- const incomplete = [];
90
- const missing = [];
91
- for (const rule of registry.getAllRules()) {
92
- const contract = getContractFromDescriptor(rule);
93
- if (!contract) {
94
- missing.push(rule.id);
95
- if (options.missingSeverity) {
96
- incomplete.push({
97
- ruleId: rule.id,
98
- missing: ["contract"],
99
- severity: options.missingSeverity,
100
- message: `Rule '${rule.id}' has no contract`
101
- });
102
- }
103
- continue;
104
- }
105
- const gaps = validateContract(contract, requiredFields, artifactIndex);
106
- if (gaps.length > 0) {
107
- incomplete.push({
108
- ruleId: rule.id,
109
- missing: gaps,
110
- severity: incompleteSeverity,
111
- message: `Rule '${rule.id}' contract is incomplete: missing ${gaps.join(", ")}`
112
- });
113
- } else {
114
- complete.push({ ruleId: rule.id, contract });
115
- }
116
- }
117
- for (const constraint of registry.getAllConstraints()) {
118
- const contract = getContractFromDescriptor(constraint);
119
- if (!contract) {
120
- missing.push(constraint.id);
121
- if (options.missingSeverity) {
122
- incomplete.push({
123
- ruleId: constraint.id,
124
- missing: ["contract"],
125
- severity: options.missingSeverity,
126
- message: `Constraint '${constraint.id}' has no contract`
127
- });
128
- }
129
- continue;
130
- }
131
- const gaps = validateContract(contract, requiredFields, artifactIndex);
132
- if (gaps.length > 0) {
133
- incomplete.push({
134
- ruleId: constraint.id,
135
- missing: gaps,
136
- severity: incompleteSeverity,
137
- message: `Constraint '${constraint.id}' contract is incomplete: missing ${gaps.join(", ")}`
138
- });
139
- } else {
140
- complete.push({ ruleId: constraint.id, contract });
141
- }
142
- }
143
- const total = registry.getAllRules().length + registry.getAllConstraints().length;
144
- return {
145
- complete,
146
- incomplete,
147
- missing,
148
- total,
149
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
150
- };
151
- }
152
- function validateContract(contract, requiredFields, artifactIndex) {
153
- const missing = [];
154
- if (requiredFields.includes("behavior") && isFieldEmpty(contract.behavior)) {
155
- missing.push("behavior");
156
- }
157
- if (requiredFields.includes("examples") && (!contract.examples || contract.examples.length === 0)) {
158
- missing.push("examples");
159
- }
160
- if (requiredFields.includes("invariants") && (!contract.invariants || contract.invariants.length === 0)) {
161
- missing.push("invariants");
162
- }
163
- if (artifactIndex?.tests && !artifactIndex.tests.has(contract.ruleId)) {
164
- missing.push("tests");
165
- }
166
- if (artifactIndex?.spec && !artifactIndex.spec.has(contract.ruleId)) {
167
- missing.push("spec");
168
- }
169
- return missing;
170
- }
171
- function isFieldEmpty(value) {
172
- return !value || value.trim() === "";
173
- }
174
- function formatValidationReport(report) {
175
- const lines = [];
176
- lines.push("Contract Validation Report");
177
- lines.push("=".repeat(50));
178
- lines.push("");
179
- lines.push(`Total: ${report.total}`);
180
- lines.push(`Complete: ${report.complete.length}`);
181
- lines.push(`Incomplete: ${report.incomplete.length}`);
182
- lines.push(`Missing: ${report.missing.length}`);
183
- lines.push("");
184
- if (report.complete.length > 0) {
185
- lines.push("\u2713 Complete Contracts:");
186
- for (const { ruleId, contract } of report.complete) {
187
- lines.push(` \u2713 ${ruleId} (v${contract.version || "1.0.0"})`);
188
- }
189
- lines.push("");
190
- }
191
- if (report.incomplete.length > 0) {
192
- lines.push("\u2717 Incomplete Contracts:");
193
- for (const gap of report.incomplete) {
194
- const icon = gap.severity === "error" ? "\u2717" : gap.severity === "warning" ? "\u26A0" : "\u2139";
195
- lines.push(` ${icon} ${gap.ruleId} - Missing: ${gap.missing.join(", ")}`);
196
- if (gap.message) {
197
- lines.push(` ${gap.message}`);
198
- }
199
- }
200
- lines.push("");
201
- }
202
- if (report.missing.length > 0) {
203
- lines.push("\u2717 No Contract:");
204
- for (const ruleId of report.missing) {
205
- lines.push(` \u2717 ${ruleId}`);
206
- }
207
- lines.push("");
208
- }
209
- lines.push(`Validated at: ${report.timestamp}`);
210
- return lines.join("\n");
211
- }
212
- function formatValidationReportJSON(report) {
213
- return JSON.stringify(report, null, 2);
214
- }
215
- function formatValidationReportSARIF(report) {
216
- const results = report.incomplete.map((gap) => {
217
- const primaryMissing = gap.missing.length > 0 ? gap.missing[0] : "contract";
218
- return {
219
- ruleId: `decision-ledger/${primaryMissing}`,
220
- level: gap.severity === "error" ? "error" : gap.severity === "warning" ? "warning" : "note",
221
- message: {
222
- text: gap.message || `Missing: ${gap.missing.join(", ")}`
223
- },
224
- locations: [
225
- {
226
- physicalLocation: {
227
- artifactLocation: {
228
- uri: "registry"
229
- },
230
- region: {
231
- startLine: 1
232
- }
233
- }
234
- }
235
- ],
236
- properties: {
237
- ruleId: gap.ruleId,
238
- missing: gap.missing
239
- }
240
- };
241
- });
242
- const sarif = {
243
- version: "2.1.0",
244
- $schema: "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
245
- runs: [
246
- {
247
- tool: {
248
- driver: {
249
- name: "Praxis Decision Ledger",
250
- version: "1.0.0",
251
- informationUri: "https://github.com/plures/praxis",
252
- rules: [
253
- {
254
- id: "decision-ledger/contract",
255
- shortDescription: {
256
- text: "Rule or constraint missing contract"
257
- }
258
- },
259
- {
260
- id: "decision-ledger/behavior",
261
- shortDescription: {
262
- text: "Contract missing behavior description"
263
- }
264
- },
265
- {
266
- id: "decision-ledger/examples",
267
- shortDescription: {
268
- text: "Contract missing examples"
269
- }
270
- },
271
- {
272
- id: "decision-ledger/invariants",
273
- shortDescription: {
274
- text: "Contract missing invariants"
275
- }
276
- },
277
- {
278
- id: "decision-ledger/tests",
279
- shortDescription: {
280
- text: "Contract missing tests"
281
- }
282
- },
283
- {
284
- id: "decision-ledger/spec",
285
- shortDescription: {
286
- text: "Contract missing spec"
287
- }
288
- }
289
- ]
290
- }
291
- },
292
- results
293
- }
294
- ]
295
- };
296
- return JSON.stringify(sarif, null, 2);
297
- }
298
-
299
- // src/decision-ledger/ledger.ts
300
- var BehaviorLedger = class _BehaviorLedger {
301
- entries = [];
302
- entryMap = /* @__PURE__ */ new Map();
303
- /**
304
- * Append a new entry to the ledger.
305
- *
306
- * @param entry The entry to append
307
- * @throws Error if entry ID already exists
308
- */
309
- append(entry) {
310
- if (this.entryMap.has(entry.id)) {
311
- throw new Error(`Ledger entry with ID '${entry.id}' already exists`);
312
- }
313
- if (entry.supersedes) {
314
- const superseded = this.entryMap.get(entry.supersedes);
315
- if (superseded && superseded.status === "active") {
316
- const updatedEntry = {
317
- ...superseded,
318
- status: "superseded"
319
- };
320
- this.entryMap.set(entry.supersedes, updatedEntry);
321
- }
322
- }
323
- this.entries.push(entry);
324
- this.entryMap.set(entry.id, entry);
325
- }
326
- /**
327
- * Get an entry by ID.
328
- *
329
- * @param id The entry ID
330
- * @returns The entry, or undefined if not found
331
- */
332
- getEntry(id) {
333
- return this.entryMap.get(id);
334
- }
335
- /**
336
- * Get all entries (in order of append) with current status.
337
- *
338
- * @returns Array of all entries with current status from the map
339
- */
340
- getAllEntries() {
341
- return this.entries.map((entry) => this.entryMap.get(entry.id));
342
- }
343
- /**
344
- * Get entries for a specific rule ID.
345
- *
346
- * @param ruleId The rule ID
347
- * @returns Array of entries for this rule with current status
348
- */
349
- getEntriesForRule(ruleId) {
350
- return this.entries.map((entry) => this.entryMap.get(entry.id)).filter((entry) => entry.contract.ruleId === ruleId);
351
- }
352
- /**
353
- * Get the latest active entry for a rule.
354
- *
355
- * @param ruleId The rule ID
356
- * @returns The latest active entry, or undefined if none
357
- */
358
- getLatestEntry(ruleId) {
359
- const entries = this.getEntriesForRule(ruleId);
360
- const activeEntries = entries.filter((entry) => entry.status === "active");
361
- if (activeEntries.length === 0) {
362
- return void 0;
363
- }
364
- return activeEntries[activeEntries.length - 1];
365
- }
366
- /**
367
- * Get all active assumptions across all entries.
368
- *
369
- * @returns Map of assumption ID to assumption
370
- */
371
- getActiveAssumptions() {
372
- const assumptions = /* @__PURE__ */ new Map();
373
- for (const entry of this.entries) {
374
- const currentEntry = this.entryMap.get(entry.id);
375
- if (currentEntry.status !== "active") {
376
- continue;
377
- }
378
- for (const assumption of currentEntry.contract.assumptions || []) {
379
- if (assumption.status === "active") {
380
- assumptions.set(assumption.id, assumption);
381
- }
382
- }
383
- }
384
- return assumptions;
385
- }
386
- /**
387
- * Find assumptions that impact a specific artifact type.
388
- *
389
- * @param impactType The artifact type ('spec', 'tests', 'code')
390
- * @returns Array of assumptions
391
- */
392
- findAssumptionsByImpact(impactType) {
393
- const assumptions = [];
394
- for (const entry of this.entries) {
395
- const currentEntry = this.entryMap.get(entry.id);
396
- if (currentEntry.status !== "active") {
397
- continue;
398
- }
399
- for (const assumption of currentEntry.contract.assumptions || []) {
400
- if (assumption.status === "active" && assumption.impacts.includes(impactType)) {
401
- assumptions.push(assumption);
402
- }
403
- }
404
- }
405
- return assumptions;
406
- }
407
- /**
408
- * Get ledger statistics.
409
- */
410
- getStats() {
411
- const currentEntries = this.entries.map((e) => this.entryMap.get(e.id));
412
- const active = currentEntries.filter((e) => e.status === "active").length;
413
- const superseded = currentEntries.filter((e) => e.status === "superseded").length;
414
- const deprecated = currentEntries.filter((e) => e.status === "deprecated").length;
415
- const uniqueRules = new Set(currentEntries.map((e) => e.contract.ruleId)).size;
416
- return {
417
- totalEntries: this.entries.length,
418
- activeEntries: active,
419
- supersededEntries: superseded,
420
- deprecatedEntries: deprecated,
421
- uniqueRules
422
- };
423
- }
424
- /**
425
- * Export ledger as JSON.
426
- *
427
- * @returns JSON string with current entry status
428
- */
429
- toJSON() {
430
- return JSON.stringify(
431
- {
432
- version: "1.0.0",
433
- // Export entries with current status from the map
434
- entries: this.entries.map((entry) => this.entryMap.get(entry.id)),
435
- stats: this.getStats()
436
- },
437
- null,
438
- 2
439
- );
440
- }
441
- /**
442
- * Import ledger from JSON.
443
- *
444
- * Note: The JSON must contain entries in the order they were originally appended.
445
- * If a superseding entry appears before the entry it supersedes, the superseding
446
- * logic will not work correctly. The toJSON method preserves this order.
447
- *
448
- * @param json The JSON string
449
- * @returns A new BehaviorLedger instance
450
- */
451
- static fromJSON(json) {
452
- const data = JSON.parse(json);
453
- const ledger = new _BehaviorLedger();
454
- for (const entry of data.entries || []) {
455
- ledger.append(entry);
456
- }
457
- return ledger;
458
- }
459
- };
460
- function createBehaviorLedger() {
461
- return new BehaviorLedger();
462
- }
463
-
464
- export {
465
- defineFact,
466
- defineEvent,
467
- defineRule,
468
- defineConstraint,
469
- defineModule,
470
- filterEvents,
471
- filterFacts,
472
- findEvent,
473
- findFact,
474
- ContractMissing,
475
- ContractValidated,
476
- AcknowledgeContractGap,
477
- ValidateContracts,
478
- ContractGapAcknowledged,
479
- ContractAdded,
480
- ContractUpdated,
481
- validateContracts,
482
- formatValidationReport,
483
- formatValidationReportJSON,
484
- formatValidationReportSARIF,
485
- BehaviorLedger,
486
- createBehaviorLedger
487
- };