@plures/praxis 1.2.13 → 1.2.41

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 (85) hide show
  1. package/README.md +44 -0
  2. package/dist/browser/{chunk-VOMLVI6V.js → chunk-BBP2F7TT.js} +70 -1
  3. package/dist/browser/{chunk-K377RW4V.js → chunk-FCEH7WMH.js} +1 -1
  4. package/dist/browser/{engine-YJZV4SLD.js → engine-65QDGCAN.js} +1 -1
  5. package/dist/browser/index.d.ts +104 -2
  6. package/dist/browser/index.js +181 -5
  7. package/dist/browser/integrations/svelte.d.ts +2 -2
  8. package/dist/browser/integrations/svelte.js +2 -2
  9. package/dist/browser/{reactive-engine.svelte-9aS0kTa8.d.ts → reactive-engine.svelte-Cqd8Mod2.d.ts} +56 -1
  10. package/dist/node/{chunk-PRPQO6R5.js → chunk-32YFEEML.js} +1 -1
  11. package/dist/node/{chunk-VOMLVI6V.js → chunk-BBP2F7TT.js} +70 -1
  12. package/dist/node/{chunk-5RH7UAQC.js → chunk-PTH6MD6P.js} +1 -0
  13. package/dist/node/cli/index.cjs +1553 -839
  14. package/dist/node/cli/index.js +39 -2
  15. package/dist/node/cloud/index.d.cts +1 -1
  16. package/dist/node/cloud/index.d.ts +1 -1
  17. package/dist/node/components/index.d.cts +2 -2
  18. package/dist/node/components/index.d.ts +2 -2
  19. package/dist/node/conversations-KQBXTP3N.js +596 -0
  20. package/dist/node/{engine-2DQBKBJC.js → engine-7CXQV6RC.js} +1 -1
  21. package/dist/node/index.cjs +408 -3
  22. package/dist/node/index.d.cts +308 -7
  23. package/dist/node/index.d.ts +308 -7
  24. package/dist/node/index.js +336 -6
  25. package/dist/node/integrations/svelte.cjs +70 -1
  26. package/dist/node/integrations/svelte.d.cts +3 -3
  27. package/dist/node/integrations/svelte.d.ts +3 -3
  28. package/dist/node/integrations/svelte.js +2 -2
  29. package/dist/node/{protocol-Qek7ebBl.d.ts → protocol-BocKczNv.d.cts} +1 -1
  30. package/dist/node/{protocol-Qek7ebBl.d.cts → protocol-BocKczNv.d.ts} +1 -1
  31. package/dist/node/{reactive-engine.svelte-CRNqHlbv.d.ts → reactive-engine.svelte-CGe8SpVE.d.cts} +57 -2
  32. package/dist/node/{reactive-engine.svelte-BFIZfawz.d.cts → reactive-engine.svelte-D-xTDxT5.d.ts} +57 -2
  33. package/dist/node/{terminal-adapter-B-UK_Vdz.d.ts → terminal-adapter-CvIvgTo4.d.ts} +1 -1
  34. package/dist/node/{terminal-adapter-BQSIF5bf.d.cts → terminal-adapter-Db-snPJ3.d.cts} +1 -1
  35. package/dist/node/{validate-CNHUULQE.js → validate-EN3M4FUR.js} +1 -1
  36. package/dist/node/{verify-KLJRXVJS.js → verify-7VZRP2WS.js} +2 -2
  37. package/docs/BOT_UPDATE_POLICY.md +125 -0
  38. package/docs/DOGFOODING_CHECKLIST.md +254 -0
  39. package/docs/DOGFOODING_INDEX.md +169 -0
  40. package/docs/DOGFOODING_QUICK_START.md +140 -0
  41. package/docs/KNO_ENG_EXTRACTION_PLAN.md +577 -0
  42. package/docs/PLURES_TOOLS_INVENTORY.md +170 -0
  43. package/docs/README.md +12 -0
  44. package/docs/TESTING_BOT_WORKFLOWS.md +154 -0
  45. package/docs/conversations/INTEGRATION_POINTS.md +719 -0
  46. package/docs/conversations/README.md +168 -0
  47. package/docs/core/extending-praxis-core.md +604 -0
  48. package/docs/core/praxis-core-api.md +385 -0
  49. package/docs/decision-ledger/contract-index.json +2 -2
  50. package/docs/decision-ledger/decisions/2026-02-01-monorepo-organization.md +130 -0
  51. package/docs/examples/DOGFOODING_WORKFLOW_EXAMPLE.md +295 -0
  52. package/docs/examples/README.md +41 -0
  53. package/docs/workflows/pr-overlap-guard.md +50 -0
  54. package/package.json +7 -2
  55. package/src/__tests__/chronicle.test.ts +512 -0
  56. package/src/__tests__/conversations.test.ts +312 -0
  57. package/src/__tests__/edge-cases.test.ts +1 -1
  58. package/src/__tests__/engine-dx.test.ts +355 -0
  59. package/src/cli/commands/conversations.ts +252 -0
  60. package/src/cli/index.ts +73 -0
  61. package/src/conversations/README.md +230 -0
  62. package/src/conversations/candidate.schema.json +123 -0
  63. package/src/conversations/candidates.ts +114 -0
  64. package/src/conversations/capture.ts +56 -0
  65. package/src/conversations/classify.ts +110 -0
  66. package/src/conversations/conversation.schema.json +106 -0
  67. package/src/conversations/emitters/fs.ts +65 -0
  68. package/src/conversations/emitters/github.ts +115 -0
  69. package/src/conversations/gate.ts +102 -0
  70. package/src/conversations/index.ts +28 -0
  71. package/src/conversations/normalize.ts +51 -0
  72. package/src/conversations/redact.ts +57 -0
  73. package/src/conversations/types.ts +96 -0
  74. package/src/core/chronicle/chronicle.ts +227 -0
  75. package/src/core/chronicle/context.ts +80 -0
  76. package/src/core/chronicle/index.ts +53 -0
  77. package/src/core/chronicle/mcp.ts +135 -0
  78. package/src/core/chronicle/types.ts +61 -0
  79. package/src/core/engine.ts +99 -1
  80. package/src/core/pluresdb/index.ts +22 -0
  81. package/src/core/pluresdb/store.ts +162 -5
  82. package/src/core/rules.ts +12 -0
  83. package/src/dsl/index.ts +6 -0
  84. package/src/index.ts +18 -0
  85. package/src/integrations/pluresdb.ts +22 -0
