sqlew 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -92,505 +92,126 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
92
92
  return {
93
93
  tools: [
94
94
  {
95
- name: 'set_decision',
96
- description: 'Set or update a decision in the shared context. Auto-detects numeric vs string values. Supports tags, layers, scopes, and version tracking.',
95
+ name: 'decision',
96
+ description: 'Manage decisions (actions: set, get, list, search_tags, search_layer, versions)',
97
97
  inputSchema: {
98
98
  type: 'object',
99
99
  properties: {
100
- key: {
100
+ action: {
101
101
  type: 'string',
102
- description: 'Unique key for the decision (e.g., "auth_method", "max_connections")',
103
- },
104
- value: {
105
- type: ['string', 'number'],
106
- description: 'Decision value (string or numeric). Numeric values are stored in optimized table.',
107
- },
108
- agent: {
109
- type: 'string',
110
- description: 'Name of the agent making the decision (defaults to "system")',
111
- },
112
- layer: {
113
- type: 'string',
114
- description: 'Architecture layer (presentation, business, data, infrastructure, cross-cutting)',
115
- enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'],
116
- },
117
- version: {
118
- type: 'string',
119
- description: 'Version identifier (defaults to "1.0.0"). Used for change tracking.',
120
- },
121
- status: {
122
- type: 'string',
123
- description: 'Decision status (defaults to "active")',
124
- enum: ['active', 'deprecated', 'draft'],
125
- },
126
- tags: {
127
- type: 'array',
128
- items: { type: 'string' },
129
- description: 'Tags for categorization (e.g., ["authentication", "security"])',
130
- },
131
- scopes: {
132
- type: 'array',
133
- items: { type: 'string' },
134
- description: 'Module or component scopes (e.g., ["user-service", "api"])',
135
- },
136
- },
137
- required: ['key', 'value'],
138
- },
139
- },
140
- {
141
- name: 'get_context',
142
- description: 'Retrieve decisions with advanced filtering. Returns token-efficient view with all metadata. Supports filtering by status, layer, tags, and scope.',
143
- inputSchema: {
144
- type: 'object',
145
- properties: {
146
- status: {
147
- type: 'string',
148
- description: 'Filter by decision status',
149
- enum: ['active', 'deprecated', 'draft'],
102
+ description: 'Action (use "help" for detailed usage)',
103
+ enum: ['set', 'get', 'list', 'search_tags', 'search_layer', 'versions', 'help']
150
104
  },
105
+ key: { type: 'string', description: 'Key' },
106
+ value: { type: ['string', 'number'], description: 'Value' },
107
+ agent: { type: 'string', description: 'Agent' },
151
108
  layer: {
152
109
  type: 'string',
153
- description: 'Filter by architecture layer',
110
+ description: 'Layer',
154
111
  enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'],
155
112
  },
156
- tags: {
157
- type: 'array',
158
- items: { type: 'string' },
159
- description: 'Filter by tags (use tag_match to control AND/OR logic)',
160
- },
161
- scope: {
162
- type: 'string',
163
- description: 'Filter by specific scope/module',
164
- },
165
- tag_match: {
166
- type: 'string',
167
- description: 'Tag matching mode: "AND" (all tags required) or "OR" (any tag)',
168
- enum: ['AND', 'OR'],
169
- default: 'OR',
170
- },
171
- },
172
- },
173
- },
174
- {
175
- name: 'get_decision',
176
- description: 'Get a specific decision by key. Returns full metadata including tags, layer, scopes, version, and timestamp.',
177
- inputSchema: {
178
- type: 'object',
179
- properties: {
180
- key: {
181
- type: 'string',
182
- description: 'Decision key to retrieve',
183
- },
184
- },
185
- required: ['key'],
186
- },
187
- },
188
- {
189
- name: 'search_by_tags',
190
- description: 'Search for decisions by tags with AND/OR logic. Supports flexible tag-based filtering with optional status and layer filters.',
191
- inputSchema: {
192
- type: 'object',
193
- properties: {
194
- tags: {
195
- type: 'array',
196
- items: { type: 'string' },
197
- description: 'Array of tags to search for (at least one required)',
198
- },
199
- match_mode: {
200
- type: 'string',
201
- description: 'Tag matching mode: "AND" (all tags required) or "OR" (any tag)',
202
- enum: ['AND', 'OR'],
203
- default: 'OR',
204
- },
113
+ version: { type: 'string', description: 'Version' },
205
114
  status: {
206
115
  type: 'string',
207
- description: 'Optional filter by decision status',
116
+ description: 'Status',
208
117
  enum: ['active', 'deprecated', 'draft'],
209
118
  },
210
- layer: {
211
- type: 'string',
212
- description: 'Optional filter by architecture layer',
213
- enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'],
214
- },
215
- },
216
- required: ['tags'],
217
- },
218
- },
219
- {
220
- name: 'get_versions',
221
- description: 'Get version history for a specific decision key. Returns all historical versions ordered by timestamp (newest first).',
222
- inputSchema: {
223
- type: 'object',
224
- properties: {
225
- key: {
226
- type: 'string',
227
- description: 'Decision key to get version history for',
228
- },
229
- },
230
- required: ['key'],
231
- },
232
- },
233
- {
234
- name: 'search_by_layer',
235
- description: 'Search for decisions within a specific architecture layer. Supports status filtering and optional tag inclusion.',
236
- inputSchema: {
237
- type: 'object',
238
- properties: {
239
- layer: {
240
- type: 'string',
241
- description: 'Architecture layer to search in',
242
- enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'],
243
- },
244
- status: {
245
- type: 'string',
246
- description: 'Filter by decision status (defaults to "active")',
247
- enum: ['active', 'deprecated', 'draft'],
248
- default: 'active',
249
- },
250
- include_tags: {
251
- type: 'boolean',
252
- description: 'Include tag information in results (defaults to true)',
253
- default: true,
254
- },
255
- },
256
- required: ['layer'],
257
- },
258
- },
259
- {
260
- name: 'send_message',
261
- description: 'Send a message from one agent to another (or broadcast to all). Supports priority levels and optional JSON payload.',
262
- inputSchema: {
263
- type: 'object',
264
- properties: {
265
- from_agent: {
266
- type: 'string',
267
- description: 'Name of the sending agent',
268
- },
269
- to_agent: {
270
- type: ['string', 'null'],
271
- description: 'Name of the receiving agent (null or omit for broadcast)',
272
- },
273
- msg_type: {
274
- type: 'string',
275
- description: 'Type of message',
276
- enum: ['decision', 'warning', 'request', 'info'],
277
- },
278
- message: {
279
- type: 'string',
280
- description: 'The message content',
281
- },
282
- priority: {
283
- type: 'string',
284
- description: 'Message priority level (defaults to "medium")',
285
- enum: ['low', 'medium', 'high', 'critical'],
286
- default: 'medium',
287
- },
288
- payload: {
289
- type: 'object',
290
- description: 'Optional JSON payload with additional data',
291
- },
292
- },
293
- required: ['from_agent', 'msg_type', 'message'],
294
- },
295
- },
296
- {
297
- name: 'get_messages',
298
- description: 'Retrieve messages for an agent. Returns messages addressed to the agent or broadcast messages. Supports filtering by read status, priority, and message type.',
299
- inputSchema: {
300
- type: 'object',
301
- properties: {
302
- agent_name: {
303
- type: 'string',
304
- description: 'Name of the agent to retrieve messages for',
305
- },
306
- unread_only: {
307
- type: 'boolean',
308
- description: 'Only return unread messages (defaults to false)',
309
- default: false,
310
- },
311
- priority_filter: {
312
- type: 'string',
313
- description: 'Filter by specific priority level',
314
- enum: ['low', 'medium', 'high', 'critical'],
315
- },
316
- msg_type_filter: {
317
- type: 'string',
318
- description: 'Filter by message type',
319
- enum: ['decision', 'warning', 'request', 'info'],
320
- },
321
- limit: {
322
- type: 'number',
323
- description: 'Maximum number of messages to return (defaults to 50)',
324
- default: 50,
325
- },
326
- },
327
- required: ['agent_name'],
328
- },
329
- },
330
- {
331
- name: 'mark_read',
332
- description: 'Mark messages as read. Only marks messages addressed to the specified agent (security check). Idempotent operation.',
333
- inputSchema: {
334
- type: 'object',
335
- properties: {
336
- message_ids: {
337
- type: 'array',
338
- items: { type: 'number' },
339
- description: 'Array of message IDs to mark as read',
340
- },
341
- agent_name: {
342
- type: 'string',
343
- description: 'Name of the agent marking messages as read',
344
- },
119
+ tags: { type: 'array', items: { type: 'string' }, description: 'Tags' },
120
+ scopes: { type: 'array', items: { type: 'string' }, description: 'Scopes' },
121
+ scope: { type: 'string', description: 'Scope' },
122
+ tag_match: { type: 'string', enum: ['AND', 'OR'], default: 'OR' },
123
+ include_tags: { type: 'boolean', default: true },
345
124
  },
346
- required: ['message_ids', 'agent_name'],
125
+ required: ['action'],
347
126
  },
348
127
  },
349
128
  {
350
- name: 'record_file_change',
351
- description: 'Record a file change with optional layer assignment and description. Auto-registers the file and agent. Useful for tracking file modifications across agents.',
129
+ name: 'message',
130
+ description: 'Agent messaging (actions: send, get, mark_read)',
352
131
  inputSchema: {
353
132
  type: 'object',
354
133
  properties: {
355
- file_path: {
356
- type: 'string',
357
- description: 'The file path (absolute or relative)',
358
- },
359
- agent_name: {
360
- type: 'string',
361
- description: 'Name of the agent making the change',
362
- },
363
- change_type: {
364
- type: 'string',
365
- description: 'Type of change made to the file',
366
- enum: ['created', 'modified', 'deleted'],
367
- },
368
- layer: {
369
- type: 'string',
370
- description: 'Optional architecture layer assignment',
371
- enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'],
372
- },
373
- description: {
374
- type: 'string',
375
- description: 'Optional description of the change',
376
- },
134
+ action: { type: 'string', description: 'Action (use "help" for usage)', enum: ['send', 'get', 'mark_read', 'help'] },
135
+ agent_name: { type: 'string' },
136
+ from_agent: { type: 'string' },
137
+ to_agent: { type: ['string', 'null'] },
138
+ msg_type: { type: 'string', enum: ['decision', 'warning', 'request', 'info'] },
139
+ message: { type: 'string' },
140
+ priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium' },
141
+ payload: { type: 'object' },
142
+ message_ids: { type: 'array', items: { type: 'number' } },
143
+ unread_only: { type: 'boolean', default: false },
144
+ msg_type_filter: { type: 'string', enum: ['decision', 'warning', 'request', 'info'] },
145
+ priority_filter: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
146
+ limit: { type: 'number', default: 50 },
377
147
  },
378
- required: ['file_path', 'agent_name', 'change_type'],
148
+ required: ['action'],
379
149
  },
380
150
  },
381
151
  {
382
- name: 'get_file_changes',
383
- description: 'Retrieve file changes with advanced filtering. Supports filtering by file, agent, layer, change type, and time range. Returns token-efficient view when no filters applied.',
152
+ name: 'file',
153
+ description: 'File change tracking (actions: record, get, check_lock)',
384
154
  inputSchema: {
385
155
  type: 'object',
386
156
  properties: {
387
- file_path: {
388
- type: 'string',
389
- description: 'Filter by specific file path',
390
- },
391
- agent_name: {
392
- type: 'string',
393
- description: 'Filter by agent who made the change',
394
- },
395
- layer: {
396
- type: 'string',
397
- description: 'Filter by architecture layer',
398
- enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'],
399
- },
400
- change_type: {
401
- type: 'string',
402
- description: 'Filter by type of change',
403
- enum: ['created', 'modified', 'deleted'],
404
- },
405
- since: {
406
- type: 'string',
407
- description: 'ISO 8601 timestamp - return changes since this time',
408
- },
409
- limit: {
410
- type: 'number',
411
- description: 'Maximum number of changes to return (default: 100)',
412
- default: 100,
413
- },
157
+ action: { type: 'string', description: 'Action (use "help" for usage)', enum: ['record', 'get', 'check_lock', 'help'] },
158
+ file_path: { type: 'string' },
159
+ agent_name: { type: 'string' },
160
+ change_type: { type: 'string', enum: ['created', 'modified', 'deleted'] },
161
+ layer: { type: 'string', enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'] },
162
+ description: { type: 'string' },
163
+ since: { type: 'string' },
164
+ limit: { type: 'number' },
165
+ lock_duration: { type: 'number' },
414
166
  },
167
+ required: ['action'],
415
168
  },
416
169
  },
417
170
  {
418
- name: 'check_file_lock',
419
- description: 'Check if a file is "locked" (recently modified). Useful to prevent concurrent edits by multiple agents. Returns lock status with details of last change.',
171
+ name: 'constraint',
172
+ description: 'Constraint management (actions: add, get, deactivate)',
420
173
  inputSchema: {
421
174
  type: 'object',
422
175
  properties: {
423
- file_path: {
424
- type: 'string',
425
- description: 'The file path to check',
426
- },
427
- lock_duration: {
428
- type: 'number',
429
- description: 'Time window in seconds to consider "locked" (default: 300 = 5 minutes)',
430
- default: 300,
431
- },
176
+ action: { type: 'string', description: 'Action (use "help" for usage)', enum: ['add', 'get', 'deactivate', 'help'] },
177
+ constraint_id: { type: 'number' },
178
+ category: { type: 'string', enum: ['performance', 'architecture', 'security'] },
179
+ constraint_text: { type: 'string' },
180
+ priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium' },
181
+ layer: { type: 'string', enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'] },
182
+ tags: { type: 'array', items: { type: 'string' } },
183
+ created_by: { type: 'string' },
184
+ active_only: { type: 'boolean', default: true },
185
+ limit: { type: 'number', default: 50 },
432
186
  },
433
- required: ['file_path'],
187
+ required: ['action'],
434
188
  },
435
189
  },
436
190
  {
437
- name: 'add_constraint',
438
- description: 'Add a constraint with priority level, optional layer assignment, and tags. Categories: performance, architecture, security. Auto-registers category and agent.',
191
+ name: 'stats',
192
+ description: 'Statistics and data cleanup (actions: layer_summary, db_stats, clear)',
439
193
  inputSchema: {
440
194
  type: 'object',
441
195
  properties: {
442
- category: {
443
- type: 'string',
444
- description: 'Constraint category',
445
- enum: ['performance', 'architecture', 'security'],
446
- },
447
- constraint_text: {
448
- type: 'string',
449
- description: 'The constraint description/requirement',
450
- },
451
- priority: {
452
- type: 'string',
453
- description: 'Priority level (defaults to "medium")',
454
- enum: ['low', 'medium', 'high', 'critical'],
455
- default: 'medium',
456
- },
457
- layer: {
458
- type: 'string',
459
- description: 'Optional architecture layer assignment',
460
- enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'],
461
- },
462
- tags: {
463
- type: 'array',
464
- items: { type: 'string' },
465
- description: 'Optional tags for categorization (e.g., ["api", "security"])',
466
- },
467
- created_by: {
468
- type: 'string',
469
- description: 'Agent creating the constraint (defaults to "system")',
470
- },
196
+ action: { type: 'string', description: 'Action (use "help" for usage)', enum: ['layer_summary', 'db_stats', 'clear', 'help'] },
197
+ messages_older_than_hours: { type: 'number' },
198
+ file_changes_older_than_days: { type: 'number' },
471
199
  },
472
- required: ['category', 'constraint_text'],
200
+ required: ['action'],
473
201
  },
474
202
  },
475
203
  {
476
- name: 'get_constraints',
477
- description: 'Retrieve constraints with advanced filtering. Supports filtering by category, layer, priority, tags, and active status. Uses token-efficient view with all metadata.',
204
+ name: 'config',
205
+ description: 'Auto-deletion config (actions: get, update)',
478
206
  inputSchema: {
479
207
  type: 'object',
480
208
  properties: {
481
- category: {
482
- type: 'string',
483
- description: 'Filter by constraint category',
484
- enum: ['performance', 'architecture', 'security'],
485
- },
486
- layer: {
487
- type: 'string',
488
- description: 'Filter by architecture layer',
489
- enum: ['presentation', 'business', 'data', 'infrastructure', 'cross-cutting'],
490
- },
491
- priority: {
492
- type: 'string',
493
- description: 'Filter by priority level',
494
- enum: ['low', 'medium', 'high', 'critical'],
495
- },
496
- tags: {
497
- type: 'array',
498
- items: { type: 'string' },
499
- description: 'Filter by tags (OR logic - matches ANY tag)',
500
- },
501
- active_only: {
502
- type: 'boolean',
503
- description: 'Only return active constraints (defaults to true)',
504
- default: true,
505
- },
506
- limit: {
507
- type: 'number',
508
- description: 'Maximum number of constraints to return (default: 50)',
509
- default: 50,
510
- },
511
- },
512
- },
513
- },
514
- {
515
- name: 'deactivate_constraint',
516
- description: 'Deactivate a constraint (soft delete). Idempotent - deactivating already-inactive constraint is safe. Constraints are never removed from database.',
517
- inputSchema: {
518
- type: 'object',
519
- properties: {
520
- constraint_id: {
521
- type: 'number',
522
- description: 'The constraint ID to deactivate',
523
- },
524
- },
525
- required: ['constraint_id'],
526
- },
527
- },
528
- {
529
- name: 'get_layer_summary',
530
- description: 'Get summary statistics for all architecture layers. Returns decision counts, recent file changes (last 1 hour), and active constraints per layer.',
531
- inputSchema: {
532
- type: 'object',
533
- properties: {},
534
- },
535
- },
536
- {
537
- name: 'clear_old_data',
538
- description: 'Manually clear old data from the database. Deletes messages older than specified hours and file changes older than specified days. Transaction-safe operation that returns counts of deleted records.',
539
- inputSchema: {
540
- type: 'object',
541
- properties: {
542
- messages_older_than_hours: {
543
- type: 'number',
544
- description: 'Delete messages older than this many hours (default: 24)',
545
- default: 24,
546
- },
547
- file_changes_older_than_days: {
548
- type: 'number',
549
- description: 'Delete file changes older than this many days (default: 7)',
550
- default: 7,
551
- },
552
- },
553
- },
554
- },
555
- {
556
- name: 'get_stats',
557
- description: 'Get comprehensive database statistics including counts for all major tables, active vs total records for decisions and constraints, and overall database health metrics.',
558
- inputSchema: {
559
- type: 'object',
560
- properties: {},
561
- },
562
- },
563
- {
564
- name: 'get_config',
565
- description: 'Get current auto-deletion configuration settings. Returns weekend-awareness flag, message retention hours, and file history retention days.',
566
- inputSchema: {
567
- type: 'object',
568
- properties: {},
569
- },
570
- },
571
- {
572
- name: 'update_config',
573
- description: 'Update auto-deletion configuration settings. All parameters are optional. Changes take effect immediately for subsequent cleanup operations.',
574
- inputSchema: {
575
- type: 'object',
576
- properties: {
577
- ignoreWeekend: {
578
- type: 'boolean',
579
- description: 'Whether to skip weekends when calculating retention periods (true = skip weekends)',
580
- },
581
- messageRetentionHours: {
582
- type: 'number',
583
- description: 'Number of hours to retain messages (1-168 hours)',
584
- minimum: 1,
585
- maximum: 168,
586
- },
587
- fileHistoryRetentionDays: {
588
- type: 'number',
589
- description: 'Number of days to retain file change history (1-90 days)',
590
- minimum: 1,
591
- maximum: 90,
592
- },
209
+ action: { type: 'string', description: 'Action (use "help" for usage)', enum: ['get', 'update', 'help'] },
210
+ ignoreWeekend: { type: 'boolean' },
211
+ messageRetentionHours: { type: 'number', minimum: 1, maximum: 168 },
212
+ fileHistoryRetentionDays: { type: 'number', minimum: 1, maximum: 90 },
593
213
  },
214
+ required: ['action'],
594
215
  },
595
216
  },
596
217
  ],
@@ -599,258 +220,209 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
599
220
  // Handle tool execution
600
221
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
601
222
  const { name, arguments: args } = request.params;
223
+ const params = args;
602
224
  try {
225
+ let result;
603
226
  switch (name) {
604
- case 'set_decision': {
605
- const params = args;
606
- const result = setDecision(params);
607
- return {
608
- content: [
609
- {
610
- type: 'text',
611
- text: JSON.stringify(result, null, 2),
612
- },
613
- ],
614
- };
615
- }
616
- case 'get_context': {
617
- const params = args;
618
- const result = getContext(params);
619
- return {
620
- content: [
621
- {
622
- type: 'text',
623
- text: JSON.stringify(result, null, 2),
624
- },
625
- ],
626
- };
627
- }
628
- case 'get_decision': {
629
- const params = args;
630
- const result = getDecision(params);
631
- return {
632
- content: [
633
- {
634
- type: 'text',
635
- text: JSON.stringify(result, null, 2),
636
- },
637
- ],
638
- };
639
- }
640
- case 'search_by_tags': {
641
- const params = args;
642
- const result = searchByTags(params);
643
- return {
644
- content: [
645
- {
646
- type: 'text',
647
- text: JSON.stringify(result, null, 2),
648
- },
649
- ],
650
- };
651
- }
652
- case 'get_versions': {
653
- const params = args;
654
- const result = getVersions(params);
655
- return {
656
- content: [
657
- {
658
- type: 'text',
659
- text: JSON.stringify(result, null, 2),
660
- },
661
- ],
662
- };
663
- }
664
- case 'search_by_layer': {
665
- const params = args;
666
- const result = searchByLayer(params);
667
- return {
668
- content: [
669
- {
670
- type: 'text',
671
- text: JSON.stringify(result, null, 2),
672
- },
673
- ],
674
- };
675
- }
676
- case 'send_message': {
677
- const params = args;
678
- const result = sendMessage(params);
679
- return {
680
- content: [
681
- {
682
- type: 'text',
683
- text: JSON.stringify(result, null, 2),
684
- },
685
- ],
686
- };
687
- }
688
- case 'get_messages': {
689
- const params = args;
690
- const result = getMessages(params);
691
- return {
692
- content: [
693
- {
694
- type: 'text',
695
- text: JSON.stringify(result, null, 2),
696
- },
697
- ],
698
- };
699
- }
700
- case 'mark_read': {
701
- const params = args;
702
- const result = markRead(params);
703
- return {
704
- content: [
705
- {
706
- type: 'text',
707
- text: JSON.stringify(result, null, 2),
708
- },
709
- ],
710
- };
711
- }
712
- case 'record_file_change': {
713
- const params = args;
714
- const result = recordFileChange(params);
715
- return {
716
- content: [
717
- {
718
- type: 'text',
719
- text: JSON.stringify(result, null, 2),
720
- },
721
- ],
722
- };
723
- }
724
- case 'get_file_changes': {
725
- const params = args;
726
- const result = getFileChanges(params);
727
- return {
728
- content: [
729
- {
730
- type: 'text',
731
- text: JSON.stringify(result, null, 2),
732
- },
733
- ],
734
- };
735
- }
736
- case 'check_file_lock': {
737
- const params = args;
738
- const result = checkFileLock(params);
739
- return {
740
- content: [
741
- {
742
- type: 'text',
743
- text: JSON.stringify(result, null, 2),
744
- },
745
- ],
746
- };
747
- }
748
- case 'add_constraint': {
749
- const params = args;
750
- const result = addConstraint(params);
751
- return {
752
- content: [
753
- {
754
- type: 'text',
755
- text: JSON.stringify(result, null, 2),
756
- },
757
- ],
758
- };
759
- }
760
- case 'get_constraints': {
761
- const params = args;
762
- const result = getConstraints(params);
763
- return {
764
- content: [
765
- {
766
- type: 'text',
767
- text: JSON.stringify(result, null, 2),
768
- },
769
- ],
770
- };
771
- }
772
- case 'deactivate_constraint': {
773
- const params = args;
774
- const result = deactivateConstraint(params);
775
- return {
776
- content: [
777
- {
778
- type: 'text',
779
- text: JSON.stringify(result, null, 2),
780
- },
781
- ],
782
- };
783
- }
784
- case 'get_layer_summary': {
785
- const result = getLayerSummary();
786
- return {
787
- content: [
788
- {
789
- type: 'text',
790
- text: JSON.stringify(result, null, 2),
791
- },
792
- ],
793
- };
794
- }
795
- case 'clear_old_data': {
796
- const params = args;
797
- const result = clearOldData(params);
798
- return {
799
- content: [
800
- {
801
- type: 'text',
802
- text: JSON.stringify(result, null, 2),
803
- },
804
- ],
805
- };
806
- }
807
- case 'get_stats': {
808
- const result = getStats();
809
- return {
810
- content: [
811
- {
812
- type: 'text',
813
- text: JSON.stringify(result, null, 2),
814
- },
815
- ],
816
- };
817
- }
818
- case 'get_config': {
819
- const result = getConfig();
820
- return {
821
- content: [
822
- {
823
- type: 'text',
824
- text: JSON.stringify(result, null, 2),
825
- },
826
- ],
827
- };
828
- }
829
- case 'update_config': {
830
- const params = args;
831
- const result = updateConfig(params);
832
- return {
833
- content: [
834
- {
835
- type: 'text',
836
- text: JSON.stringify(result, null, 2),
837
- },
838
- ],
839
- };
840
- }
227
+ case 'decision':
228
+ switch (params.action) {
229
+ case 'set':
230
+ result = setDecision(params);
231
+ break;
232
+ case 'get':
233
+ result = getDecision(params);
234
+ break;
235
+ case 'list':
236
+ result = getContext(params);
237
+ break;
238
+ case 'search_tags':
239
+ result = searchByTags({ tags: params.tags, match_mode: params.tag_match, status: params.status, layer: params.layer });
240
+ break;
241
+ case 'search_layer':
242
+ result = searchByLayer({ layer: params.layer, status: params.status, include_tags: params.include_tags });
243
+ break;
244
+ case 'versions':
245
+ result = getVersions(params);
246
+ break;
247
+ case 'help':
248
+ result = {
249
+ tool: 'decision',
250
+ description: 'Manage decisions with metadata (tags, layers, versions, scopes)',
251
+ actions: {
252
+ set: 'Set/update a decision. Params: key (required), value (required), agent, layer, version, status, tags, scopes',
253
+ get: 'Get specific decision by key. Params: key (required)',
254
+ list: 'List/filter decisions. Params: status, layer, tags, scope, tag_match',
255
+ search_tags: 'Search decisions by tags. Params: tags (required), match_mode, status, layer',
256
+ search_layer: 'Search decisions by layer. Params: layer (required), status, include_tags',
257
+ versions: 'Get version history for a decision. Params: key (required)'
258
+ },
259
+ examples: {
260
+ set: '{ action: "set", key: "auth_method", value: "jwt", tags: ["security"] }',
261
+ get: '{ action: "get", key: "auth_method" }',
262
+ list: '{ action: "list", status: "active", layer: "infrastructure" }',
263
+ search_tags: '{ action: "search_tags", tags: ["security", "api"] }'
264
+ }
265
+ };
266
+ break;
267
+ default: throw new Error(`Unknown action: ${params.action}`);
268
+ }
269
+ break;
270
+ case 'message':
271
+ switch (params.action) {
272
+ case 'send':
273
+ result = sendMessage(params);
274
+ break;
275
+ case 'get':
276
+ result = getMessages(params);
277
+ break;
278
+ case 'mark_read':
279
+ result = markRead(params);
280
+ break;
281
+ case 'help':
282
+ result = {
283
+ tool: 'message',
284
+ description: 'Send and retrieve messages between agents with priority levels',
285
+ actions: {
286
+ send: 'Send message. Params: from_agent (required), msg_type (required), message (required), to_agent, priority, payload',
287
+ get: 'Get messages for agent. Params: agent_name (required), unread_only, priority_filter, msg_type_filter, limit',
288
+ mark_read: 'Mark messages as read. Params: agent_name (required), message_ids (required)'
289
+ },
290
+ examples: {
291
+ send: '{ action: "send", from_agent: "bot1", msg_type: "info", message: "Task complete", priority: "high" }',
292
+ get: '{ action: "get", agent_name: "bot1", unread_only: true }',
293
+ mark_read: '{ action: "mark_read", agent_name: "bot1", message_ids: [1, 2, 3] }'
294
+ }
295
+ };
296
+ break;
297
+ default: throw new Error(`Unknown action: ${params.action}`);
298
+ }
299
+ break;
300
+ case 'file':
301
+ switch (params.action) {
302
+ case 'record':
303
+ result = recordFileChange(params);
304
+ break;
305
+ case 'get':
306
+ result = getFileChanges(params);
307
+ break;
308
+ case 'check_lock':
309
+ result = checkFileLock(params);
310
+ break;
311
+ case 'help':
312
+ result = {
313
+ tool: 'file',
314
+ description: 'Track file changes across agents with layer classification',
315
+ actions: {
316
+ record: 'Record file change. Params: file_path (required), agent_name (required), change_type (required), layer, description',
317
+ get: 'Get file changes. Params: file_path, agent_name, layer, change_type, since, limit',
318
+ check_lock: 'Check if file locked. Params: file_path (required), lock_duration'
319
+ },
320
+ examples: {
321
+ record: '{ action: "record", file_path: "src/index.ts", agent_name: "refactor-bot", change_type: "modified", layer: "infrastructure" }',
322
+ get: '{ action: "get", agent_name: "refactor-bot", layer: "infrastructure", limit: 10 }',
323
+ check_lock: '{ action: "check_lock", file_path: "src/index.ts", lock_duration: 300 }'
324
+ }
325
+ };
326
+ break;
327
+ default: throw new Error(`Unknown action: ${params.action}`);
328
+ }
329
+ break;
330
+ case 'constraint':
331
+ switch (params.action) {
332
+ case 'add':
333
+ result = addConstraint(params);
334
+ break;
335
+ case 'get':
336
+ result = getConstraints(params);
337
+ break;
338
+ case 'deactivate':
339
+ result = deactivateConstraint(params);
340
+ break;
341
+ case 'help':
342
+ result = {
343
+ tool: 'constraint',
344
+ description: 'Manage project constraints (performance, architecture, security)',
345
+ actions: {
346
+ add: 'Add constraint. Params: category (required), constraint_text (required), priority, layer, tags, created_by',
347
+ get: 'Get constraints. Params: category, layer, priority, tags, active_only, limit',
348
+ deactivate: 'Deactivate constraint. Params: constraint_id (required)'
349
+ },
350
+ examples: {
351
+ add: '{ action: "add", category: "performance", constraint_text: "API response time <100ms", priority: "high", tags: ["api"] }',
352
+ get: '{ action: "get", category: "performance", active_only: true }',
353
+ deactivate: '{ action: "deactivate", constraint_id: 5 }'
354
+ }
355
+ };
356
+ break;
357
+ default: throw new Error(`Unknown action: ${params.action}`);
358
+ }
359
+ break;
360
+ case 'stats':
361
+ switch (params.action) {
362
+ case 'layer_summary':
363
+ result = getLayerSummary();
364
+ break;
365
+ case 'db_stats':
366
+ result = getStats();
367
+ break;
368
+ case 'clear':
369
+ result = clearOldData(params);
370
+ break;
371
+ case 'help':
372
+ result = {
373
+ tool: 'stats',
374
+ description: 'View database statistics and manage data cleanup',
375
+ actions: {
376
+ layer_summary: 'Get summary by layer. No params required',
377
+ db_stats: 'Get database statistics. No params required',
378
+ clear: 'Clear old data. Params: messages_older_than_hours, file_changes_older_than_days'
379
+ },
380
+ examples: {
381
+ layer_summary: '{ action: "layer_summary" }',
382
+ db_stats: '{ action: "db_stats" }',
383
+ clear: '{ action: "clear", messages_older_than_hours: 48, file_changes_older_than_days: 14 }'
384
+ }
385
+ };
386
+ break;
387
+ default: throw new Error(`Unknown action: ${params.action}`);
388
+ }
389
+ break;
390
+ case 'config':
391
+ switch (params.action) {
392
+ case 'get':
393
+ result = getConfig();
394
+ break;
395
+ case 'update':
396
+ result = updateConfig(params);
397
+ break;
398
+ case 'help':
399
+ result = {
400
+ tool: 'config',
401
+ description: 'Manage auto-deletion configuration (weekend-aware retention)',
402
+ actions: {
403
+ get: 'Get current config. No params required',
404
+ update: 'Update config. Params: ignoreWeekend, messageRetentionHours (1-168), fileHistoryRetentionDays (1-90)'
405
+ },
406
+ examples: {
407
+ get: '{ action: "get" }',
408
+ update: '{ action: "update", ignoreWeekend: true, messageRetentionHours: 48 }'
409
+ }
410
+ };
411
+ break;
412
+ default: throw new Error(`Unknown action: ${params.action}`);
413
+ }
414
+ break;
841
415
  default:
842
416
  throw new Error(`Unknown tool: ${name}`);
843
417
  }
418
+ return {
419
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
420
+ };
844
421
  }
845
422
  catch (error) {
846
423
  const message = error instanceof Error ? error.message : String(error);
847
424
  return {
848
- content: [
849
- {
850
- type: 'text',
851
- text: JSON.stringify({ error: message }, null, 2),
852
- },
853
- ],
425
+ content: [{ type: 'text', text: JSON.stringify({ error: message }, null, 2) }],
854
426
  isError: true,
855
427
  };
856
428
  }