tribunal-kit 5.7.0 → 5.8.1

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 (59) hide show
  1. package/.agent/ARCHITECTURE.md +6 -7
  2. package/.agent/agents/frontend-reviewer.md +13 -0
  3. package/.agent/agents/frontend-specialist.md +14 -0
  4. package/.agent/agents/logic-reviewer.md +11 -0
  5. package/.agent/agents/orchestrator.md +15 -0
  6. package/.agent/agents/project-planner.md +5 -0
  7. package/.agent/agents/security-auditor.md +13 -0
  8. package/.agent/agents/ui-ux-auditor.md +7 -31
  9. package/.agent/history/memory/.memory.idx +1693 -0
  10. package/.agent/history/memory/MEMORY.md +123 -0
  11. package/.agent/routing_index.json +694 -714
  12. package/.agent/rules/GEMINI.md +88 -13
  13. package/.agent/scripts/_colors.js +131 -89
  14. package/.agent/scripts/_utils.js +163 -128
  15. package/.agent/scripts/auto_preview.js +207 -197
  16. package/.agent/scripts/bundle_analyzer.js +227 -192
  17. package/.agent/scripts/case_law_manager.js +991 -689
  18. package/.agent/scripts/checklist.js +233 -190
  19. package/.agent/scripts/context_broker.js +930 -605
  20. package/.agent/scripts/dependency_analyzer.js +275 -184
  21. package/.agent/scripts/graph_builder.js +412 -341
  22. package/.agent/scripts/graph_visualizer.js +392 -390
  23. package/.agent/scripts/graph_zoom.js +198 -156
  24. package/.agent/scripts/inner_loop_validator.js +523 -445
  25. package/.agent/scripts/lint_runner.js +199 -157
  26. package/.agent/scripts/marathon_harness.js +819 -661
  27. package/.agent/scripts/minify_context.js +115 -100
  28. package/.agent/scripts/mutation_runner.js +321 -280
  29. package/.agent/scripts/prompt_compiler.js +62 -42
  30. package/.agent/scripts/schema_validator.js +373 -280
  31. package/.agent/scripts/security_scan.js +333 -190
  32. package/.agent/scripts/session_manager.js +306 -270
  33. package/.agent/scripts/skill_evolution.js +810 -637
  34. package/.agent/scripts/skill_integrator.js +327 -307
  35. package/.agent/scripts/strengthen_skills.js +203 -193
  36. package/.agent/scripts/swarm_dispatcher.js +558 -457
  37. package/.agent/scripts/test_runner.js +178 -152
  38. package/.agent/scripts/verify_all.js +200 -168
  39. package/.agent/skills/fabel-protocol/SKILL.md +271 -0
  40. package/.agent/skills/thinking-protocol/SKILL.md +27 -0
  41. package/.agent/workflows/generate.md +2 -1
  42. package/.agent/workflows/tribunal-full.md +4 -3
  43. package/.agent/workflows/tribunal-speed.md +1 -1
  44. package/README.md +184 -58
  45. package/bin/mcp-server.js +496 -173
  46. package/bin/tribunal-kit.js +1245 -987
  47. package/bin/wrapper.js +108 -74
  48. package/dist/cli.js +44 -0
  49. package/dist/commands/align.js +201 -0
  50. package/dist/commands/case.js +23 -0
  51. package/dist/commands/compile.js +84 -0
  52. package/dist/commands/init.js +42 -0
  53. package/dist/commands/learn.js +57 -0
  54. package/dist/commands/memory.js +456 -0
  55. package/package.json +22 -10
  56. package/scripts/benchmark.js +162 -125
  57. package/scripts/changelog.js +196 -168
  58. package/scripts/sync-version.js +94 -81
  59. package/scripts/validate-payload.js +85 -78
