tribunal-kit 5.7.0 → 5.8.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/.agent/ARCHITECTURE.md +6 -7
- package/.agent/agents/frontend-reviewer.md +13 -0
- package/.agent/agents/frontend-specialist.md +14 -0
- package/.agent/agents/logic-reviewer.md +11 -0
- package/.agent/agents/orchestrator.md +15 -0
- package/.agent/agents/security-auditor.md +13 -0
- package/.agent/agents/ui-ux-auditor.md +7 -31
- package/.agent/history/memory/.memory.idx +766 -0
- package/.agent/history/memory/MEMORY.md +62 -0
- package/.agent/routing_index.json +694 -714
- package/.agent/rules/GEMINI.md +58 -8
- package/.agent/scripts/_colors.js +131 -89
- package/.agent/scripts/_utils.js +163 -128
- package/.agent/scripts/auto_preview.js +207 -197
- package/.agent/scripts/bundle_analyzer.js +227 -192
- package/.agent/scripts/case_law_manager.js +991 -689
- package/.agent/scripts/checklist.js +233 -190
- package/.agent/scripts/context_broker.js +930 -605
- package/.agent/scripts/dependency_analyzer.js +275 -184
- package/.agent/scripts/graph_builder.js +412 -341
- package/.agent/scripts/graph_visualizer.js +392 -390
- package/.agent/scripts/graph_zoom.js +198 -156
- package/.agent/scripts/inner_loop_validator.js +523 -445
- package/.agent/scripts/lint_runner.js +199 -157
- package/.agent/scripts/marathon_harness.js +819 -661
- package/.agent/scripts/minify_context.js +115 -100
- package/.agent/scripts/mutation_runner.js +321 -280
- package/.agent/scripts/prompt_compiler.js +62 -42
- package/.agent/scripts/schema_validator.js +373 -280
- package/.agent/scripts/security_scan.js +333 -190
- package/.agent/scripts/session_manager.js +306 -270
- package/.agent/scripts/skill_evolution.js +810 -637
- package/.agent/scripts/skill_integrator.js +327 -307
- package/.agent/scripts/strengthen_skills.js +203 -193
- package/.agent/scripts/swarm_dispatcher.js +558 -457
- package/.agent/scripts/test_runner.js +178 -152
- package/.agent/scripts/verify_all.js +200 -168
- package/.agent/skills/fabel-protocol/SKILL.md +235 -0
- package/.agent/skills/thinking-protocol/SKILL.md +27 -0
- package/.agent/workflows/generate.md +1 -1
- package/.agent/workflows/tribunal-speed.md +1 -1
- package/README.md +53 -53
- package/bin/mcp-server.js +460 -175
- package/bin/tribunal-kit.js +1245 -987
- package/bin/wrapper.js +104 -74
- package/dist/cli.js +31 -0
- package/dist/commands/case.js +23 -0
- package/dist/commands/compile.js +84 -0
- package/dist/commands/init.js +42 -0
- package/dist/commands/learn.js +57 -0
- package/dist/commands/memory.js +456 -0
- package/package.json +2 -2
- package/scripts/benchmark.js +162 -125
- package/scripts/changelog.js +196 -168
- package/scripts/sync-version.js +94 -81
- package/scripts/validate-payload.js +85 -78
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tribunal-kit",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.8.0",
|
|
4
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.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"eslint": "^9.1.1",
|
|
74
|
-
"jest": "^
|
|
74
|
+
"jest": "^30.4.2",
|
|
75
75
|
"typescript": "^5.4.5"
|
|
76
76
|
},
|
|
77
77
|
"optionalDependencies": {
|