tribunal-kit 5.8.4 → 5.8.5

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 (46) hide show
  1. package/.agent/ARCHITECTURE.md +3 -3
  2. package/.agent/history/integrity_manifest.json +75 -7
  3. package/.agent/history/memory/.memory.idx +1065 -1
  4. package/.agent/history/memory/MEMORY.md +71 -1
  5. package/.agent/rules/GEMINI.md +1 -1
  6. package/.agent/scripts/_utils.js +28 -7
  7. package/.agent/scripts/context_broker.js +0 -19
  8. package/.agent/scripts/guardrail_engine.js +1 -1
  9. package/.agent/scripts/integrity_manifest.js +10 -4
  10. package/.agent/scripts/marathon_harness.js +10 -1
  11. package/.agent/scripts/skill_evolution.js +36 -21
  12. package/.agent/scripts/swarm_dispatcher.js +65 -6
  13. package/.agent/skills/api-patterns/scripts/__pycache__/api_validator.cpython-311.pyc +0 -0
  14. package/.agent/skills/better-colors/SKILL.md +12 -4
  15. package/.agent/skills/database-design/scripts/__pycache__/schema_validator.cpython-311.pyc +0 -0
  16. package/.agent/skills/fixing-accessibility/SKILL.md +6 -4
  17. package/.agent/skills/frontend-design/SKILL.md +80 -81
  18. package/.agent/skills/frontend-design/scripts/__pycache__/accessibility_checker.cpython-311.pyc +0 -0
  19. package/.agent/skills/frontend-design/scripts/__pycache__/ux_audit.cpython-311.pyc +0 -0
  20. package/.agent/skills/geo-fundamentals/scripts/__pycache__/geo_checker.cpython-311.pyc +0 -0
  21. package/.agent/skills/i18n-localization/scripts/__pycache__/i18n_checker.cpython-311.pyc +0 -0
  22. package/.agent/skills/impeccable/SKILL.md +2 -0
  23. package/.agent/skills/lint-and-validate/scripts/__pycache__/lint_runner.cpython-311.pyc +0 -0
  24. package/.agent/skills/lint-and-validate/scripts/__pycache__/type_coverage.cpython-311.pyc +0 -0
  25. package/.agent/skills/mobile-design/scripts/__pycache__/mobile_audit.cpython-311.pyc +0 -0
  26. package/.agent/skills/motion-engineering/SKILL.md +66 -164
  27. package/.agent/skills/nextjs-react-expert/scripts/__pycache__/convert_rules.cpython-311.pyc +0 -0
  28. package/.agent/skills/nextjs-react-expert/scripts/__pycache__/react_performance_checker.cpython-311.pyc +0 -0
  29. package/.agent/skills/performance-profiling/scripts/__pycache__/lighthouse_audit.cpython-311.pyc +0 -0
  30. package/.agent/skills/seo-fundamentals/scripts/__pycache__/seo_checker.cpython-311.pyc +0 -0
  31. package/.agent/skills/testing-patterns/scripts/__pycache__/test_runner.cpython-311.pyc +0 -0
  32. package/.agent/skills/vulnerability-scanner/scripts/__pycache__/security_scan.cpython-311.pyc +0 -0
  33. package/.agent/skills/webapp-testing/scripts/__pycache__/playwright_runner.cpython-311.pyc +0 -0
  34. package/.agent/workflows/tribunal-full.md +5 -5
  35. package/CONTRIBUTING.md +1 -1
  36. package/README.md +4 -4
  37. package/bin/mcp-server.js +45 -45
  38. package/bin/wrapper.js +50 -25
  39. package/dist/cli.js +30 -0
  40. package/dist/commands/init.js +25 -1
  41. package/dist/commands/native.js +228 -0
  42. package/dist/commands/validate.js +67 -0
  43. package/dist/mcp/server.js +4 -138
  44. package/package.json +11 -10
  45. package/scripts/benchmark.js +42 -0
  46. package/scripts/sync-version.js +129 -76