@@ -0,0 +1,719 @@
1
+ # Integration Points: kno-eng → Praxis Conversations
2
+
3
+ **Document**: Integration Architecture
4
+ **Date**: 2026-02-01
5
+ **Status**: Planning
6
+
7
+ ## Overview
8
+
9
+ This document defines the specific integration points for refactoring kno-eng into the Praxis framework as the `conversations` module, ensuring seamless integration with existing Praxis infrastructure.
10
+
11
+ ## Integration Architecture
12
+
13
+ ### High-Level Integration Map
14
+
15
+ ```
16
+ ┌─────────────────────────────────────────────────────────────┐
17
+ │ Praxis Framework │
18
+ ├─────────────────────────────────────────────────────────────┤
19
+ │ │
20
+ │ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │
21
+ │ │ Schema │ │ Logic │ │ Component │ │
22
+ │ │ System │ │ Engine │ │ Generator │ │
23
+ │ └─────┬──────┘ └─────┬──────┘ └───────┬──────┘ │
24
+ │ │ │ │ │
25
+ │ │ │ │ │
26
+ │ ┌─────▼───────────────▼──────────────────▼──────┐ │
27
+ │ │ Conversations Module (kno-eng) │ │
28
+ │ ├───────────────────────────────────────────────┤ │
29
+ │ │ Capture │ Knowledge │ Rules │ Sync │ │
30
+ │ └─────┬─────────────┬────────────┬───────┬──────┘ │
31
+ │ │ │ │ │ │
32
+ ├────────┼─────────────┼────────────┼───────┼─────────────────┤
33
+ │ │ │ │ │ │
34
+ │ ┌─────▼──────┐ ┌────▼─────┐ ┌───▼────┐ ┌▼────────┐ │
35
+ │ │ PluresDB │ │ Unum │ │ Canvas │ │ Cloud │ │
36
+ │ └────────────┘ └──────────┘ └────────┘ └─────────┘ │
37
+ └─────────────────────────────────────────────────────────────┘
38
+ ```
39
+
40
+ ## 1. Data Layer Integration (PluresDB)
41
+
42
+ ### 1.1 Schema Definition
43
+
44
+ **Integration Point**: Praxis Schema System → PluresDB Collections
45
+
46
+ **Location**: `/src/conversations/schema/knowledge.schema.ts`
47
+
48
+ **Purpose**: Define data models for knowledge entries, threads, and relationships using Praxis schema format.
49
+
50
+ **Implementation**:
51
+
52
+ ```typescript
53
+ // /src/conversations/schema/knowledge.schema.ts
54
+ import { definePraxisSchema } from '@plures/praxis/schema';
55
+
56
+ export const conversationsSchema = definePraxisSchema({
57
+ version: '1.0.0',
58
+ name: 'praxis-conversations',
59
+
60
+ models: [
61
+ {
62
+ name: 'KnowledgeEntry',
63
+ description: 'Individual knowledge capture entry',
64
+ fields: [
65
+ { name: 'id', type: 'uuid', primary: true },
66
+ { name: 'type', type: 'string', required: true },
67
+ { name: 'title', type: 'string', required: true },
68
+ { name: 'content', type: 'string', required: true },
69
+ { name: 'tags', type: { array: 'string' }, default: [] },
70
+
71
+ // Code context
72
+ { name: 'filePath', type: 'string', optional: true },
73
+ { name: 'lineNumber', type: 'number', optional: true },
74
+ { name: 'commitSha', type: 'string', optional: true },
75
+
76
+ // Metadata
77
+ { name: 'createdBy', type: 'string', required: true },
78
+ { name: 'createdAt', type: 'datetime', default: 'now' },
79
+ { name: 'updatedAt', type: 'datetime', default: 'now' },
80
+
81
+ // Relationships
82
+ { name: 'relatedTo', type: { array: 'string' }, default: [] },
83
+ { name: 'threadId', type: 'string', optional: true },
84
+ ],
85
+ indexes: [
86
+ { fields: ['createdBy'], type: 'standard' },
87
+ { fields: ['createdAt'], sort: 'desc' },
88
+ { fields: ['tags'], type: 'multikey' },
89
+ { fields: ['filePath'], type: 'standard' },
90
+ ],
91
+ },
92
+
93
+ {
94
+ name: 'ConversationThread',
95
+ description: 'Threaded discussions around knowledge',
96
+ fields: [
97
+ { name: 'id', type: 'uuid', primary: true },
98
+ { name: 'topic', type: 'string', required: true },
99
+ { name: 'participants', type: { array: 'string' }, default: [] },
100
+ { name: 'entries', type: { array: 'string' }, default: [] },
101
+ { name: 'status', type: 'string', default: 'active' },
102
+ { name: 'createdAt', type: 'datetime', default: 'now' },
103
+ { name: 'updatedAt', type: 'datetime', default: 'now' },
104
+ ],
105
+ indexes: [
106
+ { fields: ['status', 'updatedAt'], sort: 'desc' },
107
+ ],
108
+ },
109
+
110
+ {
111
+ name: 'KnowledgeLink',
112
+ description: 'Relationships between knowledge entries',
113
+ fields: [
114
+ { name: 'id', type: 'uuid', primary: true },
115
+ { name: 'fromId', type: 'string', required: true },
116
+ { name: 'toId', type: 'string', required: true },
117
+ { name: 'type', type: 'string', required: true },
118
+ { name: 'strength', type: 'number', default: 1.0 },
119
+ ],
120
+ indexes: [
121
+ { fields: ['fromId'], type: 'standard' },
122
+ { fields: ['toId'], type: 'standard' },
123
+ ],
124
+ },
125
+ ],
126
+ });
127
+ ```
128
+
129
+ **Integration Benefits**:
130
+ - Leverages PluresDB's local-first storage
131
+ - Automatic CRDT conflict resolution
132
+ - Reactive queries for UI updates
133
+ - Built-in indexing for fast search
134
+
135
+ ### 1.2 Database Initialization
136
+
137
+ **Integration Point**: PluresDB Adapter → Conversations Engine
138
+
139
+ **Location**: `/src/conversations/core/db.ts`
140
+
141
+ **Implementation**:
142
+
143
+ ```typescript
144
+ // /src/conversations/core/db.ts
145
+ import { createPraxisLocalFirst } from '@plures/praxis';
146
+ import { conversationsSchema } from '../schema/knowledge.schema';
147
+
148
+ export async function createKnowledgeDB(options = {}) {
149
+ const db = await createPraxisLocalFirst({
150
+ mode: options.mode || 'auto',
151
+ dbName: options.dbName || 'praxis-knowledge',
152
+ schema: conversationsSchema,
153
+ sync: options.sync || { enabled: false },
154
+ });
155
+
156
+ return db;
157
+ }
158
+ ```
159
+
160
+ ## 2. Logic Engine Integration
161
+
162
+ ### 2.1 Facts and Events
163
+
164
+ **Integration Point**: Praxis Logic Engine → Knowledge Processing
165
+
166
+ **Location**: `/src/conversations/core/facts.ts`
167
+
168
+ **Implementation**:
169
+
170
+ ```typescript
171
+ // /src/conversations/core/facts.ts
172
+ import { defineFact, defineEvent } from '@plures/praxis';
173
+
174
+ // Facts
175
+ export const KnowledgeCaptured = defineFact<'KnowledgeCaptured', {
176
+ entry: KnowledgeEntry;
177
+ }>('KnowledgeCaptured');
178
+
179
+ export const EntryTagged = defineFact<'EntryTagged', {
180
+ entryId: string;
181
+ tags: string[];
182
+ }>('EntryTagged');
183
+
184
+ export const EntriesLinked = defineFact<'EntriesLinked', {
185
+ fromId: string;
186
+ toId: string;
187
+ type: string;
188
+ strength: number;
189
+ }>('EntriesLinked');
190
+
191
+ // Events
192
+ export const CaptureKnowledge = defineEvent<'CAPTURE_KNOWLEDGE', {
193
+ type: string;
194
+ title: string;
195
+ content: string;
196
+ context?: CodeContext;
197
+ }>('CAPTURE_KNOWLEDGE');
198
+
199
+ export const SearchKnowledge = defineEvent<'SEARCH_KNOWLEDGE', {
200
+ query: string;
201
+ filters?: SearchFilters;
202
+ }>('SEARCH_KNOWLEDGE');
203
+ ```
204
+
205
+ ### 2.2 Processing Rules
206
+
207
+ **Integration Point**: Praxis Rules → Auto-tagging and Linking
208
+
209
+ **Location**: `/src/conversations/rules/`
210
+
211
+ **Implementation**:
212
+
213
+ ```typescript
214
+ // /src/conversations/rules/auto-tag.ts
215
+ import { defineRule } from '@plures/praxis';
216
+ import { KnowledgeCaptured, EntryTagged } from '../core/facts';
217
+
218
+ export const autoTagRule = defineRule({
219
+ id: 'conversations.auto-tag',
220
+ description: 'Automatically extract tags from knowledge content',
221
+ impl: (state, events) => {
222
+ const captured = events.find(KnowledgeCaptured.is);
223
+ if (!captured) return [];
224
+
225
+ const entry = captured.payload.entry;
226
+ const extractedTags = extractTags(entry.content, entry.title);
227
+
228
+ return [
229
+ EntryTagged.create({
230
+ entryId: entry.id,
231
+ tags: extractedTags,
232
+ })
233
+ ];
234
+ },
235
+ });
236
+
237
+ // /src/conversations/rules/smart-link.ts
238
+ import { defineRule } from '@plures/praxis';
239
+ import { KnowledgeCaptured, EntriesLinked } from '../core/facts';
240
+
241
+ export const smartLinkRule = defineRule({
242
+ id: 'conversations.smart-link',
243
+ description: 'Automatically detect and link related knowledge',
244
+ impl: (state, events) => {
245
+ const captured = events.find(KnowledgeCaptured.is);
246
+ if (!captured) return [];
247
+
248
+ const entry = captured.payload.entry;
249
+ const existingEntries = state.context.knowledgeEntries || [];
250
+
251
+ // Find related entries using similarity
252
+ const related = findRelatedEntries(entry, existingEntries);
253
+
254
+ return related.map(({ id, score }) =>
255
+ EntriesLinked.create({
256
+ fromId: entry.id,
257
+ toId: id,
258
+ type: 'relates-to',
259
+ strength: score,
260
+ })
261
+ );
262
+ },
263
+ });
264
+ ```
265
+
266
+ ### 2.3 Registry Integration
267
+
268
+ **Integration Point**: Praxis Registry → Conversations Rules
269
+
270
+ **Location**: `/src/conversations/core/registry.ts`
271
+
272
+ **Implementation**:
273
+
274
+ ```typescript
275
+ // /src/conversations/core/registry.ts
276
+ import { PraxisRegistry } from '@plures/praxis';
277
+ import { autoTagRule } from '../rules/auto-tag';
278
+ import { smartLinkRule } from '../rules/smart-link';
279
+
280
+ export function createConversationsRegistry(): PraxisRegistry {
281
+ const registry = new PraxisRegistry();
282
+
283
+ // Register all conversation rules
284
+ registry.registerRule(autoTagRule);
285
+ registry.registerRule(smartLinkRule);
286
+ // ... more rules
287
+
288
+ return registry;
289
+ }
290
+ ```
291
+
292
+ ## 3. UI Component Integration
293
+
294
+ ### 3.1 Svelte Component Generation
295
+
296
+ **Integration Point**: Praxis Component Generator → Conversations UI
297
+
298
+ **Location**: `/src/conversations/components/`
299
+
300
+ **Implementation**:
301
+
302
+ ```typescript
303
+ // Generate components from schema
304
+ import { generateComponents } from '@plures/praxis/component';
305
+ import { conversationsSchema } from '../schema/knowledge.schema';
306
+
307
+ const components = generateComponents({
308
+ schema: conversationsSchema,
309
+ target: 'svelte5',
310
+ theme: 'praxis-default',
311
+ });
312
+
313
+ // Generated components:
314
+ // - KnowledgeEntryEditor.svelte
315
+ // - ConversationThreadView.svelte
316
+ // - KnowledgeSearchBar.svelte
317
+ ```
318
+
319
+ ### 3.2 Custom Components
320
+
321
+ **Location**: `/src/conversations/components/`
322
+
323
+ **Custom Components** (not auto-generated):
324
+
325
+ ```svelte
326
+ <!-- /src/conversations/components/QuickCapture.svelte -->
327
+ <script lang="ts">
328
+ import { createEventDispatcher } from 'svelte';
329
+ import type { KnowledgeCaptureEngine } from '../core/engine';
330
+
331
+ export let engine: KnowledgeCaptureEngine;
332
+
333
+ let title = '';
334
+ let content = '';
335
+ let type = 'note';
336
+
337
+ const dispatch = createEventDispatcher();
338
+
339
+ async function capture() {
340
+ const entry = await engine.capture({
341
+ type,
342
+ title,
343
+ content,
344
+ context: await extractCurrentContext(),
345
+ });
346
+
347
+ dispatch('captured', entry);
348
+ // Reset form
349
+ title = '';
350
+ content = '';
351
+ }
352
+ </script>
353
+
354
+ <div class="quick-capture">
355
+ <select bind:value={type}>
356
+ <option value="note">Note</option>
357
+ <option value="decision">Decision</option>
358
+ <option value="pattern">Pattern</option>
359
+ <option value="bug">Bug</option>
360
+ </select>
361
+
362
+ <input
363
+ bind:value={title}
364
+ placeholder="Title..."
365
+ />
366
+
367
+ <textarea
368
+ bind:value={content}
369
+ placeholder="Capture your thoughts..."
370
+ />
371
+
372
+ <button on:click={capture}>Capture</button>
373
+ </div>
374
+ ```
375
+
376
+ ## 4. CLI Integration
377
+
378
+ ### 4.1 Command Registration
379
+
380
+ **Integration Point**: Praxis CLI → Knowledge Commands
381
+
382
+ **Location**: `/src/cli/commands/knowledge.ts`
383
+
384
+ **Implementation**:
385
+
386
+ ```typescript
387
+ // /src/cli/commands/knowledge.ts
388
+ import { Command } from 'commander';
389
+ import { createKnowledgeDB, KnowledgeCaptureEngine } from '../../conversations';
390
+
391
+ export function registerKnowledgeCommands(program: Command) {
392
+ const knowledge = program
393
+ .command('knowledge')
394
+ .description('Knowledge capture and management');
395
+
396
+ knowledge
397
+ .command('capture <content>')
398
+ .option('-t, --title <title>', 'Entry title')
399
+ .option('--type <type>', 'Entry type (note, decision, pattern, bug)', 'note')
400
+ .option('--tags <tags>', 'Comma-separated tags')
401
+ .action(async (content, options) => {
402
+ const db = await createKnowledgeDB();
403
+ const engine = new KnowledgeCaptureEngine({ db });
404
+
405
+ const entry = await engine.capture({
406
+ type: options.type,
407
+ title: options.title || content.substring(0, 50),
408
+ content,
409
+ tags: options.tags ? options.tags.split(',') : [],
410
+ });
411
+
412
+ console.log(`Captured: ${entry.id}`);
413
+ });
414
+
415
+ knowledge
416
+ .command('search <query>')
417
+ .option('--type <type>', 'Filter by type')
418
+ .option('--tags <tags>', 'Filter by tags')
419
+ .action(async (query, options) => {
420
+ const db = await createKnowledgeDB();
421
+ const engine = new KnowledgeCaptureEngine({ db });
422
+
423
+ const results = await engine.search(query, {
424
+ type: options.type,
425
+ tags: options.tags ? options.tags.split(',') : undefined,
426
+ });
427
+
428
+ console.log(`Found ${results.length} entries:`);
429
+ results.forEach(r => console.log(` ${r.title} (${r.type})`));
430
+ });
431
+
432
+ knowledge
433
+ .command('export')
434
+ .option('-f, --format <format>', 'Export format (json, markdown, html)', 'json')
435
+ .option('-o, --output <path>', 'Output path')
436
+ .action(async (options) => {
437
+ const db = await createKnowledgeDB();
438
+ const engine = new KnowledgeCaptureEngine({ db });
439
+
440
+ await engine.export({
441
+ format: options.format,
442
+ outputPath: options.output,
443
+ });
444
+
445
+ console.log(`Exported to ${options.output}`);
446
+ });
447
+ }
448
+ ```
449
+
450
+ ### 4.2 CLI Entry Point
451
+
452
+ **Integration Point**: Main CLI → Knowledge Commands
453
+
454
+ **Location**: `/src/cli/index.ts`
455
+
456
+ **Implementation**:
457
+
458
+ ```typescript
459
+ // /src/cli/index.ts
460
+ import { Command } from 'commander';
461
+ import { registerKnowledgeCommands } from './commands/knowledge';
462
+
463
+ const program = new Command();
464
+
465
+ // ... existing commands
466
+
467
+ // Register knowledge commands
468
+ registerKnowledgeCommands(program);
469
+
470
+ program.parse();
471
+ ```
472
+
473
+ ## 5. Sync Integration
474
+
475
+ ### 5.1 PluresDB Sync Configuration
476
+
477
+ **Integration Point**: PluresDB Sync → Praxis Cloud
478
+
479
+ **Location**: `/src/conversations/sync/adapter.ts`
480
+
481
+ **Implementation**:
482
+
483
+ ```typescript
484
+ // /src/conversations/sync/adapter.ts
485
+ import { createPluresDBAdapter } from '@plures/praxis/adapters';
486
+
487
+ export async function createConversationsSyncAdapter(db, options = {}) {
488
+ return createPluresDBAdapter({
489
+ db,
490
+ collections: ['KnowledgeEntry', 'ConversationThread', 'KnowledgeLink'],
491
+ sync: {
492
+ enabled: options.enabled !== false,
493
+ endpoint: options.endpoint || process.env.PRAXIS_CLOUD_URL,
494
+ authToken: options.authToken || process.env.PRAXIS_AUTH_TOKEN,
495
+ autoSync: options.autoSync !== false,
496
+ syncInterval: options.syncInterval || 5000,
497
+ },
498
+ });
499
+ }
500
+ ```
501
+
502
+ ### 5.2 Conflict Resolution
503
+
504
+ **Integration Point**: PluresDB CRDT → Knowledge Merging
505
+
506
+ **Implementation**:
507
+
508
+ ```typescript
509
+ // Use PluresDB's built-in CRDT resolution
510
+ // No custom code needed - PluresDB handles it automatically
511
+
512
+ // For custom merge logic (if needed):
513
+ const db = await createKnowledgeDB({
514
+ sync: {
515
+ conflictResolution: 'custom',
516
+ resolveConflict: (local, remote, base) => {
517
+ // Custom merge logic for knowledge entries
518
+ return {
519
+ ...base,
520
+ ...remote,
521
+ ...local,
522
+ // Merge tags (union)
523
+ tags: [...new Set([...local.tags, ...remote.tags])],
524
+ // Merge relatedTo (union)
525
+ relatedTo: [...new Set([...local.relatedTo, ...remote.relatedTo])],
526
+ mergedAt: new Date(),
527
+ };
528
+ },
529
+ },
530
+ });
531
+ ```
532
+
533
+ ## 6. IDE Extension Integration
534
+
535
+ ### 6.1 VS Code Extension Architecture
536
+
537
+ **Integration Point**: VS Code Extension API → Praxis Conversations Engine
538
+
539
+ **Location**: `/extensions/vscode/`
540
+
541
+ **Implementation**:
542
+
543
+ ```typescript
544
+ // /extensions/vscode/src/extension.ts
545
+ import * as vscode from 'vscode';
546
+ import { createKnowledgeDB, KnowledgeCaptureEngine } from '@plures/praxis/conversations';
547
+
548
+ let engine: KnowledgeCaptureEngine;
549
+
550
+ export async function activate(context: vscode.ExtensionContext) {
551
+ // Initialize Praxis knowledge database
552
+ const db = await createKnowledgeDB({
553
+ mode: 'auto',
554
+ dbName: 'vscode-praxis-knowledge',
555
+ });
556
+
557
+ engine = new KnowledgeCaptureEngine({ db });
558
+
559
+ // Register command: Quick Capture
560
+ const captureCommand = vscode.commands.registerCommand(
561
+ 'praxis.captureKnowledge',
562
+ async () => {
563
+ const editor = vscode.window.activeTextEditor;
564
+
565
+ const title = await vscode.window.showInputBox({
566
+ prompt: 'Knowledge entry title',
567
+ placeHolder: 'Enter a title...',
568
+ });
569
+
570
+ if (!title) return;
571
+
572
+ const content = await vscode.window.showInputBox({
573
+ prompt: 'Content',
574
+ placeHolder: 'Capture your thoughts...',
575
+ });
576
+
577
+ if (!content) return;
578
+
579
+ const entry = await engine.capture({
580
+ type: 'note',
581
+ title,
582
+ content,
583
+ context: editor ? {
584
+ filePath: editor.document.fileName,
585
+ lineNumber: editor.selection.active.line + 1,
586
+ selectedCode: editor.document.getText(editor.selection),
587
+ } : undefined,
588
+ });
589
+
590
+ vscode.window.showInformationMessage(`Captured: ${entry.title}`);
591
+ }
592
+ );
593
+
594
+ // Register command: Search
595
+ const searchCommand = vscode.commands.registerCommand(
596
+ 'praxis.searchKnowledge',
597
+ async () => {
598
+ const query = await vscode.window.showInputBox({
599
+ prompt: 'Search knowledge',
600
+ placeHolder: 'Enter search query...',
601
+ });
602
+
603
+ if (!query) return;
604
+
605
+ const results = await engine.search(query);
606
+
607
+ // Show results in Quick Pick
608
+ const selected = await vscode.window.showQuickPick(
609
+ results.map(r => ({
610
+ label: r.title,
611
+ description: r.type,
612
+ detail: r.content.substring(0, 100),
613
+ entry: r,
614
+ })),
615
+ { placeHolder: `Found ${results.length} entries` }
616
+ );
617
+
618
+ if (selected) {
619
+ // Open entry editor or navigate to code location
620
+ if (selected.entry.context?.filePath) {
621
+ const doc = await vscode.workspace.openTextDocument(
622
+ selected.entry.context.filePath
623
+ );
624
+ const editor = await vscode.window.showTextDocument(doc);
625
+ if (selected.entry.context.lineNumber) {
626
+ const line = selected.entry.context.lineNumber - 1;
627
+ editor.selection = new vscode.Selection(line, 0, line, 0);
628
+ editor.revealRange(new vscode.Range(line, 0, line, 0));
629
+ }
630
+ }
631
+ }
632
+ }
633
+ );
634
+
635
+ context.subscriptions.push(captureCommand, searchCommand);
636
+ }
637
+ ```
638
+
639
+ ## 7. Testing Integration
640
+
641
+ ### 7.1 Test Infrastructure
642
+
643
+ **Integration Point**: Praxis Test Utils → Conversations Tests
644
+
645
+ **Location**: `/src/conversations/__tests__/`
646
+
647
+ **Implementation**:
648
+
649
+ ```typescript
650
+ // /src/conversations/__tests__/capture.test.ts
651
+ import { describe, it, expect, beforeEach } from 'vitest';
652
+ import { createKnowledgeDB, KnowledgeCaptureEngine } from '../core';
653
+
654
+ describe('KnowledgeCaptureEngine', () => {
655
+ let db;
656
+ let engine;
657
+
658
+ beforeEach(async () => {
659
+ db = await createKnowledgeDB({ mode: 'memory' }); // In-memory for tests
660
+ engine = new KnowledgeCaptureEngine({ db });
661
+ });
662
+
663
+ it('should capture knowledge with context', async () => {
664
+ const entry = await engine.capture({
665
+ type: 'decision',
666
+ title: 'Test decision',
667
+ content: 'Test content',
668
+ context: {
669
+ filePath: '/test.ts',
670
+ lineNumber: 42,
671
+ },
672
+ });
673
+
674
+ expect(entry.id).toBeDefined();
675
+ expect(entry.title).toBe('Test decision');
676
+ expect(entry.context.filePath).toBe('/test.ts');
677
+ });
678
+
679
+ it('should search knowledge by content', async () => {
680
+ await engine.capture({
681
+ type: 'note',
682
+ title: 'React patterns',
683
+ content: 'Using hooks for state management',
684
+ });
685
+
686
+ const results = await engine.search('hooks');
687
+
688
+ expect(results).toHaveLength(1);
689
+ expect(results[0].title).toBe('React patterns');
690
+ });
691
+ });
692
+ ```
693
+
694
+ ## Summary: Integration Points
695
+
696
+ | Component | Integration Point | Location | Status |
697
+ |-----------|------------------|----------|--------|
698
+ | Data Storage | PluresDB collections | `/src/conversations/schema/` | Planned |
699
+ | Logic Processing | Praxis rules & events | `/src/conversations/rules/` | Planned |
700
+ | UI Components | Svelte 5 components | `/src/conversations/components/` | Planned |
701
+ | CLI Commands | Praxis CLI | `/src/cli/commands/knowledge.ts` | Planned |
702
+ | Sync | PluresDB + Praxis Cloud | `/src/conversations/sync/` | Planned |
703
+ | IDE Extension | VS Code extension | `/extensions/vscode/` | Planned |
704
+ | Testing | Vitest tests | `/src/conversations/__tests__/` | Planned |
705
+
706
+ ## Next Steps
707
+
708
+ 1. **Phase 1**: Implement data layer (PluresDB schemas)
709
+ 2. **Phase 2**: Implement logic layer (rules and events)
710
+ 3. **Phase 3**: Implement CLI commands
711
+ 4. **Phase 4**: Build VS Code extension
712
+ 5. **Phase 5**: Generate UI components
713
+ 6. **Phase 6**: Integration testing
714
+
715
+ ---
716
+
717
+ **Document Version**: 1.0
718
+ **Last Updated**: 2026-02-01
719
+ **Review Status**: Pending stakeholder approval