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,6 +9,43 @@ Rule priority: this file (P0) agent .md file (P1) skill SKILL.md (P2)
9
9
 
10
10
  ---
11
11
 
12
+ ## Step 0 — Fabel Protocol (Before Everything)
13
+
14
+ Before classifying the request or routing to any agent, execute this cognitive loop:
15
+
16
+ ### 0a. Epistemic Check
17
+
18
+ ```
19
+ Do I KNOW this, or am I GUESSING?
20
+ → Guessing → mark // VERIFY: [reason] and search before answering.
21
+ Has this information possibly changed since my training?
22
+ → Yes → Search before answering. Never serve stale facts.
23
+ Am I importing a package/method that exists?
24
+ → Verify against package.json / requirements.txt / official docs.
25
+ ```
26
+
27
+ ### 0b. Response Format Decision
28
+
29
+ ```
30
+ Is the answer a single fact? → 1 sentence. No preamble.
31
+ Is it a technical explanation? → 1-3 paragraphs of prose. No bullets unless 4+ items.
32
+ Is it code (≤20 lines)? → Inline in response.
33
+ Is it code (>20 lines)? → Create a file.
34
+ Is it multifaceted (3+ points)? → Structured format justified.
35
+ Would the user scroll past this? → Make it scannable, not decorative.
36
+ ```
37
+
38
+ ### 0c. Precision Budget
39
+
40
+ ```
41
+ Simple fact → 1 tool call max
42
+ Medium task → 3-5 tool calls
43
+ Deep research → 5-10 tool calls
44
+ 20+ tool calls → Stop. Escalate to human. Scope is too large.
45
+ ```
46
+
47
+ ---
48
+
12
49
  ## Step 1 — Classify Every Request
13
50
 
14
51
  Before any action, identify request type:
@@ -97,17 +134,18 @@ For any complex build, new feature, or unclear request — stop and ask before w
97
134
 
98
135
  **Required questions by type:**
99
136
 
100
- | Request | Minimum Questions |
101
- | -------------------- | ----------------------------------------------- |
102
- | New feature or build | 3+ strategic questions about goal, stack, scope |
103
- | Code edit or bug fix | Confirm understanding + ask about impact |
104
- | Vague request | Ask about purpose, users, and scope |
105
- | Full orchestration | Block all subagents until plan is confirmed |
137
+ | Request | Questions |
138
+ | -------------------- | ------------------------------------------------------------ |
139
+ | New feature or build | 1-2 targeted questions about the highest-ambiguity decisions |
140
+ | Code edit or bug fix | Confirm understanding of the root cause before fixing |
141
+ | Vague request | 1 question about the core goal, then infer the rest |
142
+ | Full orchestration | Block all subagents until plan is confirmed |
106
143
 
107
144
  **Rules:**
108
145
 
109
- - Never assume. If even 1% is unclear ask.
110
- - Even if the user provides a detailed spec list still ask about edge cases or tradeoffs
146
+ - Ask only what you cannot infer from context. Check the conversation first.
147
+ - Max 2 questions per response. If you need more, prioritize the most blocking one.
148
+ - Never ask what the user already told you. Never ask generic "what stack?" if the repo shows it.
111
149
  - Do not write a single line of code until the gate is cleared
112
150
 
113
151
  ---
@@ -124,6 +162,18 @@ Never generate entire applications in one shot — one module at a time
124
162
  Never guess database column or table names
125
163
  ```
126
164
 
165
+ ### Fabel Coding Discipline
166
+
167
+ ```
168
+ Read the relevant SKILL.md BEFORE writing any code — unconditional, no exceptions.
169
+ After every file edit, re-read the file. Prior context may be stale.
170
+ Short code (≤20 lines) → inline. Long code (>20 lines) → create file.
171
+ Every uncertain API call gets // VERIFY: [reason] comment.
172
+ Scale tool calls to complexity: 1 fact, 3-5 medium, 5-10 deep, escalate beyond.
173
+ Never dump entire files into agent context — excerpt only the relevant function.
174
+ Prose first. Bullets only when 4+ distinct items. No decorative formatting.
175
+ ```
176
+
127
177
  ### Code Quality
128
178
 
129
179
  ```
@@ -9,33 +9,48 @@
9
9
  * const C = require('./_colors'); // C.RED, C.banner('Title'), etc.
10
10
  */
11
11
 
12
- 'use strict';
12
+ "use strict";
13
13
 
14
14
  // ── Core ANSI Escape Codes ──────────────────────────────────────────────────
