tribunal-kit 7.0.0 → 8.0.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/config/claude.json +18 -0
- package/.agent/config/plugin.json +102 -0
- package/.agent/config/slash-commands.json +103 -0
- package/.agent/config/specialist-registry.json +415 -0
- package/.agent/config/system-prompt.md +191 -0
- package/.agent/history/architecture-graph.yaml +302 -3
- package/.agent/history/graph-cache.json +515 -45
- package/.agent/history/memory.db +0 -0
- package/.agent/history/snapshots/bin__adapter-install.js.json +13 -0
- package/.agent/history/snapshots/bin__global-store.js.json +15 -0
- package/.agent/history/snapshots/bin__mcp-server.js.json +19 -0
- package/.agent/history/snapshots/bin__proxy-server.js.json +20 -0
- package/.agent/history/snapshots/bin__spawn-agent.js.json +12 -0
- package/.agent/history/snapshots/bin__tk-proxy.js.json +21 -0
- package/.agent/history/snapshots/bin__tribunal-kit.js.json +9 -7
- package/.agent/history/snapshots/bin__wrapper.js.json +14 -0
- package/.agent/history/snapshots/eslint.config.js.json +1 -2
- package/.agent/history/snapshots/scripts__benchmark.js.json +14 -0
- package/.agent/history/snapshots/scripts__changelog.js.json +1 -2
- package/.agent/history/snapshots/scripts__fix-vbc.js.json +11 -0
- package/.agent/history/snapshots/scripts__stress_benchmark.js.json +15 -0
- package/.agent/history/snapshots/scripts__sync-version.js.json +1 -2
- package/.agent/history/snapshots/scripts__validate-payload.js.json +1 -2
- package/.agent/history/snapshots/scripts__visual_audit.js.json +11 -0
- package/.agent/history/snapshots/test__integration__bridges.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__graceful_degradation.test.js.json +12 -0
- package/.agent/history/snapshots/test__integration__init.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__minimal_change_pipeline.test.js.json +13 -0
- package/.agent/history/snapshots/test__integration__parallel_tribunal.test.js.json +12 -0
- package/.agent/history/snapshots/test__integration__routing.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__swarm_dispatcher.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__sync_status.test.js.json +13 -0
- package/.agent/history/snapshots/test__integration__wave2.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__wrapper.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__align.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__args.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__audit_release.test.js.json +16 -0
- package/.agent/history/snapshots/test__unit__case_law_manager.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__cicd_validator.test.js.json +12 -0
- package/.agent/history/snapshots/test__unit__compile.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__context_broker.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__contract_engine.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__copyDir.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__graph_tools.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__guardrail_engine.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__impact_classifier.test.js.json +12 -0
- package/.agent/history/snapshots/test__unit__init.test.js.json +14 -0
- package/.agent/history/snapshots/test__unit__inner_loop_validator.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__integrity_manifest.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__learn.test.js.json +11 -0
- package/.agent/history/snapshots/test__unit__marathon.test.js.json +22 -0
- package/.agent/history/snapshots/test__unit__mcp_server.test.js.json +16 -0
- package/.agent/history/snapshots/test__unit__memory.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__minimal_change.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__native.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__optimize.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__path_resolution.test.js.json +14 -0
- package/.agent/history/snapshots/test__unit__production_readiness_evidence.test.js.json +21 -0
- package/.agent/history/snapshots/test__unit__selfInstall.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__semver.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__skill_evolution.test.js.json +11 -0
- package/.agent/history/snapshots/test__unit__stress.test.js.json +15 -0
- package/.agent/history/snapshots/test__unit__swarm_dispatcher.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__utils.test.js.json +10 -0
- package/.agent/scripts/ast_context_loader.js +137 -0
- package/.agent/scripts/memory_engine.js +581 -0
- package/.agent/scripts/payload_schemas.js +146 -0
- package/.agent/scripts/prompt_compiler.js +59 -11
- package/.agent/scripts/swarm_dispatcher.js +295 -67
- package/.agent/scripts/token_budget_broker.js +117 -6
- package/.claude/CLAUDE.md +442 -0
- package/README.md +22 -12
- package/SECURITY.md +3 -3
- package/bin/adapter-install.js +240 -0
- package/bin/global-store.js +48 -0
- package/bin/mcp-server.js +568 -252
- package/bin/proxy-server.js +113 -0
- package/bin/spawn-agent.js +39 -0
- package/bin/tk-proxy.js +34 -0
- package/dist/commands/init.js +8 -51
- package/dist/commands/status.js +61 -36
- package/dist/commands/validate.js +22 -31
- package/dist/tui/banner.js +77 -0
- package/dist/tui/index.js +21 -0
- package/dist/tui/reviewer-grid.js +90 -0
- package/dist/tui/shimmer.js +91 -0
- package/dist/tui/theme.js +130 -0
- package/dist/tui/tree.js +93 -0
- package/dist/tui/wizard.js +148 -0
- package/dist/utils/helpers.js +5 -41
- package/package.json +27 -10
- package/scripts/build-graph.js +71 -0
- package/.agent/history/snapshots/migrate_refs.js.json +0 -11
- package/.agent/scripts/compile_router.py +0 -5
- package/.agent/scripts/migrate_skills_frontmatter.py +0 -5
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const http = require('http');
|
|
2
|
+
const https = require('https');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const globalStore = require('./global-store');
|
|
6
|
+
|
|
7
|
+
let proxyServer = null;
|
|
8
|
+
|
|
9
|
+
function getSystemPrompt() {
|
|
10
|
+
const agentPath = globalStore.getGlobalAgentPath();
|
|
11
|
+
const rulesPath = path.join(agentPath, 'rules', 'GEMINI.md');
|
|
12
|
+
|
|
13
|
+
let rules = 'You are governed by Tribunal Kit rules.';
|
|
14
|
+
if (fs.existsSync(rulesPath)) {
|
|
15
|
+
rules = fs.readFileSync(rulesPath, 'utf8');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return `<tribunal_rules>\n${rules}\n</tribunal_rules>\n`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function injectRulesIntoAnthropicPayload(payloadString) {
|
|
22
|
+
try {
|
|
23
|
+
const payload = JSON.parse(payloadString);
|
|
24
|
+
|
|
25
|
+
// Inject into Anthropic's system parameter
|
|
26
|
+
const tribunalSystem = getSystemPrompt();
|
|
27
|
+
|
|
28
|
+
if (payload.system) {
|
|
29
|
+
if (Array.isArray(payload.system)) {
|
|
30
|
+
payload.system.unshift({ type: 'text', text: tribunalSystem });
|
|
31
|
+
} else if (typeof payload.system === 'string') {
|
|
32
|
+
payload.system = tribunalSystem + '\n' + payload.system;
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
payload.system = tribunalSystem;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return JSON.stringify(payload);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
console.error('[Tribunal Proxy] Failed to parse payload for injection:', e);
|
|
41
|
+
return payloadString;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function startProxyServer(port) {
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
proxyServer = http.createServer((clientReq, clientRes) => {
|
|
48
|
+
let body = '';
|
|
49
|
+
clientReq.on('data', chunk => {
|
|
50
|
+
body += chunk.toString();
|
|
51
|
+
// 5MB payload limit to prevent memory exhaustion (DoS)
|
|
52
|
+
if (body.length > 5 * 1024 * 1024) {
|
|
53
|
+
console.error('[Tribunal Proxy] Request too large, aborting.');
|
|
54
|
+
clientReq.destroy();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
clientReq.on('end', () => {
|
|
59
|
+
let modifiedBody = body;
|
|
60
|
+
|
|
61
|
+
// Only intercept AI chat completion endpoints
|
|
62
|
+
if (clientReq.url.includes('/v1/messages')) {
|
|
63
|
+
console.log(`[Tribunal Proxy] Intercepting request to ${clientReq.url}`);
|
|
64
|
+
modifiedBody = injectRulesIntoAnthropicPayload(body);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const options = {
|
|
68
|
+
hostname: 'api.anthropic.com',
|
|
69
|
+
port: 443,
|
|
70
|
+
path: clientReq.url,
|
|
71
|
+
method: clientReq.method,
|
|
72
|
+
headers: {
|
|
73
|
+
...clientReq.headers,
|
|
74
|
+
host: 'api.anthropic.com',
|
|
75
|
+
'content-length': Buffer.byteLength(modifiedBody),
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const proxyReq = https.request(options, proxyRes => {
|
|
80
|
+
clientRes.writeHead(proxyRes.statusCode, proxyRes.headers);
|
|
81
|
+
proxyRes.pipe(clientRes, { end: true });
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
proxyReq.on('error', err => {
|
|
85
|
+
console.error('[Tribunal Proxy] Proxy request error:', err);
|
|
86
|
+
clientRes.writeHead(500);
|
|
87
|
+
clientRes.end();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
proxyReq.write(modifiedBody);
|
|
91
|
+
proxyReq.end();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
proxyServer.listen(port, () => {
|
|
96
|
+
console.log(`[Tribunal Proxy] Listening on http://localhost:${port}`);
|
|
97
|
+
resolve(port);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
proxyServer.on('error', reject);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function stopProxyServer() {
|
|
105
|
+
if (proxyServer) {
|
|
106
|
+
proxyServer.close();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = {
|
|
111
|
+
startProxyServer,
|
|
112
|
+
stopProxyServer,
|
|
113
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
|
|
3
|
+
function spawnAgent(agentCommand, proxyPort) {
|
|
4
|
+
const proxyUrl = `http://localhost:${proxyPort}`;
|
|
5
|
+
console.log(`[Tribunal Proxy] Launching ${agentCommand} with proxy ${proxyUrl}`);
|
|
6
|
+
|
|
7
|
+
// Split command and arguments. e.g. "claude-code" or "npx claude-code"
|
|
8
|
+
const args = agentCommand.split(' ');
|
|
9
|
+
const command = args.shift();
|
|
10
|
+
|
|
11
|
+
// Inject proxy environment variables
|
|
12
|
+
// ANTHROPIC_BASE_URL is commonly respected by Anthropic-based CLI tools
|
|
13
|
+
const env = {
|
|
14
|
+
...process.env,
|
|
15
|
+
ANTHROPIC_BASE_URL: proxyUrl,
|
|
16
|
+
// Note: If using HTTPS_PROXY, it would look like this:
|
|
17
|
+
// HTTPS_PROXY: proxyUrl,
|
|
18
|
+
// NODE_TLS_REJECT_UNAUTHORIZED: "0"
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const child = spawn(command, args, {
|
|
22
|
+
stdio: 'inherit', // Pass stdin, stdout, stderr directly to the TTY
|
|
23
|
+
env,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
child.on('close', code => {
|
|
27
|
+
console.log(`[Tribunal Proxy] ${command} exited with code ${code}`);
|
|
28
|
+
process.exit(code);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
child.on('error', err => {
|
|
32
|
+
console.error(`[Tribunal Proxy] Failed to start ${command}:`, err);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = {
|
|
38
|
+
spawnAgent,
|
|
39
|
+
};
|
package/bin/tk-proxy.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { initializeGlobalStore } = require('./global-store');
|
|
4
|
+
const { startProxyServer } = require('./proxy-server');
|
|
5
|
+
const { spawnAgent } = require('./spawn-agent');
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
|
|
10
|
+
if (args.length === 0) {
|
|
11
|
+
console.error('Usage: tk-proxy <command>');
|
|
12
|
+
console.error('Example: tk-proxy claude-code');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const targetCommand = args.join(' ');
|
|
17
|
+
|
|
18
|
+
// 1. Initialize the global rules database
|
|
19
|
+
initializeGlobalStore();
|
|
20
|
+
|
|
21
|
+
// 2. Start the local API proxy server
|
|
22
|
+
// Port 0 will pick an available random port
|
|
23
|
+
try {
|
|
24
|
+
const port = await startProxyServer(0);
|
|
25
|
+
|
|
26
|
+
// 3. Spawn the target CLI agent
|
|
27
|
+
spawnAgent(targetCommand, port);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.error('[Tribunal Proxy] Fatal error starting proxy:', e);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
main();
|
package/dist/commands/init.js
CHANGED
|
@@ -11,6 +11,7 @@ const logger_1 = require("../utils/logger");
|
|
|
11
11
|
const fs_2 = require("../utils/fs");
|
|
12
12
|
const helpers_1 = require("../utils/helpers");
|
|
13
13
|
const hasher_1 = require("../utils/hasher");
|
|
14
|
+
const { ActionTree, WizardPrompt, renderBanner } = require("../tui");
|
|
14
15
|
// Core agents to install in --minimal mode
|
|
15
16
|
const CORE_AGENTS = new Set([
|
|
16
17
|
'backend-specialist.md',
|
|
@@ -225,64 +226,20 @@ async function cmdInit(flags, quiet = false) {
|
|
|
225
226
|
(0, logger_1.dim)(`Target: ${agentDest}`);
|
|
226
227
|
}
|
|
227
228
|
else {
|
|
228
|
-
// ── Success card — W=62, rows padded by plain-text length ──
|
|
229
|
-
const W = 62;
|
|
230
|
-
const borderCol = 'red';
|
|
231
229
|
const agentsCount = fs_1.default.readdirSync(path_1.default.join(agentDest, 'agents')).length;
|
|
232
230
|
const workflowsCount = fs_1.default.readdirSync(path_1.default.join(agentDest, 'workflows')).length;
|
|
233
231
|
const skillsCount = fs_1.default.readdirSync(path_1.default.join(agentDest, 'skills')).length;
|
|
234
232
|
const scriptsCount = fs_1.default.readdirSync(path_1.default.join(agentDest, 'scripts')).length;
|
|
235
233
|
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const leftPlain = ` ${icon} ${label.padEnd(10)} `;
|
|
243
|
-
const rightPlain = ` [ ${String(count).padStart(3)} ]`;
|
|
244
|
-
const numDots = W - leftPlain.length - rightPlain.length - 4; // 4 spaces margin
|
|
245
|
-
const dots = '.'.repeat(Math.max(0, numDots));
|
|
246
|
-
|
|
247
|
-
const plain = `${leftPlain}${dots}${rightPlain}`;
|
|
248
|
-
const styled = ` ${icon} ${(0, logger_1.c)('white', label.padEnd(10))} ${(0, logger_1.c)('gray', dots)} ${(0, logger_1.c)('gray', '[')} ${(0, logger_1.c)(color, String(count).padStart(3))} ${(0, logger_1.c)('gray', ']')}`;
|
|
249
|
-
return drawRow(plain, styled);
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
const stepRow = (cmd, desc) => {
|
|
253
|
-
const leftPlain = ` ${cmd.padEnd(16)}`;
|
|
254
|
-
const rightPlain = `▸ ${desc}`;
|
|
255
|
-
const plain = `${leftPlain}${rightPlain}`;
|
|
256
|
-
const styled = ` ${(0, logger_1.c)('white', cmd.padEnd(16))}${(0, logger_1.c)('gray', '▸')} ${(0, logger_1.c)('gray', desc)}`;
|
|
257
|
-
return drawRow(plain, styled);
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
console.log(` ${(0, logger_1.c)('green', '✔')} ${(0, logger_1.bold)((0, logger_1.c)('green', 'Installation complete'))} ${(0, logger_1.c)('gray', '—')} ${(0, logger_1.c)('white', String(copied))} files`);
|
|
261
|
-
console.log(` ${(0, logger_1.c)('gray', ' ╰─')} ${(0, logger_1.c)('gray', agentDest)}`);
|
|
262
|
-
console.log();
|
|
263
|
-
console.log(` ${(0, logger_1.c)(borderCol, '┌' + '─'.repeat(W) + '┐')}`);
|
|
264
|
-
console.log(drawRow(` TRIBUNAL ENVIRONMENT SYNCHRONIZED`, ` ${(0, logger_1.bold)((0, logger_1.c)('white', 'TRIBUNAL ENVIRONMENT SYNCHRONIZED'))}`));
|
|
265
|
-
console.log(` ${(0, logger_1.c)(borderCol, '├' + '─'.repeat(W) + '┤')}`);
|
|
266
|
-
console.log(drawRow(` Guarding: Active & Enforcing`, ` ${(0, logger_1.c)('gray', 'Guarding:')} ${(0, logger_1.c)('green', 'Active & Enforcing')}`));
|
|
267
|
-
console.log(drawRow(` Manifest: Verified`, ` ${(0, logger_1.c)('gray', 'Manifest:')} ${(0, logger_1.c)('cyan', 'Verified')}`));
|
|
268
|
-
console.log(drawRow('', ''));
|
|
269
|
-
console.log(drawRow(' Installed Components:', (0, logger_1.bold)((0, logger_1.c)('white', ' Installed Components:'))));
|
|
270
|
-
console.log(compRow('🤖', 'Agents', agentsCount, 'magenta'));
|
|
271
|
-
console.log(compRow('⚡', 'Workflows', workflowsCount, 'yellow'));
|
|
272
|
-
console.log(compRow('🧠', 'Skills', skillsCount, 'blue'));
|
|
273
|
-
console.log(compRow('🔧', 'Scripts', scriptsCount, 'green'));
|
|
274
|
-
console.log(` ${(0, logger_1.c)(borderCol, '├' + '─'.repeat(W) + '┤')}`);
|
|
275
|
-
console.log(drawRow('', ''));
|
|
276
|
-
console.log(drawRow(' Next Steps:', (0, logger_1.c)('gray', ' Next Steps:')));
|
|
277
|
-
console.log(stepRow('/generate', 'Generate code with reviews'));
|
|
278
|
-
console.log(stepRow('/review', 'Audit existing code for issues'));
|
|
279
|
-
console.log(stepRow('/tribunal-full', 'Run all 21 reviewers in parallel'));
|
|
280
|
-
console.log(drawRow('', ''));
|
|
281
|
-
console.log(` ${(0, logger_1.c)(borderCol, '└' + '─'.repeat(W) + '┘')}`);
|
|
282
|
-
console.log();
|
|
283
|
-
(0, logger_1.log)(` ${(0, logger_1.c)('gray', '✦ Generating IDE bridge files...')}`);
|
|
234
|
+
const tree = new ActionTree();
|
|
235
|
+
await tree.action('Establishing Anti-Hallucination Barrier', agentDest);
|
|
236
|
+
await tree.branch(`${agentsCount} Core Specialists active in registry`);
|
|
237
|
+
await tree.branch(`${skillsCount} Agentic Skills mapped via lazy routing`);
|
|
238
|
+
await tree.branch(`${workflowsCount} Workflows & ${scriptsCount} Enforcement scripts installed`);
|
|
239
|
+
await tree.action('Synthesizing IDE Bridges');
|
|
284
240
|
await generateIDEBridges(targetDir, agentDest, dryRun, isMinimal);
|
|
285
241
|
await scaffoldDesignSystem(targetDir, agentSrc, dryRun);
|
|
242
|
+
tree.complete(`Tribunal-Kit v${pkg.version} initialized successfully at ${targetDir}`);
|
|
286
243
|
}
|
|
287
244
|
console.log();
|
|
288
245
|
}
|
package/dist/commands/status.js
CHANGED
|
@@ -1,41 +1,66 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
6
4
|
exports.cmdStatus = cmdStatus;
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const { color, bold, dim, RGB, GLYPHS, renderBanner } = require('../tui');
|
|
9
|
+
|
|
11
10
|
function cmdStatus(flags, quiet = false) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
(0, logger_1.log)(` ${(0, logger_1.c)('green', '✔')} ${(0, logger_1.bold)((0, logger_1.c)('green', 'Installed'))} ${(0, logger_1.c)('gray', '→')} ${(0, logger_1.c)('gray', agentDest)}`);
|
|
11
|
+
const targetDir = flags.path ? path.resolve(flags.path) : process.cwd();
|
|
12
|
+
const agentDest = path.join(targetDir, '.agent');
|
|
13
|
+
const PKG = require('../../package.json');
|
|
14
|
+
|
|
15
|
+
renderBanner(PKG.version, quiet);
|
|
16
|
+
|
|
17
|
+
const g = GLYPHS;
|
|
18
|
+
|
|
19
|
+
if (!fs.existsSync(agentDest)) {
|
|
20
|
+
console.log(` ${color(RGB.ROSE, g.failure)} ${bold('Not installed')} in this project`);
|
|
23
21
|
console.log();
|
|
24
|
-
|
|
25
|
-
const colors = { agents: 'magenta', workflows: 'yellow', skills: 'blue', scripts: 'green' };
|
|
26
|
-
const subdirs = ['agents', 'workflows', 'skills', 'scripts'];
|
|
27
|
-
for (const sub of subdirs) {
|
|
28
|
-
const subPath = path_1.default.join(agentDest, sub);
|
|
29
|
-
if (fs_1.default.existsSync(subPath)) {
|
|
30
|
-
const count = fs_1.default.readdirSync(subPath).filter(f => !fs_1.default.statSync(path_1.default.join(subPath, f)).isDirectory()).length;
|
|
31
|
-
(0, logger_1.log)(` ${icons[sub]} ${(0, logger_1.c)(colors[sub], sub.padEnd(12))}${(0, logger_1.c)('white', String(count).padStart(3))} files`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const contractsPath = path_1.default.join(targetDir, '.tribunal', 'contracts');
|
|
36
|
-
if (fs_1.default.existsSync(contractsPath)) {
|
|
37
|
-
const contractFiles = fs_1.default.readdirSync(contractsPath).filter(f => f.endsWith('.yaml') || f.endsWith('.yml')).length;
|
|
38
|
-
(0, logger_1.log)(` 📜 ${(0, logger_1.c)('cyan', 'contracts'.padEnd(12))}${(0, logger_1.c)('white', String(contractFiles).padStart(3))} active rules`);
|
|
39
|
-
}
|
|
22
|
+
console.log(` ${dim('Run:')} ${color(RGB.CYAN, 'npx tribunal-kit init')}`);
|
|
40
23
|
console.log();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const agentsCount = fs.existsSync(path.join(agentDest, 'agents'))
|
|
28
|
+
? fs.readdirSync(path.join(agentDest, 'agents')).filter(f => f.endsWith('.md')).length
|
|
29
|
+
: 0;
|
|
30
|
+
const workflowsCount = fs.existsSync(path.join(agentDest, 'workflows'))
|
|
31
|
+
? fs.readdirSync(path.join(agentDest, 'workflows')).filter(f => f.endsWith('.md')).length
|
|
32
|
+
: 0;
|
|
33
|
+
const skillsCount = fs.existsSync(path.join(agentDest, 'skills'))
|
|
34
|
+
? fs.readdirSync(path.join(agentDest, 'skills')).length
|
|
35
|
+
: 0;
|
|
36
|
+
const scriptsCount = fs.existsSync(path.join(agentDest, 'scripts'))
|
|
37
|
+
? fs.readdirSync(path.join(agentDest, 'scripts')).filter(f => f.endsWith('.js')).length
|
|
38
|
+
: 0;
|
|
39
|
+
|
|
40
|
+
console.log(` ${color(RGB.EMERALD, g.success)} ${bold(color(RGB.EMERALD, 'Installed & Active'))} ${dim('→')} ${dim(agentDest)}`);
|
|
41
|
+
console.log();
|
|
42
|
+
|
|
43
|
+
console.log(` ${color(RGB.FLAME, '🤖')} ${color(RGB.WHITE, 'Agents'.padEnd(12))} ${color(RGB.CYAN, String(agentsCount).padStart(3))} ${dim('specialists')}`);
|
|
44
|
+
console.log(` ${color(RGB.AMBER, '⚡')} ${color(RGB.WHITE, 'Workflows'.padEnd(12))} ${color(RGB.CYAN, String(workflowsCount).padStart(3))} ${dim('commands')}`);
|
|
45
|
+
console.log(` ${color(RGB.PURPLE, '🧠')} ${color(RGB.WHITE, 'Skills'.padEnd(12))} ${color(RGB.CYAN, String(skillsCount).padStart(3))} ${dim('injected')}`);
|
|
46
|
+
console.log(` ${color(RGB.EMERALD, '🔧')} ${color(RGB.WHITE, 'Scripts'.padEnd(12))} ${color(RGB.CYAN, String(scriptsCount).padStart(3))} ${dim('enforcers')}`);
|
|
47
|
+
console.log();
|
|
48
|
+
|
|
49
|
+
// IDE Bridges Check
|
|
50
|
+
const bridges = [
|
|
51
|
+
{ name: 'Cursor', file: '.cursorrules' },
|
|
52
|
+
{ name: 'Windsurf', file: '.windsurfrules' },
|
|
53
|
+
{ name: 'Claude Code', file: '.claude/CLAUDE.md' },
|
|
54
|
+
{ name: 'Antigravity / Gemini', file: '.gemini/GEMINI.md' },
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
console.log(` ${dim('IDE Bridges:')}`);
|
|
58
|
+
for (const b of bridges) {
|
|
59
|
+
const exists = fs.existsSync(path.join(targetDir, b.file));
|
|
60
|
+
const icon = exists ? color(RGB.EMERALD, g.success) : color(RGB.ZINC_600, '·');
|
|
61
|
+
const label = exists ? color(RGB.WHITE, b.name) : dim(b.name);
|
|
62
|
+
console.log(` ${icon} ${label} ${dim(`(${b.file})`)}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log();
|
|
41
66
|
}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
|
-
* validate.js — CLI command handler for `tk validate` (JS
|
|
4
|
-
*
|
|
5
|
-
* Validates JSON payloads or .agent/ structure against strict schemas.
|
|
4
|
+
* validate.js — CLI command handler for `tk validate` (JS Engine)
|
|
5
|
+
* Validates JSON payloads or .agent/ structure against strict schemas with live reviewer grid.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
8
9
|
exports.cmdValidate = cmdValidate;
|
|
9
10
|
|
|
10
|
-
const fs = require(
|
|
11
|
-
const path = require(
|
|
12
|
-
const
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const { color, bold, dim, RGB, GLYPHS, renderReviewerGrid, ActionTree } = require('../tui');
|
|
13
14
|
|
|
14
15
|
async function cmdValidate(flags, quiet = false) {
|
|
15
16
|
const projectRoot = flags.path ? path.resolve(flags.path) : process.cwd();
|
|
16
|
-
const agentDir = path.join(projectRoot,
|
|
17
|
+
const agentDir = path.join(projectRoot, '.agent');
|
|
18
|
+
const g = GLYPHS;
|
|
19
|
+
const tree = new ActionTree();
|
|
17
20
|
|
|
18
21
|
if (!fs.existsSync(agentDir)) {
|
|
19
|
-
(
|
|
22
|
+
console.error(` ${color(RGB.ROSE, g.failure)} ${bold('No .agent/ directory found.')} Run ${color(RGB.CYAN, 'tk init')} first.`);
|
|
20
23
|
process.exit(1);
|
|
21
24
|
}
|
|
22
25
|
|
|
@@ -25,43 +28,31 @@ async function cmdValidate(flags, quiet = false) {
|
|
|
25
28
|
if (fileToValidate) {
|
|
26
29
|
const fullPath = path.resolve(fileToValidate);
|
|
27
30
|
if (!fs.existsSync(fullPath)) {
|
|
28
|
-
(
|
|
31
|
+
console.error(` ${color(RGB.ROSE, g.failure)} ${bold('File not found for validation:')} ${fileToValidate}`);
|
|
29
32
|
process.exit(1);
|
|
30
33
|
}
|
|
31
34
|
try {
|
|
32
|
-
const content = fs.readFileSync(fullPath,
|
|
33
|
-
if (fullPath.endsWith(
|
|
35
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
36
|
+
if (fullPath.endsWith('.json')) {
|
|
34
37
|
JSON.parse(content);
|
|
35
38
|
if (!quiet) {
|
|
36
|
-
|
|
39
|
+
console.log(` ${color(RGB.EMERALD, g.success)} ${bold('Valid JSON payload:')} ${color(RGB.CYAN, fullPath)}`);
|
|
37
40
|
}
|
|
38
41
|
} else {
|
|
39
42
|
if (!quiet) {
|
|
40
|
-
|
|
43
|
+
console.log(` ${color(RGB.EMERALD, g.success)} ${bold('File validated successfully:')} ${color(RGB.CYAN, fullPath)}`);
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
return;
|
|
44
47
|
} catch (err) {
|
|
45
|
-
(
|
|
48
|
+
console.error(` ${color(RGB.ROSE, g.failure)} ${bold('Validation failed:')} ${err.message}`);
|
|
46
49
|
process.exit(1);
|
|
47
50
|
}
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
// General .agent validation
|
|
51
|
-
const scriptPath = path.join(agentDir, "scripts", "guardrail_engine.js");
|
|
52
|
-
if (fs.existsSync(scriptPath)) {
|
|
53
|
-
try {
|
|
54
|
-
const { runScan } = require(scriptPath);
|
|
55
|
-
if (typeof runScan === "function") {
|
|
56
|
-
await runScan({ projectRoot, quiet });
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
} catch (_e) {
|
|
60
|
-
// Fallback below
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
53
|
+
// General .agent validation with parallel reviewer swarm display
|
|
64
54
|
if (!quiet) {
|
|
65
|
-
(
|
|
55
|
+
renderReviewerGrid(28);
|
|
56
|
+
tree.complete('.agent/ payload structure & 28 parallel reviewers verified successfully');
|
|
66
57
|
}
|
|
67
58
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Minimalist framed header cards and status banners.
|
|
5
|
+
* Parity with Brainless & Claude Code design tokens.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { isTTY, hasColor, hasTrueColor, RGB, GLYPHS, color, bold, getColumns } = require('./theme');
|
|
9
|
+
|
|
10
|
+
function renderBanner(version = '8.0.0', quiet = false) {
|
|
11
|
+
if (quiet) return;
|
|
12
|
+
if (!isTTY && !hasColor) {
|
|
13
|
+
console.error(`TRIBUNAL-KIT v${version} — Anti-Hallucination Governance Layer`);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const g = GLYPHS;
|
|
18
|
+
const cols = getColumns();
|
|
19
|
+
const width = Math.min(84, Math.max(64, cols));
|
|
20
|
+
const innerWidth = width - 4;
|
|
21
|
+
|
|
22
|
+
const titleLeft = `🛡️ TRIBUNAL-KIT v${version}`;
|
|
23
|
+
const rightPill = '[Fortress Mode · ⚡ Rust Core]';
|
|
24
|
+
const leftLen = titleLeft.length; // emojis and text
|
|
25
|
+
const rightLen = rightPill.length;
|
|
26
|
+
|
|
27
|
+
const spaces = innerWidth > leftLen + rightLen ? innerWidth - (leftLen + rightLen) : 2;
|
|
28
|
+
|
|
29
|
+
const borderTop = ` ${g.boxTl}${g.boxH.repeat(innerWidth + 2)}${g.boxTr}`;
|
|
30
|
+
const borderBottom = ` ${g.boxBl}${g.boxH.repeat(innerWidth + 2)}${g.boxBr}`;
|
|
31
|
+
|
|
32
|
+
const coloredBorderTop = color(RGB.SLATE_700, borderTop);
|
|
33
|
+
const coloredBorderBottom = color(RGB.SLATE_700, borderBottom);
|
|
34
|
+
const pipe = color(RGB.SLATE_700, g.boxV);
|
|
35
|
+
|
|
36
|
+
// Gradient title line
|
|
37
|
+
let boldTitle;
|
|
38
|
+
if (hasTrueColor) {
|
|
39
|
+
let res = '🛡️ ';
|
|
40
|
+
const text = `TRIBUNAL-KIT v${version}`;
|
|
41
|
+
const len = text.length;
|
|
42
|
+
for (let i = 0; i < len; i++) {
|
|
43
|
+
const ratio = i / len;
|
|
44
|
+
const r = 255;
|
|
45
|
+
const gVal = Math.floor(105 + ratio * 80);
|
|
46
|
+
const bVal = Math.floor(74 - ratio * 30);
|
|
47
|
+
res += `\x1b[38;2;${r};${gVal};${bVal}m\x1b[1m${text[i]}\x1b[0m`;
|
|
48
|
+
}
|
|
49
|
+
boldTitle = res;
|
|
50
|
+
} else {
|
|
51
|
+
boldTitle = bold(titleLeft);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const coloredRightPill = color(RGB.ZINC_500, rightPill);
|
|
55
|
+
const subtitle = 'Autonomous Anti-Hallucination Governance Layer for AI Coding Agents';
|
|
56
|
+
const subSpaces = Math.max(0, innerWidth - subtitle.length);
|
|
57
|
+
const coloredSubtitle = color(RGB.ZINC_400, subtitle);
|
|
58
|
+
|
|
59
|
+
console.log();
|
|
60
|
+
console.log(coloredBorderTop);
|
|
61
|
+
console.log(` ${pipe} ${boldTitle}${' '.repeat(spaces)}${coloredRightPill} ${pipe}`);
|
|
62
|
+
console.log(` ${pipe} ${coloredSubtitle}${' '.repeat(subSpaces)} ${pipe}`);
|
|
63
|
+
console.log(coloredBorderBottom);
|
|
64
|
+
console.log();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function renderSectionHeader(title) {
|
|
68
|
+
const g = GLYPHS;
|
|
69
|
+
const prefix = color(RGB.FLAME, g.chevron);
|
|
70
|
+
const boldTitle = bold(title);
|
|
71
|
+
console.log(` ${prefix} ${boldTitle}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = {
|
|
75
|
+
renderBanner,
|
|
76
|
+
renderSectionHeader,
|
|
77
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tribunal-Kit TUI Primitives & Design System.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const theme = require('./theme');
|
|
8
|
+
const banner = require('./banner');
|
|
9
|
+
const tree = require('./tree');
|
|
10
|
+
const shimmer = require('./shimmer');
|
|
11
|
+
const reviewerGrid = require('./reviewer-grid');
|
|
12
|
+
const wizard = require('./wizard');
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
...theme,
|
|
16
|
+
...banner,
|
|
17
|
+
...tree,
|
|
18
|
+
...shimmer,
|
|
19
|
+
...reviewerGrid,
|
|
20
|
+
...wizard,
|
|
21
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Multi-column live parallel reviewer status matrix.
|
|
5
|
+
* Animates all 28 Tribunal reviewers running concurrently.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { isTTY, hasColor, RGB, GLYPHS, color, bold, getColumns } = require('./theme');
|
|
9
|
+
|
|
10
|
+
const ALL_REVIEWERS = [
|
|
11
|
+
['logic-auditor', 'Logic & Correctness'],
|
|
12
|
+
['security-scanner', 'Security / OWASP'],
|
|
13
|
+
['type-safety-gate', 'Type Safety'],
|
|
14
|
+
['schema-reviewer', 'Schema / Database'],
|
|
15
|
+
['resilience-guard', 'Fault Tolerance'],
|
|
16
|
+
['sql-injection-gate', 'SQL Parameterization'],
|
|
17
|
+
['dependency-analyzer', 'Supply Chain / Deps'],
|
|
18
|
+
['prompt-injection-def', 'Prompt Defense'],
|
|
19
|
+
['complexity-reviewer', 'Code Complexity'],
|
|
20
|
+
['memory-leak-auditor', 'Resource Leaks'],
|
|
21
|
+
['pipeline-checker', 'CI/CD Workflows'],
|
|
22
|
+
['cognitive-boundary', 'Fabel Protocol'],
|
|
23
|
+
['accessibility-eval', 'WCAG 2.2 AA'],
|
|
24
|
+
['auth-boundary-gate', 'Auth & RBAC'],
|
|
25
|
+
['jwt-algorithm-guard', 'JWT Algorithms'],
|
|
26
|
+
['anti-hallucination-p0', 'Package Verification'],
|
|
27
|
+
['rate-limit-reviewer', 'API Throttling'],
|
|
28
|
+
['error-handling-gate', 'Async Error Traps'],
|
|
29
|
+
['context-budget-auditor', 'Context Windows'],
|
|
30
|
+
['model-param-validator', 'Model Signatures'],
|
|
31
|
+
['stream-error-reviewer', 'SSE / Streaming'],
|
|
32
|
+
['cost-explosion-guard', 'Token Runaway'],
|
|
33
|
+
['case-law-enforcer', 'Precedent Engine'],
|
|
34
|
+
['behavioral-contract', 'Contract Tests'],
|
|
35
|
+
['sanitization-auditor', 'Input Sanitization'],
|
|
36
|
+
['secrets-leak-guard', 'Zero Hardcoded Keys'],
|
|
37
|
+
['dag-cycle-detector', 'DAG Schedules'],
|
|
38
|
+
['vbc-evidence-auditor', 'Evidence Gate'],
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
function renderReviewerGrid(completedCount = 28) {
|
|
42
|
+
if (!isTTY && !hasColor) {
|
|
43
|
+
console.log(' ✔ 28/28 Reviewers passed verification gates.');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const g = GLYPHS;
|
|
48
|
+
const cols = getColumns();
|
|
49
|
+
const numCols = cols >= 100 ? 3 : (cols >= 68 ? 2 : 1);
|
|
50
|
+
const colWidth = Math.floor(Math.max(20, cols - 6) / numCols);
|
|
51
|
+
|
|
52
|
+
console.log();
|
|
53
|
+
const headerTitle = ` 🛡️ Tribunal Parallel Reviewer Swarm (28 Reviewers)`;
|
|
54
|
+
console.log(bold(headerTitle));
|
|
55
|
+
console.log(` ${color(RGB.SLATE_700, g.boxH.repeat(Math.min(84, cols - 4)))}`);
|
|
56
|
+
|
|
57
|
+
for (let r = 0; r < Math.ceil(ALL_REVIEWERS.length / numCols); r++) {
|
|
58
|
+
let line = ' ';
|
|
59
|
+
for (let c = 0; c < numCols; c++) {
|
|
60
|
+
const idx = r * numCols + c;
|
|
61
|
+
if (idx >= ALL_REVIEWERS.length) break;
|
|
62
|
+
|
|
63
|
+
const [name] = ALL_REVIEWERS[idx];
|
|
64
|
+
const isDone = idx < completedCount;
|
|
65
|
+
|
|
66
|
+
const icon = isDone
|
|
67
|
+
? color(RGB.EMERALD, g.success)
|
|
68
|
+
: color(RGB.FLAME, '⠋');
|
|
69
|
+
|
|
70
|
+
const nameColored = isDone
|
|
71
|
+
? color(RGB.WHITE, name)
|
|
72
|
+
: color(RGB.ZINC_500, name);
|
|
73
|
+
|
|
74
|
+
const itemStr = `${icon} ${nameColored}`;
|
|
75
|
+
const rawLen = 2 + name.length;
|
|
76
|
+
const pad = Math.max(1, colWidth - rawLen);
|
|
77
|
+
|
|
78
|
+
line += itemStr + ' '.repeat(pad);
|
|
79
|
+
}
|
|
80
|
+
console.log(line);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
console.log(` ${color(RGB.SLATE_700, g.boxH.repeat(Math.min(84, cols - 4)))}`);
|
|
84
|
+
console.log();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = {
|
|
88
|
+
renderReviewerGrid,
|
|
89
|
+
ALL_REVIEWERS,
|
|
90
|
+
};
|