@@ -1,142 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+
3
4
  /**
4
- * Tribunal-Kit MCP Server (dist/ version — Performance-Optimized)
5
- *
6
- * Uses in-process require() for commands instead of spawning child processes.
7
- * Protocol: MCP 2024-11-05 over JSON-RPC 2.0 / stdio
5
+ * Compatibility entry point for the historical dist/mcp/server.js path.
6
+ * bin/mcp-server.js is the single canonical MCP implementation.
8
7
  */
9
- const { spawnSync } = require('child_process');
10
- const path = require('path');
11
-
12
- const PKG = require('../../package.json');
13
-
14
- // Timeout for spawned processes (30 seconds)
15
- const SPAWN_TIMEOUT_MS = 30000;
16
-
17
- const readline = require('readline');
18
- const rl = readline.createInterface({
19
- input: process.stdin,
20
- output: process.stdout,
21
- terminal: false
22
- });
23
-
24
- function handleRequest(req) {
25
- if (req.method === 'initialize') {
26
- return {
27
- protocolVersion: "2024-11-05",
28
- capabilities: { tools: {} },
29
- serverInfo: {
30
- name: "tribunal-kit-mcp",
31
- version: PKG.version
32
- }
33
- };
34
- }
35
-
36
- if (req.method === 'tools/list') {
37
- return {
38
- tools: [
39
- {
40
- name: "run_tribunal_audit",
41
- description: "Runs a full anti-hallucination audit across the workspace.",
42
- inputSchema: { type: "object", properties: {}, additionalProperties: false }
43
- },
44
- {
45
- name: "sync_ide_bridges",
46
- description: "Synchronize IDE bridge files with the current GEMINI.md rules.",
47
- inputSchema: { type: "object", properties: {}, additionalProperties: false }
48
- },
49
- {
50
- name: "search_case_law",
51
- description: "Search historical code rejections and legal precedent.",
52
- inputSchema: {
53
- type: "object",
54
- properties: {
55
- query: { type: "string", description: "Search query" }
56
- },
57
- required: ["query"],
58
- additionalProperties: false
59
- }
60
- }
61
- ]
62
- };
63
- }
64
-
65
- if (req.method === 'tools/call') {
66
- const toolName = req.params && req.params.name;
67
- if (!toolName) {
68
- throw { code: -32602, message: "Missing required parameter: params.name" };
69
- }
70
-
71
- if (toolName === 'run_tribunal_audit') {
72
- // Validate uses the Rust binary — still needs spawn
73
- const CLI = path.resolve(__dirname, '../../bin/wrapper.js');
74
- const result = spawnSync(process.execPath, [CLI, 'validate', '--quiet'], {
75
- encoding: 'utf8',
76
- timeout: SPAWN_TIMEOUT_MS,
77
- });
78
- return { content: [{ type: "text", text: result.stdout || result.stderr || "No output" }] };
79
- }
80
-
81
- if (toolName === 'sync_ide_bridges') {
82
- // In-process — no spawn needed
83
- const CLI = path.resolve(__dirname, '../../bin/wrapper.js');
84
- const result = spawnSync(process.execPath, [CLI, 'sync', '--quiet'], {
85
- encoding: 'utf8',
86
- timeout: SPAWN_TIMEOUT_MS,
87
- });
88
- return { content: [{ type: "text", text: result.stdout || result.stderr || "Sync complete" }] };
89
- }
90
-
91
- if (toolName === 'search_case_law') {
92
- const query = req.params && req.params.arguments && req.params.arguments.query;
93
- if (!query || typeof query !== 'string') {
94
- throw { code: -32602, message: "Missing or invalid required argument: query (string)" };
95
- }
96
- const script = path.resolve(__dirname, '../../.agent/scripts/case_law_manager.js');
97
- const result = spawnSync(process.execPath, [script, 'search-cases', '--query', query], {
98
- encoding: 'utf8',
99
- timeout: SPAWN_TIMEOUT_MS,
100
- });
101
- return { content: [{ type: "text", text: result.stdout || result.stderr || "No results" }] };
102
- }
103
-
104
- throw { code: -32601, message: `Unknown tool: ${toolName}` };
105
- }
106
-
107
- throw { code: -32601, message: `Unknown method: ${req.method}` };
108
- }
109
-
110
- rl.on('line', (line) => {
111
- if (!line.trim()) return;
112
-
113
- let req;
114
- try {
115
- req = JSON.parse(line);
116
- } catch (parseErr) {
117
- const errorRes = {
118
- jsonrpc: "2.0", id: null,
119
- error: { code: -32700, message: "Parse error: " + parseErr.message }
120
- };
121
- console.log(JSON.stringify(errorRes));
122
- return;
123
- }
124
-
125
- try {
126
- const result = handleRequest(req);
127
- const res = { jsonrpc: "2.0", id: req.id, result };
128
- console.log(JSON.stringify(res));
129
-
130
- if (req.method === 'initialize') {
131
- console.log(JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized", params: {} }));
132
- }
133
- } catch (e) {
134
- const code = (e && typeof e.code === 'number') ? e.code : -32603;
135
- const message = (e && e.message) ? e.message : "Internal server error";
136
- const errorRes = {
137
- jsonrpc: "2.0", id: req.id || null,
138
- error: { code, message }
139
- };
140
- console.log(JSON.stringify(errorRes));
141
- }
142
- });
8
+ module.exports = require("../../bin/mcp-server.js");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tribunal-kit",
3
- "version": "5.8.4",
4
- "description": "The operating system for AI software engineering — governance, memory, review pipelines, and reusable skills for every coding agent. 44 specialist agents, 34 workflows, 20 parallel Tribunal code reviewers, MCP server, Rust core engine, and long-running autonomous agent harness for Cursor, VSCode, Windsurf, Claude Code, and Aider.",
3
+ "version": "5.8.5",
4
+ "description": "The operating system for AI software engineering — governance, memory, review pipelines, and reusable skills for every coding agent. 44 specialist agents, 34 workflows, 19 parallel Tribunal code reviewers, MCP server, Rust core engine, and long-running autonomous agent harness for Cursor, VSCode, Windsurf, Claude Code, and Aider.",
5
5
  "keywords": [
6
6
  "ai",
7
7
  "ai-agent",
@@ -93,7 +93,7 @@
93
93
  "benchmark:rust": "cargo build --release && node scripts/benchmark.js",
94
94
  "build:rust": "cargo build --release",
95
95
  "test:rust": "cargo test --manifest-path crates/core/Cargo.toml",
96
- "build": "echo 'No build step required for this project'"
96
+ "build": "npm run build:rust"
97
97
  },
98
98
  "devDependencies": {
99
99
  "eslint": "^9.1.1",
@@ -101,12 +101,12 @@
101
101
  "typescript": "^5.4.5"
102
102
  },
103
103
  "optionalDependencies": {
104
- "@tribunal-kit/core-darwin-arm64": "^5.8.4",
105
- "@tribunal-kit/core-darwin-x64": "^5.8.4",
106
- "@tribunal-kit/core-linux-arm64": "^5.8.4",
107
- "@tribunal-kit/core-linux-x64": "^5.8.4",
108
- "@tribunal-kit/core-win32-arm64": "^5.8.4",
109
- "@tribunal-kit/core-win32-x64": "^5.8.4"
104
+ "@tribunal-kit/core-darwin-arm64": "^5.8.5",
105
+ "@tribunal-kit/core-darwin-x64": "^5.8.5",
106
+ "@tribunal-kit/core-linux-arm64": "^5.8.5",
107
+ "@tribunal-kit/core-linux-x64": "^5.8.5",
108
+ "@tribunal-kit/core-win32-arm64": "^5.8.5",
109
+ "@tribunal-kit/core-win32-x64": "^5.8.5"
110
110
  },
111
111
  "jest": {
112
112
  "testMatch": [
@@ -115,7 +115,8 @@
115
115
  "testEnvironment": "node",
116
116
  "coverageDirectory": "coverage",
117
117
  "collectCoverageFrom": [
118
- "bin/**/*.js"
118
+ "bin/**/*.js",
119
+ ".agent/scripts/**/*.js"
119
120
  ]
120
121
  }
121
122
  }
@@ -142,6 +142,48 @@ async function main() {
142
142
  );
143
143
  results.push(initRealResult);
144
144
 
145
+ // 5. DAG scheduling benchmark
146
+ console.log(c("cyan", " ▸ Benchmarking: DAG scheduling calculation"));
147
+ const dagResult = await benchmark(
148
+ "DAG wave scheduling",
149
+ () => {
150
+ const workers = [
151
+ { task_id: "w1", dependencies: [] },
152
+ { task_id: "w2", dependencies: ["w1"] },
153
+ { task_id: "w3", dependencies: ["w1"] },
154
+ { task_id: "w4", dependencies: ["w2", "w3"] },
155
+ ];
156
+ const inDegree = {};
157
+ const adjList = {};
158
+ workers.forEach((w) => {
159
+ inDegree[w.task_id] = 0;
160
+ adjList[w.task_id] = [];
161
+ });
162
+ workers.forEach((w) => {
163
+ w.dependencies.forEach((dep) => {
164
+ adjList[dep].push(w.task_id);
165
+ inDegree[w.task_id] += 1;
166
+ });
167
+ });
168
+ let currentWave = Object.keys(inDegree).filter((id) => inDegree[id] === 0);
169
+ const waves = [];
170
+ while (currentWave.length > 0) {
171
+ waves.push(currentWave);
172
+ const next = [];
173
+ currentWave.forEach((id) => {
174
+ adjList[id].forEach((nbr) => {
175
+ inDegree[nbr] -= 1;
176
+ if (inDegree[nbr] === 0) next.push(nbr);
177
+ });
178
+ });
179
+ currentWave = next;
180
+ }
181
+ },
182
+ 100,
183
+ );
184
+ results.push(dagResult);
185
+
186
+
145
187
  // Print results table
146
188
  console.log();
147
189
  console.log(bold(` Results`));
@@ -1,94 +1,147 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * sync-version.js — Version Sync for Tribunal Kit
3
+ * sync-version.js — Release metadata consistency check for Tribunal Kit.
4
4
  *
5
- * Reads the version and counts from package.json and the .agent/ directory,
6
- * then updates all stale references across documentation files.
7
- *
8
- * Run manually or as a preversion npm script:
9
- * node scripts/sync-version.js
5
+ * Verifies the package version, native package metadata, lockfile metadata,
6
+ * and public asset-count claims before a release. It intentionally performs
7
+ * no implicit writes: a failed check makes stale release metadata visible.
10
8
  */
11
9
 
10
+ "use strict";
11
+
12
12
  const fs = require("fs");
13
13
  const path = require("path");
14
14
 
15
15
  const ROOT = path.resolve(__dirname, "..");
16
- const PKG = JSON.parse(
17
- fs.readFileSync(path.join(ROOT, "package.json"), "utf8"),
18
- );
19
-
20
- // Count actual installed items
21
- function countItems(dir) {
22
- const fullPath = path.join(ROOT, ".agent", dir);
23
- if (!fs.existsSync(fullPath)) return "?";
24
- return fs.readdirSync(fullPath).filter((f) => !f.startsWith(".")).length;
16
+ const PKG_PATH = path.join(ROOT, "package.json");
17
+ const PKG = JSON.parse(fs.readFileSync(PKG_PATH, "utf8"));
18
+ const VERSION = PKG.version;
19
+
20
+ function readText(relativePath) {
21
+ return fs.readFileSync(path.join(ROOT, relativePath), "utf8");
22
+ }
23
+
24
+ function readJson(relativePath) {
25
+ return JSON.parse(readText(relativePath));
26
+ }
27
+
28
+ function countDirectory(relativePath, predicate) {
29
+ const directory = path.join(ROOT, relativePath);
30
+ if (!fs.existsSync(directory)) return 0;
31
+ return fs.readdirSync(directory, { withFileTypes: true }).filter(predicate).length;
32
+ }
33
+
34
+ function countReviewers() {
35
+ const agentsDir = path.join(ROOT, ".agent", "agents");
36
+ return countDirectory(".agent/agents", (entry) => {
37
+ if (!entry.isFile() || !entry.name.endsWith(".md")) return false;
38
+ const content = fs.readFileSync(path.join(agentsDir, entry.name), "utf8");
39
+ return /reviewer|auditor|tester|throughput-optimizer/i.test(entry.name) || /^role:\s*reviewer\s*$/im.test(content);
40
+ });
25
41
  }
26
42
 
27
- const version = PKG.version;
28
- const agents = countItems("agents");
29
- const skills = countItems("skills");
30
- const workflows = countItems("workflows");
31
- const scripts = countItems("scripts");
32
-
33
- console.log(`\n 📊 Tribunal Kit v${version} Actual Counts`);
34
- console.log(` ──────────────────────────────────────`);
35
- console.log(` Agents: ${agents}`);
36
- console.log(` Skills: ${skills}`);
37
- console.log(` Workflows: ${workflows}`);
38
- console.log(` Scripts: ${scripts}`);
39
- console.log();
40
-
41
- // Files to check for stale numbers
42
- const FILES_TO_CHECK = ["README.md", "AGENT_FLOW.md", ".agent/ARCHITECTURE.md"];
43
-
44
- let staleFound = 0;
45
-
46
- for (const relPath of FILES_TO_CHECK) {
47
- const filePath = path.join(ROOT, relPath);
48
- if (!fs.existsSync(filePath)) continue;
49
-
50
- const content = fs.readFileSync(filePath, "utf8");
51
-
52
- // Check for common stale patterns
53
- const checks = [
54
- {
55
- regex: /(\d+)\s*(specialist\s+)?agents/gi,
56
- expected: agents,
57
- label: "agents",
58
- },
59
- { regex: /(\d+)\s*skill\s*modules/gi, expected: skills, label: "skills" },
60
- {
61
- regex: /(\d+)\s*slash\s*command/gi,
62
- expected: workflows,
63
- label: "workflows",
64
- },
65
- ];
66
-
67
- for (const check of checks) {
68
- let match;
69
- while ((match = check.regex.exec(content)) !== null) {
70
- const found = parseInt(match[1]);
71
- if (found !== check.expected && found > 5) {
72
- // ignore tiny numbers
73
- staleFound++;
74
- const line = content.substring(0, match.index).split("\n").length;
75
- console.log(
76
- ` ⚠️ ${relPath}:${line} — says ${found} ${check.label}, actual is ${check.expected}`,
77
- );
43
+
44
+ const COUNTS = {
45
+ agents: countDirectory(".agent/agents", (entry) => entry.isFile() && entry.name.endsWith(".md")),
46
+ reviewers: countReviewers(),
47
+ skills: countDirectory(".agent/skills", (entry) => entry.isDirectory() && fs.existsSync(path.join(ROOT, ".agent", "skills", entry.name, "SKILL.md"))),
48
+ workflows: countDirectory(".agent/workflows", (entry) => entry.isFile() && entry.name.endsWith(".md")),
49
+ scripts: countDirectory(".agent/scripts", (entry) => entry.isFile() && /\.(?:js|py)$/.test(entry.name)),
50
+ };
51
+
52
+ const failures = [];
53
+
54
+ function fail(message) {
55
+ failures.push(message);
56
+ }
57
+
58
+ function checkVersionMetadata() {
59
+ const expectedOptionalVersion = `^${VERSION}`;
60
+ for (const [name, declaredVersion] of Object.entries(PKG.optionalDependencies || {})) {
61
+ if (declaredVersion !== expectedOptionalVersion) {
62
+ fail(`package.json optional dependency ${name} is ${declaredVersion}, expected ${expectedOptionalVersion}`);
63
+ }
64
+ }
65
+
66
+ const lock = readJson("package-lock.json");
67
+ if (lock.version !== VERSION || lock.packages?.[""]?.version !== VERSION) {
68
+ fail(`package-lock.json root version does not match package.json (${VERSION})`);
69
+ }
70
+ for (const [name, declaredVersion] of Object.entries(lock.packages?.[""]?.optionalDependencies || {})) {
71
+ if (declaredVersion !== expectedOptionalVersion) {
72
+ fail(`package-lock.json optional dependency ${name} is ${declaredVersion}, expected ${expectedOptionalVersion}`);
73
+ }
74
+ }
75
+
76
+ const cargoToml = readText("crates/core/Cargo.toml");
77
+ const cargoTomlVersion = cargoToml.match(/^version\s*=\s*"([^"]+)"/m)?.[1];
78
+ if (cargoTomlVersion !== VERSION) {
79
+ fail(`crates/core/Cargo.toml version is ${cargoTomlVersion || "missing"}, expected ${VERSION}`);
80
+ }
81
+
82
+ const cargoLock = readText("Cargo.lock");
83
+ const cargoLockVersion = cargoLock.match(/name\s*=\s*"tribunal-core"\s*\nversion\s*=\s*"([^"]+)"/)?.[1];
84
+ if (cargoLockVersion !== VERSION) {
85
+ fail(`Cargo.lock tribunal-core version is ${cargoLockVersion || "missing"}, expected ${VERSION}`);
86
+ }
87
+
88
+ const readmeRelease = readText("README.md").match(/Release-v([0-9]+\.[0-9]+\.[0-9]+)/)?.[1];
89
+ if (readmeRelease !== VERSION) {
90
+ fail(`README release badge is ${readmeRelease || "missing"}, expected ${VERSION}`);
91
+ }
92
+ }
93
+
94
+ const DOCUMENTS = [
95
+ "README.md",
96
+ ".agent/ARCHITECTURE.md",
97
+ ".agent/rules/GEMINI.md",
98
+ "CONTRIBUTING.md",
99
+ ];
100
+
101
+ const CLAIM_PATTERNS = [
102
+ { entity: "agents", regex: /(\d+)\s*(?:specialist\s+)?agents?\b/gi },
103
+ {
104
+ entity: "reviewers",
105
+ regex: /(\d+)\s*(?:-\s*)?(?:(?:parallel|domain(?:-specific)?|tribunal|code)\s+)*reviewers?\b/gi,
106
+ },
107
+ { entity: "skills", regex: /(\d+)\s*(?:valid\s+|modular\s+)?skills?(?:\s+(?:packages?|modules?))?\b/gi },
108
+ { entity: "workflows", regex: /(\d+)\s*(?:slash\s+)?workflows?\b/gi },
109
+ { entity: "scripts", regex: /(\d+)\s*(?:JS\s+)?(?:automation\s+)?scripts?\b/gi },
110
+ ];
111
+
112
+ function checkDocumentCounts() {
113
+ for (const relativePath of DOCUMENTS) {
114
+ const content = readText(relativePath);
115
+ for (const { entity, regex } of CLAIM_PATTERNS) {
116
+ regex.lastIndex = 0;
117
+ let match;
118
+ while ((match = regex.exec(content)) !== null) {
119
+ const claimed = Number.parseInt(match[1], 10);
120
+ if (claimed < 5 || claimed > 500) continue;
121
+ if (claimed !== COUNTS[entity]) {
122
+ const line = content.slice(0, match.index).split(/\r?\n/).length;
123
+ fail(`${relativePath}:${line} says ${claimed} ${entity}, actual is ${COUNTS[entity]}`);
124
+ }
78
125
  }
79
126
  }
80
127
  }
81
128
  }
82
129
 
83
- if (staleFound === 0) {
84
- console.log(
85
- ` All counts are in sync across ${FILES_TO_CHECK.length} files.`,
86
- );
130
+ console.log(`\n Tribunal Kit v${VERSION} — Release Metadata Check`);
131
+ console.log(" ────────────────────────────────────────────────");
132
+ console.log(` Agents: ${COUNTS.agents} (${COUNTS.reviewers} reviewers)`);
133
+ console.log(` Skills: ${COUNTS.skills}`);
134
+ console.log(` Workflows: ${COUNTS.workflows}`);
135
+ console.log(` Scripts: ${COUNTS.scripts}`);
136
+
137
+ checkVersionMetadata();
138
+ checkDocumentCounts();
139
+
140
+ if (failures.length > 0) {
141
+ console.log();
142
+ for (const message of failures) console.log(` ✗ ${message}`);
143
+ console.log(`\n Found ${failures.length} release metadata inconsistency${failures.length === 1 ? "" : "ies"}.`);
144
+ process.exitCode = 1;
87
145
  } else {
88
- console.log(
89
- `\n ❌ Found ${staleFound} stale reference(s). Update manually or run the sync tool.`,
90
- );
91
- process.exit(1);
146
+ console.log(`\n ✓ Version metadata and public count claims are in sync across ${DOCUMENTS.length} documents.\n`);
92
147
  }
93
-
94
- console.log();