15
- const GREEN = '\x1b[92m';
16
- const YELLOW = '\x1b[93m';
17
- const CYAN = '\x1b[96m';
18
- const RED = '\x1b[91m';
19
- const BLUE = '\x1b[94m';
20
- const MAGENTA = '\x1b[95m';
21
- const WHITE = '\x1b[97m';
22
- const GRAY = '\x1b[90m';
23
- const BOLD = '\x1b[1m';
24
- const DIM = '\x1b[2m';
25
- const ITALIC = '\x1b[3m';
26
- const UNDERLINE = '\x1b[4m';
27
- const RESET = '\x1b[0m';
15
+ const GREEN = "\x1b[92m";
16
+ const YELLOW = "\x1b[93m";
17
+ const CYAN = "\x1b[96m";
18
+ const RED = "\x1b[91m";
19
+ const BLUE = "\x1b[94m";
20
+ const MAGENTA = "\x1b[95m";
21
+ const WHITE = "\x1b[97m";
22
+ const GRAY = "\x1b[90m";
23
+ const BOLD = "\x1b[1m";
24
+ const DIM = "\x1b[2m";
25
+ const ITALIC = "\x1b[3m";
26
+ const UNDERLINE = "\x1b[4m";
27
+ const RESET = "\x1b[0m";
28
28
 
29
29
  // ── Box Drawing Characters ──────────────────────────────────────────────────
30
30
  const BOX = {
31
- TL: '', TR: '╗', BL: '╚', BR: '╝',
32
- H: '═', V: '║',
33
- tl: '┌', tr: '┐', bl: '└', br: '┘',
34
- h: '─', v: '│',
35
- cross: '┼', teeL: '├', teeR: '┤', teeT: '┬', teeB: '┴',
36
- bullet: '●', bulletEmpty: '○',
37
- arrow: '→', arrowLeft: '←',
38
- check: '✔', cross_mark: '✖',
31
+ TL: "",
32
+ TR: "╗",
33
+ BL: "╚",
34
+ BR: "╝",
35
+ H: "═",
36
+ V: "║",
37
+ tl: "┌",
38
+ tr: "┐",
39
+ bl: "└",
40
+ br: "┘",
41
+ h: "─",
42
+ v: "│",
43
+ cross: "┼",
44
+ teeL: "├",
45
+ teeR: "┤",
46
+ teeT: "┬",
47
+ teeB: "┴",
48
+ bullet: "●",
49
+ bulletEmpty: "○",
50
+ arrow: "→",
51
+ arrowLeft: "←",
52
+ check: "✔",
53
+ cross_mark: "✖",
39
54
  };
40
55
 
41
56
  // ── Branded Output Helpers ──────────────────────────────────────────────────