@@ -281,6 +281,47 @@ async function generateIDEBridges(targetDir, agentDest, dryRun = false) {
281
281
  # Auto-generated by tribunal-kit init. Do not edit manually.
282
282
  # Source: .agent/rules/GEMINI.md
283
283
 
284
+ ${rulesContent}
285
+ `;
286
+ // ── 2. Windsurf (.windsurfrules) ─────────────────────
287
+ const windsurfRules = `# Tribunal Kit — Windsurf Bridge
288
+ # Auto-generated by tribunal-kit init. Do not edit manually.
289
+ # Source: .agent/rules/GEMINI.md
290
+
291
+ ${rulesContent}
292
+ `;
293
+ // ── 3. Gemini / Antigravity (.gemini/settings.json) ──
294
+ const geminiSettings = JSON.stringify({
295
+ "rules": [
296
+ { "path": "../.agent/rules/GEMINI.md", "trigger": "always_on" }
297
+ ],
298
+ "agents": { "directory": "../.agent/agents" },
299
+ "skills": { "directory": "../.agent/skills" },
300
+ "workflows": { "directory": "../.agent/workflows" }
301
+ }, null, 2) + '\n';
302
+ // ── Also create .gemini/GEMINI.md as a direct rules file ──
303
+ const geminiRulesBridge = `---
304
+ trigger: always_on
305
+ ---
306
+
307
+ # Tribunal Kit — Gemini Bridge
308
+ # Auto-generated by tribunal-kit init.
309
+ # Full rules: .agent/rules/GEMINI.md
310
+
311
+ ${rulesContent}
312
+ `;
313
+ // ── 4. GitHub Copilot (.github/copilot-instructions.md) ──
314
+ const copilotInstructions = `# Tribunal Kit — Copilot Bridge
315
+ # Auto-generated by tribunal-kit init. Do not edit manually.
316
+ # Source: .agent/rules/GEMINI.md
317
+
318
+ ${rulesContent}
319
+ `;
320
+ // ── 5. Claude (.claude/CLAUDE.md) ─────────────────────
321
+ const claudeRules = `# Tribunal Kit — Claude Bridge
322
+ # Auto-generated by tribunal-kit init. Do not edit manually.
323
+ # Source: .agent/rules/GEMINI.md
324
+
284
325
  ${rulesContent}
285
326
  `;
286
327
  // Fire ALL bridge writes concurrently via Promise.all
@@ -295,3 +336,4 @@ ${rulesContent}
295
336
  await Promise.all(bridges.map(b => writeBridge(b.path, b.content, b.label)));
296
337
  console.log();
297
338
  }
339
+
@@ -55,6 +55,63 @@ async function cmdLearn(flags, quiet = false) {
55
55
  (0, logger_1.log)(` ${(0, logger_1.c)('gray', '\u25b8')} Search existing case law:`);
56
56
  (0, logger_1.log)(` ${(0, logger_1.c)('white', 'npx tribunal-kit case search "your query"')}`);
57
57
  console.log();
58
+ // Phase 3: Memory Distillation
59
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '\u229b')} ${(0, logger_1.bold)('Phase 3')} \u2014 Memory Distillation (storing project knowledge)`);
60
+ try {
61
+ const { _memoryStore } = require('./memory');
62
+ // Auto-extract SEMANTIC memories from project-idioms if it exists
63
+ const idiomsPath = path_1.default.join(agentDest, 'skills', 'project-idioms', 'SKILL.md');
64
+ let memoriesStored = 0;
65
+ if (fs_1.default.existsSync(idiomsPath)) {
66
+ const idiomsContent = fs_1.default.readFileSync(idiomsPath, 'utf8');
67
+ // Extract lines that look like project rules (lines starting with - or * that contain actionable content)
68
+ const ruleLines = idiomsContent.split('\n')
69
+ .filter(line => /^[\s]*[-*]\s+/.test(line) && line.trim().length > 20)
70
+ .map(line => line.replace(/^[\s]*[-*]\s+/, '').trim())
71
+ .slice(0, 10); // Cap at 10 to prevent bloat
72
+
73
+ for (const rule of ruleLines) {
74
+ try {
75
+ _memoryStore(agentDest, 'semantic', rule, ['project-idiom', 'auto-learned'], null);
76
+ memoriesStored++;
77
+ } catch {
78
+ // Skip duplicates or capacity errors silently
79
+ }
80
+ }
81
+ }
82
+ // Auto-extract PROCEDURAL memories from package.json scripts
83
+ const pkgPath = path_1.default.join(targetDir, 'package.json');
84
+ if (fs_1.default.existsSync(pkgPath)) {
85
+ try {
86
+ const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf8'));
87
+ if (pkg.scripts) {
88
+ const importantScripts = ['build', 'test', 'dev', 'start', 'deploy', 'lint'];
89
+ for (const key of importantScripts) {
90
+ if (pkg.scripts[key]) {
91
+ try {
92
+ _memoryStore(agentDest, 'procedural',
93
+ `Run \`${pkg.scripts[key]}\` to ${key} the project`,
94
+ ['build-script', key, 'auto-learned'], null);
95
+ memoriesStored++;
96
+ } catch {
97
+ // Skip
98
+ }
99
+ }
100
+ }
101
+ }
102
+ } catch {
103
+ // Unreadable package.json
104
+ }
105
+ }
106
+ if (memoriesStored > 0) {
107
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', '\u2714')} ${memoriesStored} memories auto-stored (semantic + procedural)`);
108
+ } else {
109
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '\u25b8')} No new memories to distill (run again after committing changes)`);
110
+ }
111
+ } catch (e) {
112
+ (0, logger_1.log)(` ${(0, logger_1.c)('yellow', '\u26a0')} Memory distillation skipped: ${e.message || String(e)}`);
113
+ }
114
+ console.log();
58
115
  (0, logger_1.log)(` ${(0, logger_1.c)('green', '\u2714')} ${(0, logger_1.bold)('Learn cycle complete.')} Your Tribunal grows smarter with every commit.`);
59
116
  console.log();
60
117
  }
@@ -0,0 +1,456 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cmdMemory = cmdMemory;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const logger_1 = require("../utils/logger");
10
+ const helpers_1 = require("../utils/helpers");
11
+
12
+ /**
13
+ * Tribunal Memory Engine — Node.js CLI Handler
14
+ *
15
+ * Routes memory subcommands to the Rust binary when available,
16
+ * with a pure JS fallback for environments without native binaries.
17
+ *
18
+ * Commands:
19
+ * tk memory store --type semantic --content "..." --tags "db,orm"
20
+ * tk memory recall --query "database" --budget 2000
21
+ * tk memory gc
22
+ * tk memory stats
23
+ * tk memory export
24
+ */
25
+
26
+ // ── Memory Index I/O (JS fallback) ──────────────────────────────────────────
27
+
28
+ const MEMORY_DIR = 'history/memory';
29
+ const INDEX_FILE = '.memory.idx';
30
+ const PROJECTION_FILE = 'MEMORY.md';
31
+ const MAX_ENTRIES = 500;
32
+ const EPISODIC_TTL_DAYS = 30;
33
+
34
+ function getMemoryDir(agentDest) {
35
+ return path_1.default.join(agentDest, MEMORY_DIR);
36
+ }
37
+
38
+ function getIndexPath(agentDest) {
39
+ return path_1.default.join(getMemoryDir(agentDest), INDEX_FILE);
40
+ }
41
+
42
+ function getProjectionPath(agentDest) {
43
+ return path_1.default.join(getMemoryDir(agentDest), PROJECTION_FILE);
44
+ }
45
+
46
+ function loadIndex(agentDest) {
47
+ const indexPath = getIndexPath(agentDest);
48
+ if (!fs_1.default.existsSync(indexPath)) {
49
+ return { version: 1, entries: [], next_id: 1 };
50
+ }
51
+ try {
52
+ const content = fs_1.default.readFileSync(indexPath, 'utf8');
53
+ return JSON.parse(content);
54
+ } catch {
55
+ return { version: 1, entries: [], next_id: 1 };
56
+ }
57
+ }
58
+
59
+ function saveIndex(agentDest, index) {
60
+ const memDir = getMemoryDir(agentDest);
61
+ fs_1.default.mkdirSync(memDir, { recursive: true });
62
+ const indexPath = getIndexPath(agentDest);
63
+ // Atomic write: write temp, rename
64
+ const tmpPath = indexPath + '.tmp';
65
+ fs_1.default.writeFileSync(tmpPath, JSON.stringify(index, null, 2), 'utf8');
66
+ fs_1.default.renameSync(tmpPath, indexPath);
67
+ }
68
+
69
+ function estimateTokens(text) {
70
+ return Math.ceil(text.length / 4);
71
+ }
72
+
73
+ function nowEpochStr() {
74
+ return `${Math.floor(Date.now() / 1000)}Z`;
75
+ }
76
+
77
+ function daysSince(ts) {
78
+ const created = parseInt(ts.replace('Z', ''), 10) || 0;
79
+ const now = Math.floor(Date.now() / 1000);
80
+ return Math.floor((now - created) / 86400);
81
+ }
82
+
83
+ // ── Scoring Engine ──────────────────────────────────────────────────────────
84
+
85
+ const TYPE_PRIORITY = { semantic: 1.0, procedural: 0.9, episodic: 0.7, working: 0.5 };
86
+
87
+ function computeScore(entry, query) {
88
+ const queryLower = query.toLowerCase();
89
+ const contentLower = entry.content.toLowerCase();
90
+
91
+ let relevance = 0;
92
+ if (contentLower.includes(queryLower)) {
93
+ relevance = 1.0;
94
+ } else if (entry.tags.some(t => t.toLowerCase().includes(queryLower))) {
95
+ relevance = 0.8;
96
+ } else if (queryLower.split(/\s+/).some(word => contentLower.includes(word))) {
97
+ relevance = 0.3;
98
+ }
99
+
100
+ if (relevance === 0) return 0;
101
+
102
+ const priority = TYPE_PRIORITY[entry.memory_type] || 0.5;
103
+ let recency = 0;
104
+ if (entry.memory_type === 'episodic') {
105
+ const age = daysSince(entry.created_at);
106
+ recency = Math.exp(-age / 30);
107
+ }
108
+ const freqBoost = Math.max(0, Math.log(entry.access_count || 1)) * 0.05;
109
+
110
+ return (relevance * priority) + recency + freqBoost;
111
+ }
112
+
113
+ // ── Store ───────────────────────────────────────────────────────────────────
114
+
115
+ function memoryStore(agentDest, type, content, tags, sessionId) {
116
+ const VALID_TYPES = ['episodic', 'semantic', 'procedural', 'working'];
117
+ if (!VALID_TYPES.includes(type)) {
118
+ throw new Error(`Invalid memory type: "${type}". Must be one of: ${VALID_TYPES.join(', ')}`);
119
+ }
120
+ if (!content || content.trim().length === 0) {
121
+ throw new Error('Memory content cannot be empty');
122
+ }
123
+
124
+ const index = loadIndex(agentDest);
125
+
126
+ // Enforce cap — auto-GC if needed
127
+ if (index.entries.length >= MAX_ENTRIES) {
128
+ index.entries = index.entries.filter(e => e.memory_type !== 'working');
129
+ if (index.entries.length >= MAX_ENTRIES) {
130
+ index.entries = index.entries.filter(e => {
131
+ if (e.memory_type === 'episodic') {
132
+ return daysSince(e.created_at) < EPISODIC_TTL_DAYS;
133
+ }
134
+ return true;
135
+ });
136
+ }
137
+ if (index.entries.length >= MAX_ENTRIES) {
138
+ throw new Error(`Memory at capacity (${MAX_ENTRIES}). Run: tk memory gc`);
139
+ }
140
+ }
141
+
142
+ const now = nowEpochStr();
143
+ const id = index.next_id || (index.entries.length > 0 ? Math.max(...index.entries.map(e => e.id)) + 1 : 1);
144
+ const entry = {
145
+ id,
146
+ memory_type: type,
147
+ content: content.trim(),
148
+ tags: tags.filter(t => t.length > 0),
149
+ created_at: now,
150
+ last_accessed: now,
151
+ access_count: 0,
152
+ token_estimate: estimateTokens(content),
153
+ source: type === 'working' ? 'session' : 'manual',
154
+ session_id: sessionId || null,
155
+ };
156
+
157
+ index.entries.push(entry);
158
+ index.next_id = id + 1;
159
+ saveIndex(agentDest, index);
160
+ generateProjection(agentDest, index);
161
+
162
+ return { id, token_estimate: entry.token_estimate };
163
+ }
164
+
165
+ // ── Recall ──────────────────────────────────────────────────────────────────
166
+
167
+ function memoryRecall(agentDest, query, budget = 2000) {
168
+ const index = loadIndex(agentDest);
169
+
170
+ const scored = index.entries
171
+ .map(entry => ({ entry, score: computeScore(entry, query) }))
172
+ .filter(s => s.score > 0)
173
+ .sort((a, b) => b.score - a.score);
174
+
175
+ let totalTokens = 0;
176
+ const results = [];
177
+
178
+ for (const { entry, score } of scored) {
179
+ if (totalTokens + entry.token_estimate > budget) break;
180
+ totalTokens += entry.token_estimate;
181
+ entry.last_accessed = nowEpochStr();
182
+ entry.access_count = (entry.access_count || 0) + 1;
183
+ results.push({ ...entry, score });
184
+ }
185
+
186
+ // Save updated access counts
187
+ saveIndex(agentDest, index);
188
+
189
+ return { results, tokens_used: totalTokens, budget };
190
+ }
191
+
192
+ // ── Garbage Collect ─────────────────────────────────────────────────────────
193
+
194
+ function memoryGc(agentDest) {
195
+ const index = loadIndex(agentDest);
196
+ const before = index.entries.length;
197
+
198
+ let workingRemoved = 0;
199
+ let episodicRemoved = 0;
200
+
201
+ index.entries = index.entries.filter(e => {
202
+ if (e.memory_type === 'working') { workingRemoved++; return false; }
203
+ if (e.memory_type === 'episodic' && daysSince(e.created_at) >= EPISODIC_TTL_DAYS) {
204
+ episodicRemoved++; return false;
205
+ }
206
+ return true;
207
+ });
208
+
209
+ saveIndex(agentDest, index);
210
+ generateProjection(agentDest, index);
211
+
212
+ return { working_removed: workingRemoved, episodic_removed: episodicRemoved, before, after: index.entries.length };
213
+ }
214
+
215
+ // ── Stats ───────────────────────────────────────────────────────────────────
216
+
217
+ function memoryStats(agentDest) {
218
+ const index = loadIndex(agentDest);
219
+ const total = index.entries.length;
220
+ const semantic = index.entries.filter(e => e.memory_type === 'semantic').length;
221
+ const procedural = index.entries.filter(e => e.memory_type === 'procedural').length;
222
+ const episodic = index.entries.filter(e => e.memory_type === 'episodic').length;
223
+ const working = index.entries.filter(e => e.memory_type === 'working').length;
224
+ const totalTokens = index.entries.reduce((sum, e) => sum + (e.token_estimate || 0), 0);
225
+ return { total, semantic, procedural, episodic, working, total_tokens: totalTokens, capacity: MAX_ENTRIES };
226
+ }
227
+
228
+ // ── Projection Generator ───────────────────────────────────────────────────
229
+
230
+ function generateProjection(agentDest, index) {
231
+ if (!index) index = loadIndex(agentDest);
232
+
233
+ let md = '# 🧠 Tribunal Memory Index\n';
234
+ md += '> Auto-generated by `tribunal-kit memory export`. Do not edit manually.\n';
235
+
236
+ const sem = index.entries.filter(e => e.memory_type === 'semantic');
237
+ const proc = index.entries.filter(e => e.memory_type === 'procedural');
238
+ const ep = index.entries.filter(e => e.memory_type === 'episodic');
239
+ const work = index.entries.filter(e => e.memory_type === 'working');
240
+
241
+ md += `> Entries: ${index.entries.length} | Semantic: ${sem.length} | Procedural: ${proc.length} | Episodic: ${ep.length} | Working: ${work.length}\n\n`;
242
+
243
+ if (sem.length > 0) {
244
+ md += '## SEMANTIC (Permanent Facts)\n';
245
+ md += '| ID | Content | Tags | Source | Created |\n';
246
+ md += '|----|---------|------|--------|---------|\n';
247
+ for (const e of sem) {
248
+ md += `| ${e.id} | ${e.content.replace(/\|/g, '\\|')} | ${e.tags.join(', ')} | ${e.source} | ${e.created_at} |\n`;
249
+ }
250
+ md += '\n';
251
+ }
252
+
253
+ if (proc.length > 0) {
254
+ md += '## PROCEDURAL (How-To Recipes)\n';
255
+ md += '| ID | Content | Tags | Source | Created |\n';
256
+ md += '|----|---------|------|--------|---------|\n';
257
+ for (const e of proc) {
258
+ md += `| ${e.id} | ${e.content.replace(/\|/g, '\\|')} | ${e.tags.join(', ')} | ${e.source} | ${e.created_at} |\n`;
259
+ }
260
+ md += '\n';
261
+ }
262
+
263
+ if (ep.length > 0) {
264
+ md += '## EPISODIC (Session History — auto-decays after 30 days)\n';
265
+ md += '| ID | Content | Tags | Source | Created | Days Remaining |\n';
266
+ md += '|----|---------|------|--------|---------|----------------|\n';
267
+ for (const e of ep) {
268
+ const remaining = Math.max(0, EPISODIC_TTL_DAYS - daysSince(e.created_at));
269
+ md += `| ${e.id} | ${e.content.replace(/\|/g, '\\|')} | ${e.tags.join(', ')} | ${e.source} | ${e.created_at} | ${remaining} |\n`;
270
+ }
271
+ md += '\n';
272
+ }
273
+
274
+ if (work.length > 0) {
275
+ md += '## WORKING (Current Session — cleared on GC)\n';
276
+ md += '| ID | Content | Tags | Session |\n';
277
+ md += '|----|---------|------|---------|\n';
278
+ for (const e of work) {
279
+ md += `| ${e.id} | ${e.content.replace(/\|/g, '\\|')} | ${e.tags.join(', ')} | ${e.session_id || '—'} |\n`;
280
+ }
281
+ md += '\n';
282
+ }
283
+
284
+ if (index.entries.length === 0) {
285
+ md += '*No memories recorded yet. Run `tk memory store` to add your first memory.*\n';
286
+ }
287
+
288
+ const projPath = getProjectionPath(agentDest);
289
+ fs_1.default.mkdirSync(path_1.default.dirname(projPath), { recursive: true });
290
+ fs_1.default.writeFileSync(projPath, md, 'utf8');
291
+
292
+ return projPath;
293
+ }
294
+
295
+ // ── CLI Router ──────────────────────────────────────────────────────────────
296
+
297
+ async function cmdMemory(flags, processArgs, quiet = false) {
298
+ const targetDir = flags.path ? path_1.default.resolve(flags.path) : process.cwd();
299
+ const agentDest = path_1.default.join(targetDir, '.agent');
300
+
301
+ if (!fs_1.default.existsSync(agentDest)) {
302
+ (0, logger_1.err)('.agent/ not found. Run: npx tribunal-kit init');
303
+ process.exit(1);
304
+ }
305
+
306
+ const args = processArgs.slice(3);
307
+ const subcommand = args[0];
308
+
309
+ if (!subcommand || subcommand === 'help' || subcommand === '--help' || subcommand === '-h') {
310
+ (0, helpers_1.banner)(quiet);
311
+ const W = 62;
312
+ const title = ' Tribunal Memory — 4-Type Taxonomy Engine';
313
+ const trail = ' '.repeat(Math.max(0, W - title.length));
314
+ console.log(` ${(0, logger_1.c)('cyan', '\u2554' + '\u2550'.repeat(W) + '\u2557')}`);
315
+ console.log(` ${(0, logger_1.c)('cyan', '\u2551')}${(0, logger_1.bold)((0, logger_1.c)('white', title))}${trail}${(0, logger_1.c)('cyan', '\u2551')}`);
316
+ console.log(` ${(0, logger_1.c)('cyan', '\u255a' + '\u2550'.repeat(W) + '\u255d')}`);
317
+ console.log();
318
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'store'.padEnd(10))} ${(0, logger_1.c)('gray', 'Store a new memory entry')}`);
319
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'recall'.padEnd(10))} ${(0, logger_1.c)('gray', 'Budget-constrained memory recall')}`);
320
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'gc'.padEnd(10))} ${(0, logger_1.c)('gray', 'Garbage collect expired/working memories')}`);
321
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'stats'.padEnd(10))} ${(0, logger_1.c)('gray', 'Show memory index statistics')}`);
322
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'export'.padEnd(10))} ${(0, logger_1.c)('gray', 'Export MEMORY.md projection')}`);
323
+ console.log();
324
+ (0, logger_1.log)((0, logger_1.bold)(' Memory Types'));
325
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '─'.repeat(40))}`);
326
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', 'semantic'.padEnd(14))} ${(0, logger_1.c)('gray', 'Permanent project facts & rules')}`);
327
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', 'procedural'.padEnd(14))} ${(0, logger_1.c)('gray', 'How-to recipes & build steps')}`);
328
+ (0, logger_1.log)(` ${(0, logger_1.c)('yellow', 'episodic'.padEnd(14))} ${(0, logger_1.c)('gray', 'Session events (30-day TTL)')}`);
329
+ (0, logger_1.log)(` ${(0, logger_1.c)('yellow', 'working'.padEnd(14))} ${(0, logger_1.c)('gray', 'Scratch memory (cleared on GC)')}`);
330
+ console.log();
331
+ (0, logger_1.log)((0, logger_1.bold)(' Examples'));
332
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '─'.repeat(40))}`);
333
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▸')} ${(0, logger_1.c)('white', 'tk memory store --type semantic --content "Uses PostgreSQL" --tags db,orm')}`);
334
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▸')} ${(0, logger_1.c)('white', 'tk memory recall --query "database" --budget 2000')}`);
335
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▸')} ${(0, logger_1.c)('white', 'tk memory gc')}`);
336
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▸')} ${(0, logger_1.c)('white', 'tk memory stats')}`);
337
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▸')} ${(0, logger_1.c)('white', 'tk memory export')}`);
338
+ console.log();
339
+ process.exit(0);
340
+ }
341
+
342
+ // Parse flags from remaining args
343
+ function getFlag(name) {
344
+ const idx = args.indexOf(`--${name}`);
345
+ if (idx === -1) return null;
346
+ return args[idx + 1] || null;
347
+ }
348
+
349
+ try {
350
+ switch (subcommand) {
351
+ case 'store': {
352
+ const type = getFlag('type');
353
+ const content = getFlag('content');
354
+ const tagsRaw = getFlag('tags') || '';
355
+ const sessionId = getFlag('session-id');
356
+ if (!type || !content) {
357
+ (0, logger_1.err)('Usage: tk memory store --type <type> --content "<text>" [--tags tag1,tag2]');
358
+ process.exit(1);
359
+ }
360
+ const tags = tagsRaw.split(',').map(t => t.trim()).filter(t => t.length > 0);
361
+ const result = memoryStore(agentDest, type, content, tags, sessionId);
362
+ if (!quiet) {
363
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', '✔')} ${(0, logger_1.bold)('Memory stored')} #${result.id} (${type})`);
364
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} ${(0, logger_1.c)('gray', content)}`);
365
+ if (tags.length > 0) {
366
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Tags: ${(0, logger_1.c)('gray', tags.join(', '))}`);
367
+ }
368
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} ~${result.token_estimate} tokens`);
369
+ }
370
+ break;
371
+ }
372
+
373
+ case 'recall': {
374
+ const query = getFlag('query');
375
+ const budgetStr = getFlag('budget');
376
+ const budget = budgetStr ? parseInt(budgetStr, 10) : 2000;
377
+ if (!query) {
378
+ (0, logger_1.err)('Usage: tk memory recall --query "<search>" [--budget 2000]');
379
+ process.exit(1);
380
+ }
381
+ const { results, tokens_used } = memoryRecall(agentDest, query, budget);
382
+ if (!quiet) {
383
+ if (results.length === 0) {
384
+ (0, logger_1.log)(` ${(0, logger_1.c)('yellow', '⚠')} No memories match query: "${query}"`);
385
+ } else {
386
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', '✔')} ${results.length} memories recalled (budget: ${budget} tokens)`);
387
+ for (const entry of results) {
388
+ const typeLabel = entry.memory_type.toUpperCase();
389
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} [${(0, logger_1.c)('cyan', typeLabel)}] #${entry.id}: ${entry.content} ${(0, logger_1.c)('gray', `(score: ${entry.score.toFixed(2)}, ~${entry.token_estimate}tok)`)}`);
390
+ }
391
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Total: ~${tokens_used} tokens used of ${budget} budget`);
392
+ }
393
+ }
394
+ // Machine output for agent consumption
395
+ console.log(JSON.stringify({
396
+ action: 'recall', query, budget, tokens_used,
397
+ count: results.length,
398
+ entries: results.map(e => ({
399
+ id: e.id, memory_type: e.memory_type, content: e.content,
400
+ tags: e.tags, score: e.score, token_estimate: e.token_estimate,
401
+ })),
402
+ }));
403
+ break;
404
+ }
405
+
406
+ case 'gc': {
407
+ const result = memoryGc(agentDest);
408
+ if (!quiet) {
409
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', '✔')} ${(0, logger_1.bold)('Garbage collection complete')}`);
410
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Working removed: ${result.working_removed}`);
411
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Episodic expired: ${result.episodic_removed}`);
412
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Entries: ${result.before} → ${result.after}`);
413
+ }
414
+ break;
415
+ }
416
+
417
+ case 'stats': {
418
+ const stats = memoryStats(agentDest);
419
+ if (!quiet) {
420
+ (0, logger_1.log)(`\n 🧠 ${(0, logger_1.bold)('Tribunal Memory Index')}`);
421
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Total entries: ${stats.total}`);
422
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Semantic: ${stats.semantic} (permanent)`);
423
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Procedural: ${stats.procedural} (permanent)`);
424
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Episodic: ${stats.episodic} (30-day TTL)`);
425
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Working: ${stats.working} (session-scoped)`);
426
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Token budget: ~${stats.total_tokens} tokens indexed`);
427
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▶')} Capacity: ${stats.total}/${stats.capacity}\n`);
428
+ }
429
+ break;
430
+ }
431
+
432
+ case 'export': {
433
+ const projPath = generateProjection(agentDest);
434
+ if (!quiet) {
435
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', '✔')} ${(0, logger_1.bold)('MEMORY.md exported')} → ${projPath}`);
436
+ }
437
+ break;
438
+ }
439
+
440
+ default:
441
+ (0, logger_1.err)(`Unknown memory subcommand: "${subcommand}"`);
442
+ (0, logger_1.log)(' Run: tk memory --help');
443
+ process.exit(1);
444
+ }
445
+ } catch (e) {
446
+ (0, logger_1.err)(e.message || String(e));
447
+ process.exit(1);
448
+ }
449
+ }
450
+
451
+ // Export internal functions for MCP server and learn/case integration
452
+ exports._memoryStore = memoryStore;
453
+ exports._memoryRecall = memoryRecall;
454
+ exports._memoryGc = memoryGc;
455
+ exports._memoryStats = memoryStats;
456
+ exports._generateProjection = generateProjection;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tribunal-kit",
3
- "version": "5.7.0",
4
- "description": "Anti-Hallucination AI Agent Kit — 43 specialist agents, 32 slash commands, 19 parallel Tribunal reviewers, Performance Swarm engine, Supreme Court case law pipeline, and long-running agent harness.",
3
+ "version": "5.8.1",
4
+ "description": "Anti-Hallucination AI Agent Kit for IDEs (Cursor, VSCode, Windsurf) — 43 specialist agents, 34 workflows, 20 parallel Tribunal code reviewers, Model Context Protocol (MCP) server, and long-running autonomous agent harness.",
5
5
  "keywords": [
6
6
  "ai",
7
7
  "ai-agent",
@@ -33,7 +33,17 @@
33
33
  "ai-coding",
34
34
  "autonomous-agents",
35
35
  "coding-assistant",
36
- "automation"
36
+ "automation",
37
+ "model-context-protocol-server",
38
+ "mcp-server",
39
+ "claude-code",
40
+ "aider",
41
+ "cursor-rules-generator",
42
+ "agentic-ai",
43
+ "ai-code-reviewer",
44
+ "hallucination-mitigation",
45
+ "autonomous-workflows",
46
+ "code-correctness"
37
47
  ],
