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
|
@@ -17,43 +17,52 @@
|
|
|
17
17
|
* node .agent/scripts/checklist.js . --skip security,seo
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
"use strict";
|
|
21
21
|
|
|
22
|
-
const fs
|
|
23
|
-
const path = require(
|
|
24
|
-
const { execFileSync } = require(
|
|
22
|
+
const fs = require("fs");
|
|
23
|
+
const path = require("path");
|
|
24
|
+
const { execFileSync } = require("child_process");
|
|
25
25
|
|
|
26
26
|
const {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
RED,
|
|
28
|
+
GREEN,
|
|
29
|
+
YELLOW,
|
|
30
|
+
BOLD,
|
|
31
|
+
DIM,
|
|
32
|
+
CYAN,
|
|
33
|
+
RESET,
|
|
34
|
+
banner,
|
|
35
|
+
sectionHeader,
|
|
36
|
+
summaryTable,
|
|
37
|
+
timer,
|
|
38
|
+
formatMs,
|
|
39
|
+
fail,
|
|
40
|
+
} = require("./_colors");
|
|
41
|
+
|
|
42
|
+
const { walkDir } = require("./_utils");
|
|
33
43
|
|
|
34
44
|
// ── Results Tracking ────────────────────────────────────────────────────────
|
|
35
45
|
|
|
36
46
|
const RESULTS = [];
|
|
37
47
|
|
|
38
48
|
function trackOk(label, ms) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
const timing = ms != null ? `${DIM}(${formatMs(ms)})${RESET}` : "";
|
|
50
|
+
console.log(` ${GREEN}✅ ${label}${RESET} ${timing}`);
|
|
51
|
+
RESULTS.push({ name: label, status: "pass", ms });
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
function trackFail(label, ms, note) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
const timing = ms != null ? `${DIM}(${formatMs(ms)})${RESET}` : "";
|
|
56
|
+
console.log(` ${RED}❌ ${label}${RESET} ${timing}`);
|
|
57
|
+
if (note) console.log(` ${note.slice(0, 500)}`);
|
|
58
|
+
RESULTS.push({ name: label, status: "fail", ms });
|
|
49
59
|
}
|
|
50
60
|
|
|
51
61
|
function trackSkip(label, reason) {
|
|
52
|
-
|
|
53
|
-
|
|
62
|
+
console.log(` ${YELLOW}⏭️ ${label} — ${reason}${RESET}`);
|
|
63
|
+
RESULTS.push({ name: label, status: "skip" });
|
|
54
64
|
}
|
|
55
65
|
|
|
56
|
-
|
|
57
66
|
/**
|
|
58
67
|
* Run a shell command and return true if it exits with code 0.
|
|
59
68
|
* @param {string} label - Human-readable label for the check.
|
|
@@ -62,34 +71,33 @@ function trackSkip(label, reason) {
|
|
|
62
71
|
* @returns {boolean}
|
|
63
72
|
*/
|
|
64
73
|
function runCheck(label, cmd, cwd) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
const output = ((err.stdout || '') + (err.stderr || '')).trim();
|
|
87
|
-
trackFail(`${label} failed`, ms, output || 'non-zero exit code');
|
|
88
|
-
return false;
|
|
74
|
+
const elapsed = timer();
|
|
75
|
+
try {
|
|
76
|
+
execFileSync(cmd[0], cmd.slice(1), {
|
|
77
|
+
cwd,
|
|
78
|
+
stdio: "pipe",
|
|
79
|
+
timeout: 60000,
|
|
80
|
+
encoding: "utf8",
|
|
81
|
+
shell: process.platform === "win32",
|
|
82
|
+
});
|
|
83
|
+
trackOk(`${label} passed`, elapsed());
|
|
84
|
+
return true;
|
|
85
|
+
} catch (err) {
|
|
86
|
+
const ms = elapsed();
|
|
87
|
+
if (err.code === "ENOENT") {
|
|
88
|
+
trackSkip(label, "command not found (tool not installed)");
|
|
89
|
+
return true; // Don't block on tools that aren't installed
|
|
90
|
+
}
|
|
91
|
+
if (err.killed) {
|
|
92
|
+
trackFail(label, ms, "timed out after 60s");
|
|
93
|
+
return false;
|
|
89
94
|
}
|
|
95
|
+
const output = ((err.stdout || "") + (err.stderr || "")).trim();
|
|
96
|
+
trackFail(`${label} failed`, ms, output || "non-zero exit code");
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
90
99
|
}
|
|
91
100
|
|
|
92
|
-
|
|
93
101
|
/**
|
|
94
102
|
* Scan for hardcoded secrets in source files.
|
|
95
103
|
* Uses shared walkDir from _utils.js.
|
|
@@ -97,45 +105,54 @@ function runCheck(label, cmd, cwd) {
|
|
|
97
105
|
* @returns {boolean} True if no secrets found.
|
|
98
106
|
*/
|
|
99
107
|
function checkSecrets(projectRoot) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
fail(`Possible secret: ${rel}:${i + 1} → ${lines[i].trim().slice(0, 80)}`);
|
|
124
|
-
foundIssues = true;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
108
|
+
const elapsed = timer();
|
|
109
|
+
const dangerousPatterns = [
|
|
110
|
+
"password=",
|
|
111
|
+
"secret=",
|
|
112
|
+
"api_key=",
|
|
113
|
+
"apikey=",
|
|
114
|
+
"auth_token=",
|
|
115
|
+
"private_key=",
|
|
116
|
+
];
|
|
117
|
+
let foundIssues = false;
|
|
118
|
+
const sourceExtensions = new Set([".ts", ".tsx", ".js", ".jsx", ".py"]);
|
|
119
|
+
|
|
120
|
+
const files = walkDir(projectRoot, { extensions: sourceExtensions });
|
|
121
|
+
|
|
122
|
+
for (const fullPath of files) {
|
|
123
|
+
// Skip .env files — they are allowed to contain secrets
|
|
124
|
+
if (path.basename(fullPath).startsWith(".env")) continue;
|
|
125
|
+
|
|
126
|
+
let content;
|
|
127
|
+
try {
|
|
128
|
+
content = fs.readFileSync(fullPath, "utf8");
|
|
129
|
+
} catch {
|
|
130
|
+
continue;
|
|
127
131
|
}
|
|
128
132
|
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
const lines = content.split("\n");
|
|
134
|
+
for (let i = 0; i < lines.length; i++) {
|
|
135
|
+
const lineLower = lines[i].toLowerCase().trim();
|
|
136
|
+
const hasPattern = dangerousPatterns.some((p) => lineLower.includes(p));
|
|
137
|
+
if (hasPattern && lineLower.includes("=") && !lineLower.startsWith("#")) {
|
|
138
|
+
const rel = path.relative(projectRoot, fullPath);
|
|
139
|
+
fail(
|
|
140
|
+
`Possible secret: ${rel}:${i + 1} → ${lines[i].trim().slice(0, 80)}`,
|
|
141
|
+
);
|
|
142
|
+
foundIssues = true;
|
|
143
|
+
}
|
|
134
144
|
}
|
|
135
|
-
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const ms = elapsed();
|
|
148
|
+
if (!foundIssues) {
|
|
149
|
+
trackOk(`Secret scan — ${files.length} files clean`, ms);
|
|
150
|
+
} else {
|
|
151
|
+
trackFail("Secret scan — hardcoded credentials detected", ms);
|
|
152
|
+
}
|
|
153
|
+
return !foundIssues;
|
|
136
154
|
}
|
|
137
155
|
|
|
138
|
-
|
|
139
156
|
/**
|
|
140
157
|
* Run all checklist tiers. Returns number of failures.
|
|
141
158
|
* @param {string} projectRoot - Project root.
|
|
@@ -144,135 +161,161 @@ function checkSecrets(projectRoot) {
|
|
|
144
161
|
* @returns {number}
|
|
145
162
|
*/
|
|
146
163
|
function runAll(projectRoot, url, skipTiers) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
console.log(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
164
|
+
let failures = 0;
|
|
165
|
+
RESULTS.length = 0;
|
|
166
|
+
const totalTimer = timer();
|
|
167
|
+
|
|
168
|
+
// Priority 1 — Security
|
|
169
|
+
if (!skipTiers.includes("security")) {
|
|
170
|
+
console.log(sectionHeader("Security — Secret Scan", 1));
|
|
171
|
+
if (!checkSecrets(projectRoot)) failures++;
|
|
172
|
+
} else {
|
|
173
|
+
trackSkip("Security", "skipped by flag");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Priority 2 — Lint
|
|
177
|
+
if (!skipTiers.includes("lint")) {
|
|
178
|
+
console.log(sectionHeader("Lint", 2));
|
|
179
|
+
if (
|
|
180
|
+
!runCheck(
|
|
181
|
+
"ESLint",
|
|
182
|
+
["npx", "eslint", ".", "--max-warnings=0"],
|
|
183
|
+
projectRoot,
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
failures++;
|
|
187
|
+
if (!runCheck("TypeScript", ["npx", "tsc", "--noEmit"], projectRoot))
|
|
188
|
+
failures++;
|
|
189
|
+
} else {
|
|
190
|
+
trackSkip("Lint", "skipped by flag");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Priority 3 — Schema
|
|
194
|
+
if (!skipTiers.includes("schema")) {
|
|
195
|
+
console.log(sectionHeader("Schema Validation", 3));
|
|
196
|
+
trackSkip("Schema", "run manually if you have DB migrations");
|
|
197
|
+
} else {
|
|
198
|
+
trackSkip("Schema", "skipped by flag");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Priority 4 — Tests
|
|
202
|
+
if (!skipTiers.includes("tests")) {
|
|
203
|
+
console.log(sectionHeader("Tests", 4));
|
|
204
|
+
if (
|
|
205
|
+
!runCheck(
|
|
206
|
+
"Test suite",
|
|
207
|
+
["npm", "test", "--", "--passWithNoTests"],
|
|
208
|
+
projectRoot,
|
|
209
|
+
)
|
|
210
|
+
)
|
|
211
|
+
failures++;
|
|
212
|
+
} else {
|
|
213
|
+
trackSkip("Tests", "skipped by flag");
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Priority 5 — UX
|
|
217
|
+
if (!skipTiers.includes("ux")) {
|
|
218
|
+
console.log(sectionHeader("UX / Accessibility", 5));
|
|
219
|
+
trackSkip("UX audit", "run /preview start then check with Lighthouse");
|
|
220
|
+
} else {
|
|
221
|
+
trackSkip("UX", "skipped by flag");
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Priority 6 — SEO
|
|
225
|
+
if (!skipTiers.includes("seo")) {
|
|
226
|
+
console.log(sectionHeader("SEO", 6));
|
|
227
|
+
trackSkip("SEO check", "use /ui-ux-pro-max for SEO-sensitive pages");
|
|
228
|
+
} else {
|
|
229
|
+
trackSkip("SEO", "skipped by flag");
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Priority 7 — Lighthouse / E2E
|
|
233
|
+
if (url && !skipTiers.includes("e2e")) {
|
|
234
|
+
console.log(sectionHeader("Lighthouse / E2E", 7));
|
|
235
|
+
if (!runCheck("Playwright E2E", ["npx", "playwright", "test"], projectRoot))
|
|
236
|
+
failures++;
|
|
237
|
+
} else if (!url) {
|
|
238
|
+
trackSkip("E2E / Lighthouse", "pass --url to enable");
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ━━━ Summary ━━━
|
|
242
|
+
const totalMs = totalTimer();
|
|
243
|
+
console.log(`\n${BOLD}${CYAN}━━━ Checklist Summary ━━━${RESET}`);
|
|
244
|
+
summaryTable(RESULTS);
|
|
245
|
+
|
|
246
|
+
const passCount = RESULTS.filter((r) => r.status === "pass").length;
|
|
247
|
+
const failCount = RESULTS.filter((r) => r.status === "fail").length;
|
|
248
|
+
const skipCount = RESULTS.filter((r) => r.status === "skip").length;
|
|
249
|
+
|
|
250
|
+
console.log(
|
|
251
|
+
`\n ${DIM}Total: ${RESULTS.length} checks in ${formatMs(totalMs)}${RESET}`,
|
|
252
|
+
);
|
|
253
|
+
console.log(
|
|
254
|
+
` ${GREEN}${passCount} passed${RESET} ${failCount > 0 ? `${RED}${failCount} failed${RESET} ` : ""}${skipCount > 0 ? `${YELLOW}${skipCount} skipped${RESET}` : ""}`,
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
console.log();
|
|
258
|
+
if (failures === 0) {
|
|
259
|
+
console.log(
|
|
260
|
+
`${GREEN}${BOLD} ✔ All checks passed — ready to proceed.${RESET}`,
|
|
261
|
+
);
|
|
262
|
+
} else {
|
|
263
|
+
console.log(
|
|
264
|
+
`${RED}${BOLD} ✖ ${failures} tier(s) failed — fix critical issues before proceeding.${RESET}`,
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
console.log();
|
|
268
|
+
|
|
269
|
+
return failures;
|
|
229
270
|
}
|
|
230
271
|
|
|
231
|
-
|
|
232
272
|
/**
|
|
233
273
|
* Parse CLI arguments manually (no external dependencies).
|
|
234
274
|
*/
|
|
235
275
|
function parseArgs(argv) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
276
|
+
const args = { path: null, url: null, skip: [] };
|
|
277
|
+
const raw = argv.slice(2);
|
|
278
|
+
|
|
279
|
+
for (let i = 0; i < raw.length; i++) {
|
|
280
|
+
if (raw[i] === "--url" && raw[i + 1]) {
|
|
281
|
+
args.url = raw[++i];
|
|
282
|
+
} else if (raw[i] === "--skip" && raw[i + 1]) {
|
|
283
|
+
args.skip = raw[++i]
|
|
284
|
+
.split(",")
|
|
285
|
+
.map((s) => s.trim().toLowerCase())
|
|
286
|
+
.filter(Boolean);
|
|
287
|
+
} else if (!raw[i].startsWith("--") && !args.path) {
|
|
288
|
+
args.path = raw[i];
|
|
247
289
|
}
|
|
248
|
-
|
|
290
|
+
}
|
|
291
|
+
return args;
|
|
249
292
|
}
|
|
250
293
|
|
|
251
|
-
|
|
252
294
|
function main() {
|
|
253
|
-
|
|
295
|
+
const args = parseArgs(process.argv);
|
|
254
296
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
297
|
+
if (!args.path) {
|
|
298
|
+
console.error(
|
|
299
|
+
`Usage: node checklist.js <path> [--url <url>] [--skip security,lint,schema,tests,ux,seo,e2e]`,
|
|
300
|
+
);
|
|
301
|
+
process.exit(1);
|
|
302
|
+
}
|
|
259
303
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
304
|
+
const projectRoot = path.resolve(args.path);
|
|
305
|
+
if (!fs.existsSync(projectRoot) || !fs.statSync(projectRoot).isDirectory()) {
|
|
306
|
+
fail(`Directory not found: ${projectRoot}`);
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
265
309
|
|
|
266
|
-
|
|
310
|
+
console.log(banner("checklist.js", { Project: projectRoot }));
|
|
267
311
|
|
|
268
|
-
|
|
269
|
-
|
|
312
|
+
const failures = runAll(projectRoot, args.url, args.skip);
|
|
313
|
+
process.exit(failures > 0 ? 1 : 0);
|
|
270
314
|
}
|
|
271
315
|
|
|
272
|
-
|
|
273
316
|
// ━━━ Exports for testing & programmatic use ━━━
|
|
274
317
|
module.exports = { runCheck, checkSecrets, runAll };
|
|
275
318
|
|
|
276
319
|
if (require.main === module) {
|
|
277
|
-
|
|
320
|
+
main();
|
|
278
321
|
}
|