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.
Files changed (56) 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/security-auditor.md +13 -0
  7. package/.agent/agents/ui-ux-auditor.md +7 -31
  8. package/.agent/history/memory/.memory.idx +766 -0
  9. package/.agent/history/memory/MEMORY.md +62 -0
  10. package/.agent/routing_index.json +694 -714
  11. package/.agent/rules/GEMINI.md +58 -8
  12. package/.agent/scripts/_colors.js +131 -89
  13. package/.agent/scripts/_utils.js +163 -128
  14. package/.agent/scripts/auto_preview.js +207 -197
  15. package/.agent/scripts/bundle_analyzer.js +227 -192
  16. package/.agent/scripts/case_law_manager.js +991 -689
  17. package/.agent/scripts/checklist.js +233 -190
  18. package/.agent/scripts/context_broker.js +930 -605
  19. package/.agent/scripts/dependency_analyzer.js +275 -184
  20. package/.agent/scripts/graph_builder.js +412 -341
  21. package/.agent/scripts/graph_visualizer.js +392 -390
  22. package/.agent/scripts/graph_zoom.js +198 -156
  23. package/.agent/scripts/inner_loop_validator.js +523 -445
  24. package/.agent/scripts/lint_runner.js +199 -157
  25. package/.agent/scripts/marathon_harness.js +819 -661
  26. package/.agent/scripts/minify_context.js +115 -100
  27. package/.agent/scripts/mutation_runner.js +321 -280
  28. package/.agent/scripts/prompt_compiler.js +62 -42
  29. package/.agent/scripts/schema_validator.js +373 -280
  30. package/.agent/scripts/security_scan.js +333 -190
  31. package/.agent/scripts/session_manager.js +306 -270
  32. package/.agent/scripts/skill_evolution.js +810 -637
  33. package/.agent/scripts/skill_integrator.js +327 -307
  34. package/.agent/scripts/strengthen_skills.js +203 -193
  35. package/.agent/scripts/swarm_dispatcher.js +558 -457
  36. package/.agent/scripts/test_runner.js +178 -152
  37. package/.agent/scripts/verify_all.js +200 -168
  38. package/.agent/skills/fabel-protocol/SKILL.md +235 -0
  39. package/.agent/skills/thinking-protocol/SKILL.md +27 -0
  40. package/.agent/workflows/generate.md +1 -1
  41. package/.agent/workflows/tribunal-speed.md +1 -1
  42. package/README.md +53 -53
  43. package/bin/mcp-server.js +460 -175
  44. package/bin/tribunal-kit.js +1245 -987
  45. package/bin/wrapper.js +104 -74
  46. package/dist/cli.js +31 -0
  47. package/dist/commands/case.js +23 -0
  48. package/dist/commands/compile.js +84 -0
  49. package/dist/commands/init.js +42 -0
  50. package/dist/commands/learn.js +57 -0
  51. package/dist/commands/memory.js +456 -0
  52. package/package.json +2 -2
  53. package/scripts/benchmark.js +162 -125
  54. package/scripts/changelog.js +196 -168
  55. package/scripts/sync-version.js +94 -81
  56. package/scripts/validate-payload.js +85 -78
@@ -9,41 +9,50 @@
9
9
  * node .agent/scripts/verify_all.js --skip build,deps
10
10
  */
11
11
 
12
- 'use strict';
12
+ "use strict";
13
13
 
14
- const fs = require('fs');
15
- const path = require('path');
16
- const { execFileSync } = require('child_process');
14
+ const fs = require("fs");
15
+ const path = require("path");
16
+ const { execFileSync } = require("child_process");
17
17
 
18
18
  const {
19
- RED, GREEN, YELLOW, BLUE, BOLD, DIM, CYAN, RESET,
20
- banner, sectionHeader, summaryTable, timer, formatMs,
21
- ok, fail, skip,
22
- } = require('./_colors');
23
-
24
- const { walkDir, hasNpm, SOURCE_EXTENSIONS } = require('./_utils');
19
+ RED,
20
+ GREEN,
21
+ YELLOW,
22
+ BOLD,
23
+ DIM,
24
+ CYAN,
25
+ RESET,
26
+ banner,
27
+ sectionHeader,
28
+ summaryTable,
29
+ timer,
30
+ formatMs,
31
+ } = require("./_colors");
32
+
33
+ const { walkDir, hasNpm } = require("./_utils");
25
34
 