38
48
  "homepage": "https://github.com/Harmitx7/tribunal-kit",
39
49
  "repository": {
@@ -67,20 +77,22 @@
67
77
  "changelog:preview": "node scripts/changelog.js --preview",
68
78
  "sync": "node scripts/sync-version.js",
69
79
  "validate-payload": "node scripts/validate-payload.js",
80
+ "benchmark": "node scripts/benchmark.js",
81
+ "benchmark:rust": "cargo build --release && node scripts/benchmark.js",
70
82
  "build": "echo 'No build step required for this project'"
71
83
  },
72
84
  "devDependencies": {
73
85
  "eslint": "^9.1.1",
74
- "jest": "^25.0.0",
86
+ "jest": "^30.4.2",
75
87
  "typescript": "^5.4.5"
76
88
  },
77
89
  "optionalDependencies": {
78
- "@tribunal-kit/core-darwin-arm64": "^4.5.1",
79
- "@tribunal-kit/core-darwin-x64": "^4.5.1",
80
- "@tribunal-kit/core-linux-arm64": "^4.5.1",
81
- "@tribunal-kit/core-linux-x64": "^4.5.1",
82
- "@tribunal-kit/core-win32-arm64": "^4.5.1",
83
- "@tribunal-kit/core-win32-x64": "^4.5.1"
90
+ "@tribunal-kit/core-darwin-arm64": "^5.8.1",
91
+ "@tribunal-kit/core-darwin-x64": "^5.8.1",
92
+ "@tribunal-kit/core-linux-arm64": "^5.8.1",
93
+ "@tribunal-kit/core-linux-x64": "^5.8.1",
94
+ "@tribunal-kit/core-win32-arm64": "^5.8.1",
95
+ "@tribunal-kit/core-win32-x64": "^5.8.1"
84
96
  },
85
97
  "jest": {
86
98
  "testMatch": [