@@ -47,21 +62,21 @@ const BOX = {
47
62
  * @returns {string} Formatted banner string
48
63
  */
49
64
  function banner(title, meta = {}) {
50
- const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 19);
51
- const lines = [
52
- ` ${BOLD}${CYAN}⚖️ TRIBUNAL KIT${RESET} ${DIM}— ${title}${RESET}`,
53
- ];
54
-
55
- const metaEntries = Object.entries(meta);
56
- if (metaEntries.length > 0) {
57
- for (const [key, value] of metaEntries) {
58
- lines.push(` ${DIM}${key}:${RESET} ${value}`);
59
- }
65
+ const timestamp = new Date().toISOString().replace("T", " ").slice(0, 19);
66
+ const lines = [
67
+ ` ${BOLD}${CYAN}⚖️ TRIBUNAL KIT${RESET} ${DIM}— ${title}${RESET}`,
68
+ ];
69
+
70
+ const metaEntries = Object.entries(meta);
71
+ if (metaEntries.length > 0) {
72
+ for (const [key, value] of metaEntries) {
73
+ lines.push(` ${DIM}${key}:${RESET} ${value}`);
60
74
  }
61
- lines.push(` ${DIM}${timestamp}${RESET}`);
75
+ }
76
+ lines.push(` ${DIM}${timestamp}${RESET}`);
62
77
 
63
- const divider = `${CYAN}${''.repeat(56)}${RESET}`;
64
- return `\n${divider}\n${lines.join('\n')}\n${divider}`;
78
+ const divider = `${CYAN}${"".repeat(56)}${RESET}`;
79
+ return `\n${divider}\n${lines.join("\n")}\n${divider}`;
65
80
  }
66
81
 
67
82
  /**
@@ -72,9 +87,9 @@ function banner(title, meta = {}) {
72
87
  * @returns {string}
73
88
  */
74
89
  function sectionHeader(title, index, ms) {
75
- const num = index != null ? `${index} — ` : '';
76
- const timing = ms != null ? `${DIM} (${formatMs(ms)})${RESET}` : '';
77
- return `\n${BOLD}${BLUE}━━━ ${num}${title} ━━━${RESET}${timing}`;
90
+ const num = index != null ? `${index} — ` : "";
91
+ const timing = ms != null ? `${DIM} (${formatMs(ms)})${RESET}` : "";
92
+ return `\n${BOLD}${BLUE}━━━ ${num}${title} ━━━${RESET}${timing}`;
78
93
  }
79
94
 
80
95
  /**
@@ -83,27 +98,37 @@ function sectionHeader(title, index, ms) {
83
98
  * @returns {string}
84
99
  */
85
100
  function formatMs(ms) {
86
- if (ms < 1000) return `${ms}ms`;
87
- if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
88
- return `${Math.floor(ms / 60000)}m ${Math.round((ms % 60000) / 1000)}s`;
101
+ if (ms < 1000) return `${ms}ms`;
102
+ if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
103
+ return `${Math.floor(ms / 60000)}m ${Math.round((ms % 60000) / 1000)}s`;
89
104
  }
90
105
 
91
106
  // ── Status Indicator Helpers ────────────────────────────────────────────────
92
107
 
93
108
  /** @param {string} msg */
94
- function ok(msg) { console.log(` ${GREEN}✅ ${msg}${RESET}`); }
109
+ function ok(msg) {
110
+ console.log(` ${GREEN}✅ ${msg}${RESET}`);
111
+ }
95
112
 
96
113
  /** @param {string} msg */
97
- function fail(msg) { console.log(` ${RED}❌ ${msg}${RESET}`); }
114
+ function fail(msg) {
115
+ console.log(` ${RED}❌ ${msg}${RESET}`);
116
+ }
98
117
 
99
118
  /** @param {string} msg */
100
- function warn(msg) { console.log(` ${YELLOW}⚠️ ${msg}${RESET}`); }
119
+ function warn(msg) {
120
+ console.log(` ${YELLOW}⚠️ ${msg}${RESET}`);
121
+ }
101
122
 
102
123
  /** @param {string} msg */
103
- function skip(msg) { console.log(` ${YELLOW}⏭️ ${msg}${RESET}`); }
124
+ function skip(msg) {
125
+ console.log(` ${YELLOW}⏭️ ${msg}${RESET}`);
126
+ }
104
127
 
105
128
  /** @param {string} msg */
106
- function info(msg) { console.log(` ${BLUE}ℹ️ ${msg}${RESET}`); }
129
+ function info(msg) {
130
+ console.log(` ${BLUE}ℹ️ ${msg}${RESET}`);
131
+ }
107
132
 
108
133
  // ── Summary Table Builder ───────────────────────────────────────────────────
109
134
 
@@ -112,34 +137,34 @@ function info(msg) { console.log(` ${BLUE}ℹ️ ${msg}${RESET}`); }
112
137
  * @param {Array<{name: string, status: 'pass'|'fail'|'skip'|'warn', ms?: number}>} rows
113
138
  */
114
139
  function summaryTable(rows) {
115
- const maxName = Math.max(...rows.map(r => r.name.length), 18);
116
- const colW = maxName + 2;
117
-
118
- const statusIcon = (s) => {
119
- if (s === 'pass') return `${GREEN} ✅ ${RESET}`;
120
- if (s === 'fail') return `${RED} ❌ ${RESET}`;
121
- if (s === 'skip') return `${YELLOW} ⏭️ ${RESET}`;
122
- if (s === 'warn') return `${YELLOW} ⚠️ ${RESET}`;
123
- return `${DIM} — ${RESET}`;
124
- };
125
-
126
- const pad = (str, len) => str + ' '.repeat(Math.max(0, len - str.length));
127
- const top = ` ${BOX.tl}${BOX.h.repeat(colW)}${BOX.teeT}${BOX.h.repeat(6)}${BOX.teeT}${BOX.h.repeat(10)}${BOX.tr}`;
128
- const mid = ` ${BOX.teeL}${BOX.h.repeat(colW)}${BOX.cross}${BOX.h.repeat(6)}${BOX.cross}${BOX.h.repeat(10)}${BOX.teeR}`;
129
- const bot = ` ${BOX.bl}${BOX.h.repeat(colW)}${BOX.teeB}${BOX.h.repeat(6)}${BOX.teeB}${BOX.h.repeat(10)}${BOX.br}`;
130
- const hdr = ` ${BOX.v} ${BOLD}${pad('Check', colW - 2)}${RESET} ${BOX.v}${BOLD} Res ${RESET}${BOX.v} ${BOLD}${pad('Time', 8)}${RESET}${BOX.v}`;
131
-
132
- console.log(top);
133
- console.log(hdr);
134
- console.log(mid);
135
-
136
- for (const row of rows) {
137
- const time = row.ms != null ? formatMs(row.ms) : '';
138
- const line = ` ${BOX.v} ${pad(row.name, colW - 2)} ${BOX.v}${statusIcon(row.status)}${BOX.v} ${pad(time, 8)}${BOX.v}`;
139
- console.log(line);
140
- }
141
-
142
- console.log(bot);
140
+ const maxName = Math.max(...rows.map((r) => r.name.length), 18);
141
+ const colW = maxName + 2;
142
+
143
+ const statusIcon = (s) => {
144
+ if (s === "pass") return `${GREEN} ✅ ${RESET}`;
145
+ if (s === "fail") return `${RED} ❌ ${RESET}`;
146
+ if (s === "skip") return `${YELLOW} ⏭️ ${RESET}`;
147
+ if (s === "warn") return `${YELLOW} ⚠️ ${RESET}`;
148
+ return `${DIM} — ${RESET}`;
149
+ };
150
+
151
+ const pad = (str, len) => str + " ".repeat(Math.max(0, len - str.length));
152
+ const top = ` ${BOX.tl}${BOX.h.repeat(colW)}${BOX.teeT}${BOX.h.repeat(6)}${BOX.teeT}${BOX.h.repeat(10)}${BOX.tr}`;
153
+ const mid = ` ${BOX.teeL}${BOX.h.repeat(colW)}${BOX.cross}${BOX.h.repeat(6)}${BOX.cross}${BOX.h.repeat(10)}${BOX.teeR}`;
154
+ const bot = ` ${BOX.bl}${BOX.h.repeat(colW)}${BOX.teeB}${BOX.h.repeat(6)}${BOX.teeB}${BOX.h.repeat(10)}${BOX.br}`;
155
+ const hdr = ` ${BOX.v} ${BOLD}${pad("Check", colW - 2)}${RESET} ${BOX.v}${BOLD} Res ${RESET}${BOX.v} ${BOLD}${pad("Time", 8)}${RESET}${BOX.v}`;
156
+
157
+ console.log(top);
158
+ console.log(hdr);
159
+ console.log(mid);
160
+
161
+ for (const row of rows) {
162
+ const time = row.ms != null ? formatMs(row.ms) : "";
163
+ const line = ` ${BOX.v} ${pad(row.name, colW - 2)} ${BOX.v}${statusIcon(row.status)}${BOX.v} ${pad(time, 8)}${BOX.v}`;
164
+ console.log(line);
165
+ }
166
+
167
+ console.log(bot);
143
168
  }
144
169
 
145
170
  // ── High-Precision Timer ────────────────────────────────────────────────────
@@ -149,22 +174,39 @@ function summaryTable(rows) {
149
174
  * @returns {function(): number}
150
175
  */
151
176
  function timer() {
152
- const start = process.hrtime.bigint();
153
- return () => Number(process.hrtime.bigint() - start) / 1e6;
177
+ const start = process.hrtime.bigint();
178
+ return () => Number(process.hrtime.bigint() - start) / 1e6;
154
179
  }
155
180
 
156
181
  module.exports = {
157
- // Core colors
158
- GREEN, YELLOW, CYAN, RED, BLUE, MAGENTA, WHITE, GRAY,
159
- BOLD, DIM, ITALIC, UNDERLINE, RESET,
160
- // Box drawing
161
- BOX,
162
- // Branded helpers
163
- banner, sectionHeader, formatMs,
164
- // Status indicators
165
- ok, fail, warn, skip, info,
166
- // Summary
167
- summaryTable,
168
- // Timing
169
- timer,
182
+ // Core colors
183
+ GREEN,
184
+ YELLOW,
185
+ CYAN,
186
+ RED,
187
+ BLUE,
188
+ MAGENTA,
189
+ WHITE,
190
+ GRAY,
191
+ BOLD,
192
+ DIM,
193
+ ITALIC,
194
+ UNDERLINE,
195
+ RESET,
196
+ // Box drawing
197
+ BOX,
198
+ // Branded helpers
199
+ banner,
200
+ sectionHeader,
201
+ formatMs,
202
+ // Status indicators
203
+ ok,
204
+ fail,
205
+ warn,
206
+ skip,
207
+ info,
208
+ // Summary
209
+ summaryTable,
210
+ // Timing
211
+ timer,
170
212
  };