26
35
  // ── Results Tracking ────────────────────────────────────────────────────────
27
36
 
28
37
  const RESULTS = [];
29
38
 
30
39
  function trackOk(label, ms, note) {
31
- const timing = ms != null ? `${DIM}(${formatMs(ms)})${RESET}` : '';
32
- const noteStr = note ? ` ${DIM}${note}${RESET}` : '';
33
- console.log(` ${GREEN}✅ ${label}${RESET} ${timing}${noteStr}`);
34
- RESULTS.push({ name: label, status: 'pass', ms, note: note || '' });
40
+ const timing = ms != null ? `${DIM}(${formatMs(ms)})${RESET}` : "";
41
+ const noteStr = note ? ` ${DIM}${note}${RESET}` : "";
42
+ console.log(` ${GREEN}✅ ${label}${RESET} ${timing}${noteStr}`);
43
+ RESULTS.push({ name: label, status: "pass", ms, note: note || "" });
35
44
  }
36
45
 
37
46
  function trackFail(label, ms, note) {
38
- const timing = ms != null ? `${DIM}(${formatMs(ms)})${RESET}` : '';
39
- const noteStr = note ? `\n ${note}` : '';
40
- console.log(` ${RED}❌ ${label}${RESET} ${timing}${noteStr}`);
41
- RESULTS.push({ name: label, status: 'fail', ms, note: note || '' });
47
+ const timing = ms != null ? `${DIM}(${formatMs(ms)})${RESET}` : "";
48
+ const noteStr = note ? `\n ${note}` : "";
49
+ console.log(` ${RED}❌ ${label}${RESET} ${timing}${noteStr}`);
50
+ RESULTS.push({ name: label, status: "fail", ms, note: note || "" });
42
51
  }
43
52
 
44
53
  function trackSkip(label, reason) {
45
- console.log(` ${YELLOW}⏭️ ${label} — ${reason}${RESET}`);
46
- RESULTS.push({ name: label, status: 'skip', note: `skipped: ${reason}` });
54
+ console.log(` ${YELLOW}⏭️ ${label} — ${reason}${RESET}`);
55
+ RESULTS.push({ name: label, status: "skip", note: `skipped: ${reason}` });
47
56
  }
48
57
 
49
58
  // ── Command Runner ──────────────────────────────────────────────────────────
@@ -52,197 +61,220 @@ function trackSkip(label, reason) {
52
61
  * Run a shell command and return true if it exits with code 0.
53
62
  */
54
63
  function run(label, cmd, cwd) {
55
- const elapsed = timer();
56
- try {
57
- const isWindows = process.platform === 'win32';
58
-
59
- execFileSync(cmd[0], cmd.slice(1), {
60
- cwd,
61
- stdio: 'pipe',
62
- timeout: 120000,
63
- encoding: 'utf8',
64
- shell: isWindows
65
- });
66
- trackOk(label, elapsed());
67
- return true;
68
- } catch (err) {
69
- const ms = elapsed();
70
- if (err.code === 'ENOENT') {
71
- trackSkip(label, 'tool not installed — skipping');
72
- return true;
73
- }
74
- if (err.killed) {
75
- trackFail(label, ms, 'timed out after 120s');
76
- return false;
77
- }
78
- const output = ((err.stdout || '') + (err.stderr || '')).trim();
79
- trackFail(label, ms, output ? output.slice(0, 500) : 'non-zero exit code');
80
- return false;
64
+ const elapsed = timer();
65
+ try {
66
+ const isWindows = process.platform === "win32";
67
+
68
+ execFileSync(cmd[0], cmd.slice(1), {
69
+ cwd,
70
+ stdio: "pipe",
71
+ timeout: 120000,
72
+ encoding: "utf8",
73
+ shell: isWindows,
74
+ });
75
+ trackOk(label, elapsed());
76
+ return true;
77
+ } catch (err) {
78
+ const ms = elapsed();
79
+ if (err.code === "ENOENT") {
80
+ trackSkip(label, "tool not installed — skipping");
81
+ return true;
81
82
  }
83
+ if (err.killed) {
84
+ trackFail(label, ms, "timed out after 120s");
85
+ return false;
86
+ }
87
+ const output = ((err.stdout || "") + (err.stderr || "")).trim();
88
+ trackFail(label, ms, output ? output.slice(0, 500) : "non-zero exit code");
89
+ return false;
90
+ }
82
91
  }
83
92
 
84
-
85
93
  /**
86
94
  * Scan source files for obviously hardcoded credentials.
87
95
  * Uses shared walkDir from _utils.js to eliminate duplicated walker code.
88
96
  */
89
97
  function scanSecrets(cwd) {
90
- const elapsed = timer();
91
- const patterns = ['password=', 'secret=', 'api_key=', 'private_key=', 'auth_token='];
92
- const found = [];
93
-
94
- const sourceExtensions = new Set(['.ts', '.tsx', '.js', '.jsx', '.py']);
95
- const files = walkDir(cwd, { extensions: sourceExtensions });
96
-
97
- for (const fullPath of files) {
98
- let content;
99
- try { content = fs.readFileSync(fullPath, 'utf8'); } catch { continue; }
100
-
101
- const lines = content.split('\n');
102
- for (let i = 0; i < lines.length; i++) {
103
- const low = lines[i].toLowerCase().trim();
104
- const hasPattern = patterns.some(p => low.includes(p));
105
- if (hasPattern && !low.startsWith('#') && low.includes('=')) {
106
- const rel = path.relative(cwd, fullPath);
107
- found.push(`${rel}:${i + 1}`);
108
- }
109
- }
98
+ const elapsed = timer();
99
+ const patterns = [
100
+ "password=",
101
+ "secret=",
102
+ "api_key=",
103
+ "private_key=",
104
+ "auth_token=",
105
+ ];
106
+ const found = [];
107
+
108
+ const sourceExtensions = new Set([".ts", ".tsx", ".js", ".jsx", ".py"]);
109
+ const files = walkDir(cwd, { extensions: sourceExtensions });
110
+
111
+ for (const fullPath of files) {
112
+ let content;
113
+ try {
114
+ content = fs.readFileSync(fullPath, "utf8");
115
+ } catch {
116
+ continue;
110
117
  }
111
118
 
112
- const ms = elapsed();
113
- if (found.length > 0) {
114
- trackFail('Secret scan', ms, found.slice(0, 5).join('\n '));
115
- return false;
119
+ const lines = content.split("\n");
120
+ for (let i = 0; i < lines.length; i++) {
121
+ const low = lines[i].toLowerCase().trim();
122
+ const hasPattern = patterns.some((p) => low.includes(p));
123
+ if (hasPattern && !low.startsWith("#") && low.includes("=")) {
124
+ const rel = path.relative(cwd, fullPath);
125
+ found.push(`${rel}:${i + 1}`);
126
+ }
116
127
  }
117
- trackOk('Secret scan — no hardcoded credentials found', ms, `${files.length} files scanned`);
118
- return true;
128
+ }
129
+
130
+ const ms = elapsed();
131
+ if (found.length > 0) {
132
+ trackFail("Secret scan", ms, found.slice(0, 5).join("\n "));
133
+ return false;
134
+ }
135
+ trackOk(
136
+ "Secret scan — no hardcoded credentials found",
137
+ ms,
138
+ `${files.length} files scanned`,
139
+ );
140
+ return true;
119
141
  }
120
142
 
121
-
122
143
  /**
123
144
  * Run all verification checks. Returns number of failures.
124
145
  */
125
146
  function verifyAll(cwd, skipped) {
126
- let failures = 0;
127
- RESULTS.length = 0; // Reset for clean runs (prevents accumulation in tests)
128
- const totalTimer = timer();
129
-
130
- console.log(sectionHeader('Secret Scan', 1));
131
- if (!skipped.includes('secrets')) {
132
- if (!scanSecrets(cwd)) failures++;
147
+ let failures = 0;
148
+ RESULTS.length = 0; // Reset for clean runs (prevents accumulation in tests)
149
+ const totalTimer = timer();
150
+
151
+ console.log(sectionHeader("Secret Scan", 1));
152
+ if (!skipped.includes("secrets")) {
153
+ if (!scanSecrets(cwd)) failures++;
154
+ } else {
155
+ trackSkip("Secret scan", "skipped by flag");
156
+ }
157
+
158
+ console.log(sectionHeader("TypeScript", 2));
159
+ if (!skipped.includes("typescript")) {
160
+ if (hasNpm(cwd)) {
161
+ if (!run("tsc --noEmit", ["npx", "tsc", "--noEmit"], cwd)) failures++;
133
162
  } else {
134
- trackSkip('Secret scan', 'skipped by flag');
163
+ trackSkip("TypeScript", "no package.json found in project");
135
164
  }
136
-
137
- console.log(sectionHeader('TypeScript', 2));
138
- if (!skipped.includes('typescript')) {
139
- if (hasNpm(cwd)) {
140
- if (!run('tsc --noEmit', ['npx', 'tsc', '--noEmit'], cwd)) failures++;
141
- } else {
142
- trackSkip('TypeScript', 'no package.json found in project');
143
- }
165
+ } else {
166
+ trackSkip("TypeScript", "skipped by flag");
167
+ }
168
+
169
+ console.log(sectionHeader("ESLint", 3));
170
+ if (!skipped.includes("lint")) {
171
+ if (hasNpm(cwd)) {
172
+ if (!run("ESLint", ["npx", "eslint", ".", "--max-warnings=0"], cwd))
173
+ failures++;
144
174
  } else {
145
- trackSkip('TypeScript', 'skipped by flag');
175
+ trackSkip("ESLint", "no package.json found in project");
146
176
  }
147
-
148
- console.log(sectionHeader('ESLint', 3));
149
- if (!skipped.includes('lint')) {
150
- if (hasNpm(cwd)) {
151
- if (!run('ESLint', ['npx', 'eslint', '.', '--max-warnings=0'], cwd)) failures++;
152
- } else {
153
- trackSkip('ESLint', 'no package.json found in project');
154
- }
177
+ } else {
178
+ trackSkip("ESLint", "skipped by flag");
179
+ }
180
+
181
+ console.log(sectionHeader("Unit Tests", 4));
182
+ if (!skipped.includes("tests")) {
183
+ if (hasNpm(cwd)) {
184
+ if (!run("Test suite", ["npm", "test", "--", "--passWithNoTests"], cwd))
185
+ failures++;
155
186
  } else {
156
- trackSkip('ESLint', 'skipped by flag');
187
+ trackSkip("Tests", "no package.json found in project");
157
188
  }
158
-
159
- console.log(sectionHeader('Unit Tests', 4));
160
- if (!skipped.includes('tests')) {
161
- if (hasNpm(cwd)) {
162
- if (!run('Test suite', ['npm', 'test', '--', '--passWithNoTests'], cwd)) failures++;
163
- } else {
164
- trackSkip('Tests', 'no package.json found in project');
165
- }
189
+ } else {
190
+ trackSkip("Tests", "skipped by flag");
191
+ }
192
+
193
+ console.log(sectionHeader("Build", 5));
194
+ if (!skipped.includes("build")) {
195
+ if (hasNpm(cwd)) {
196
+ if (!run("npm run build", ["npm", "run", "build"], cwd)) failures++;
166
197
  } else {
167
- trackSkip('Tests', 'skipped by flag');
198
+ trackSkip("Build", "no package.json found in project");
168
199
  }
169
-
170
- console.log(sectionHeader('Build', 5));
171
- if (!skipped.includes('build')) {
172
- if (hasNpm(cwd)) {
173
- if (!run('npm run build', ['npm', 'run', 'build'], cwd)) failures++;
174
- } else {
175
- trackSkip('Build', 'no package.json found in project');
176
- }
200
+ } else {
201
+ trackSkip("Build", "skipped by flag");
202
+ }
203
+
204
+ console.log(sectionHeader("Dependency Audit", 6));
205
+ if (!skipped.includes("deps")) {
206
+ if (hasNpm(cwd)) {
207
+ if (!run("npm audit", ["npm", "audit", "--audit-level=high"], cwd))
208
+ failures++;
177
209
  } else {
178
- trackSkip('Build', 'skipped by flag');
210
+ trackSkip("Dependency audit", "no package.json found in project");
179
211
  }
180
-
181
- console.log(sectionHeader('Dependency Audit', 6));
182
- if (!skipped.includes('deps')) {
183
- if (hasNpm(cwd)) {
184
- if (!run('npm audit', ['npm', 'audit', '--audit-level=high'], cwd)) failures++;
185
- } else {
186
- trackSkip('Dependency audit', 'no package.json found in project');
187
- }
188
- } else {
189
- trackSkip('Dependency audit', 'skipped by flag');
190
- }
191
-
192
- // ━━━ Summary Table ━━━
193
- const totalMs = totalTimer();
194
- console.log(`\n${BOLD}${CYAN}━━━ Verification Summary ━━━${RESET}`);
195
- summaryTable(RESULTS);
196
-
197
- const passCount = RESULTS.filter(r => r.status === 'pass').length;
198
- const failCount = RESULTS.filter(r => r.status === 'fail').length;
199
- const skipCount = RESULTS.filter(r => r.status === 'skip').length;
200
-
201
- console.log(`\n ${DIM}Total: ${RESULTS.length} checks in ${formatMs(totalMs)}${RESET}`);
202
- console.log(` ${GREEN}${passCount} passed${RESET} ${failCount > 0 ? `${RED}${failCount} failed${RESET} ` : ''}${skipCount > 0 ? `${YELLOW}${skipCount} skipped${RESET}` : ''}`);
203
-
204
- console.log();
205
- if (failures === 0) {
206
- console.log(`${GREEN}${BOLD} ✔ All checks passed — safe to deploy.${RESET}`);
207
- } else {
208
- console.log(`${RED}${BOLD} ✖ ${failures} check(s) failed — fix before deploying.${RESET}`);
209
- }
210
- console.log();
211
-
212
- return failures;
212
+ } else {
213
+ trackSkip("Dependency audit", "skipped by flag");
214
+ }
215
+
216
+ // ━━━ Summary Table ━━━
217
+ const totalMs = totalTimer();
218
+ console.log(`\n${BOLD}${CYAN}━━━ Verification Summary ━━━${RESET}`);
219
+ summaryTable(RESULTS);
220
+
221
+ const passCount = RESULTS.filter((r) => r.status === "pass").length;
222
+ const failCount = RESULTS.filter((r) => r.status === "fail").length;
223
+ const skipCount = RESULTS.filter((r) => r.status === "skip").length;
224
+
225
+ console.log(
226
+ `\n ${DIM}Total: ${RESULTS.length} checks in ${formatMs(totalMs)}${RESET}`,
227
+ );
228
+ console.log(
229
+ ` ${GREEN}${passCount} passed${RESET} ${failCount > 0 ? `${RED}${failCount} failed${RESET} ` : ""}${skipCount > 0 ? `${YELLOW}${skipCount} skipped${RESET}` : ""}`,
230
+ );
231
+
232
+ console.log();
233
+ if (failures === 0) {
234
+ console.log(
235
+ `${GREEN}${BOLD} ✔ All checks passed — safe to deploy.${RESET}`,
236
+ );
237
+ } else {
238
+ console.log(
239
+ `${RED}${BOLD} ✖ ${failures} check(s) failed — fix before deploying.${RESET}`,
240
+ );
241
+ }
242
+ console.log();
243
+
244
+ return failures;
213
245
  }
214
246
 
215
-
216
247
  /**
217
248
  * Parse CLI arguments manually (no external dependencies).
218
249
  */
219
250
  function parseArgs(argv) {
220
- const args = { skip: [] };
221
- const raw = argv.slice(2);
222
-
223
- for (let i = 0; i < raw.length; i++) {
224
- if (raw[i] === '--skip' && raw[i + 1]) {
225
- args.skip = raw[++i].split(',').map(s => s.trim().toLowerCase()).filter(Boolean);
226
- }
251
+ const args = { skip: [] };
252
+ const raw = argv.slice(2);
253
+
254
+ for (let i = 0; i < raw.length; i++) {
255
+ if (raw[i] === "--skip" && raw[i + 1]) {
256
+ args.skip = raw[++i]
257
+ .split(",")
258
+ .map((s) => s.trim().toLowerCase())
259
+ .filter(Boolean);
227
260
  }
228
- return args;
261
+ }
262
+ return args;
229
263
  }
230
264
 
231
-
232
265
  function main() {
233
- const args = parseArgs(process.argv);
234
- const cwd = process.cwd();
266
+ const args = parseArgs(process.argv);
267
+ const cwd = process.cwd();
235
268
 
236
- console.log(banner('verify_all.js', { Project: cwd }));
269
+ console.log(banner("verify_all.js", { Project: cwd }));
237
270
 
238
- const failures = verifyAll(cwd, args.skip);
239
- process.exit(failures > 0 ? 1 : 0);
271
+ const failures = verifyAll(cwd, args.skip);
272
+ process.exit(failures > 0 ? 1 : 0);
240
273
  }
241
274
 
242
-
243
275
  // ━━━ Exports for testing & programmatic use ━━━
244
276
  module.exports = { verifyAll, scanSecrets, hasNpm };
245
277
 
246
278
  if (require.main === module) {
247
- main();
279
+ main();
248
280
  }