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.
Files changed (95) hide show
  1. package/.agent/config/claude.json +18 -0
  2. package/.agent/config/plugin.json +102 -0
  3. package/.agent/config/slash-commands.json +103 -0
  4. package/.agent/config/specialist-registry.json +415 -0
  5. package/.agent/config/system-prompt.md +191 -0
  6. package/.agent/history/architecture-graph.yaml +302 -3
  7. package/.agent/history/graph-cache.json +515 -45
  8. package/.agent/history/memory.db +0 -0
  9. package/.agent/history/snapshots/bin__adapter-install.js.json +13 -0
  10. package/.agent/history/snapshots/bin__global-store.js.json +15 -0
  11. package/.agent/history/snapshots/bin__mcp-server.js.json +19 -0
  12. package/.agent/history/snapshots/bin__proxy-server.js.json +20 -0
  13. package/.agent/history/snapshots/bin__spawn-agent.js.json +12 -0
  14. package/.agent/history/snapshots/bin__tk-proxy.js.json +21 -0
  15. package/.agent/history/snapshots/bin__tribunal-kit.js.json +9 -7
  16. package/.agent/history/snapshots/bin__wrapper.js.json +14 -0
  17. package/.agent/history/snapshots/eslint.config.js.json +1 -2
  18. package/.agent/history/snapshots/scripts__benchmark.js.json +14 -0
  19. package/.agent/history/snapshots/scripts__changelog.js.json +1 -2
  20. package/.agent/history/snapshots/scripts__fix-vbc.js.json +11 -0
  21. package/.agent/history/snapshots/scripts__stress_benchmark.js.json +15 -0
  22. package/.agent/history/snapshots/scripts__sync-version.js.json +1 -2
  23. package/.agent/history/snapshots/scripts__validate-payload.js.json +1 -2
  24. package/.agent/history/snapshots/scripts__visual_audit.js.json +11 -0
  25. package/.agent/history/snapshots/test__integration__bridges.test.js.json +1 -2
  26. package/.agent/history/snapshots/test__integration__graceful_degradation.test.js.json +12 -0
  27. package/.agent/history/snapshots/test__integration__init.test.js.json +1 -2
  28. package/.agent/history/snapshots/test__integration__minimal_change_pipeline.test.js.json +13 -0
  29. package/.agent/history/snapshots/test__integration__parallel_tribunal.test.js.json +12 -0
  30. package/.agent/history/snapshots/test__integration__routing.test.js.json +1 -2
  31. package/.agent/history/snapshots/test__integration__swarm_dispatcher.test.js.json +1 -2
  32. package/.agent/history/snapshots/test__integration__sync_status.test.js.json +13 -0
  33. package/.agent/history/snapshots/test__integration__wave2.test.js.json +1 -2
  34. package/.agent/history/snapshots/test__integration__wrapper.test.js.json +13 -0
  35. package/.agent/history/snapshots/test__unit__align.test.js.json +10 -0
  36. package/.agent/history/snapshots/test__unit__args.test.js.json +3 -3
  37. package/.agent/history/snapshots/test__unit__audit_release.test.js.json +16 -0
  38. package/.agent/history/snapshots/test__unit__case_law_manager.test.js.json +1 -2
  39. package/.agent/history/snapshots/test__unit__cicd_validator.test.js.json +12 -0
  40. package/.agent/history/snapshots/test__unit__compile.test.js.json +10 -0
  41. package/.agent/history/snapshots/test__unit__context_broker.test.js.json +1 -2
  42. package/.agent/history/snapshots/test__unit__contract_engine.test.js.json +13 -0
  43. package/.agent/history/snapshots/test__unit__copyDir.test.js.json +3 -3
  44. package/.agent/history/snapshots/test__unit__graph_tools.test.js.json +1 -2
  45. package/.agent/history/snapshots/test__unit__guardrail_engine.test.js.json +10 -0
  46. package/.agent/history/snapshots/test__unit__impact_classifier.test.js.json +12 -0
  47. package/.agent/history/snapshots/test__unit__init.test.js.json +14 -0
  48. package/.agent/history/snapshots/test__unit__inner_loop_validator.test.js.json +1 -2
  49. package/.agent/history/snapshots/test__unit__integrity_manifest.test.js.json +13 -0
  50. package/.agent/history/snapshots/test__unit__learn.test.js.json +11 -0
  51. package/.agent/history/snapshots/test__unit__marathon.test.js.json +22 -0
  52. package/.agent/history/snapshots/test__unit__mcp_server.test.js.json +16 -0
  53. package/.agent/history/snapshots/test__unit__memory.test.js.json +13 -0
  54. package/.agent/history/snapshots/test__unit__minimal_change.test.js.json +10 -0
  55. package/.agent/history/snapshots/test__unit__native.test.js.json +10 -0
  56. package/.agent/history/snapshots/test__unit__optimize.test.js.json +13 -0
  57. package/.agent/history/snapshots/test__unit__path_resolution.test.js.json +14 -0
  58. package/.agent/history/snapshots/test__unit__production_readiness_evidence.test.js.json +21 -0
  59. package/.agent/history/snapshots/test__unit__selfInstall.test.js.json +3 -3
  60. package/.agent/history/snapshots/test__unit__semver.test.js.json +3 -3
  61. package/.agent/history/snapshots/test__unit__skill_evolution.test.js.json +11 -0
  62. package/.agent/history/snapshots/test__unit__stress.test.js.json +15 -0
  63. package/.agent/history/snapshots/test__unit__swarm_dispatcher.test.js.json +3 -3
  64. package/.agent/history/snapshots/test__unit__utils.test.js.json +10 -0
  65. package/.agent/scripts/ast_context_loader.js +137 -0
  66. package/.agent/scripts/memory_engine.js +581 -0
  67. package/.agent/scripts/payload_schemas.js +146 -0
  68. package/.agent/scripts/prompt_compiler.js +59 -11
  69. package/.agent/scripts/swarm_dispatcher.js +295 -67
  70. package/.agent/scripts/token_budget_broker.js +117 -6
  71. package/.claude/CLAUDE.md +442 -0
  72. package/README.md +22 -12
  73. package/SECURITY.md +3 -3
  74. package/bin/adapter-install.js +240 -0
  75. package/bin/global-store.js +48 -0
  76. package/bin/mcp-server.js +568 -252
  77. package/bin/proxy-server.js +113 -0
  78. package/bin/spawn-agent.js +39 -0
  79. package/bin/tk-proxy.js +34 -0
  80. package/dist/commands/init.js +8 -51
  81. package/dist/commands/status.js +61 -36
  82. package/dist/commands/validate.js +22 -31
  83. package/dist/tui/banner.js +77 -0
  84. package/dist/tui/index.js +21 -0
  85. package/dist/tui/reviewer-grid.js +90 -0
  86. package/dist/tui/shimmer.js +91 -0
  87. package/dist/tui/theme.js +130 -0
  88. package/dist/tui/tree.js +93 -0
  89. package/dist/tui/wizard.js +148 -0
  90. package/dist/utils/helpers.js +5 -41
  91. package/package.json +27 -10
  92. package/scripts/build-graph.js +71 -0
  93. package/.agent/history/snapshots/migrate_refs.js.json +0 -11
  94. package/.agent/scripts/compile_router.py +0 -5
  95. package/.agent/scripts/migrate_skills_frontmatter.py +0 -5
@@ -0,0 +1,15 @@
1
+ {
2
+ "file": "scripts/stress_benchmark.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 1,
5
+ "imports": {
6
+ "fs": [],
7
+ "path": [],
8
+ "os": [],
9
+ "perf_hooks": []
10
+ },
11
+ "dependents": [
12
+ "test/unit/stress.test.js"
13
+ ],
14
+ "content": "#!/usr/bin/env node\n/**\n * Tribunal-Kit Deep Stress Benchmark & Verification Suite\n * =========================================================\n * Heavy-load stress testing for high performance, zero hallucination,\n * low token consumption, and absolute governance integrity.\n *\n * Run: node scripts/stress_benchmark.js\n */\n\n'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\nconst os = require('os');\nconst { performance } = require('perf_hooks');\n\n// ANSI colors\nconst C = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n green: '\\x1b[92m',\n yellow: '\\x1b[93m',\n cyan: '\\x1b[96m',\n red: '\\x1b[91m',\n gray: '\\x1b[90m',\n white: '\\x1b[97m',\n};\n\nfunction c(color, text) {\n return `${C[color]}${text}${C.reset}`;\n}\nfunction bold(text) {\n return `${C.bold}${text}${C.reset}`;\n}\n\n// Target scripts\nconst SCRIPT_DIR = path.resolve(__dirname, '../.agent/scripts');\nconst contextBroker = require(path.join(SCRIPT_DIR, 'context_broker.js'));\nconst pipelineEngine = require(path.join(SCRIPT_DIR, 'pipeline_engine.js'));\nconst innerLoopValidator = require(path.join(SCRIPT_DIR, 'inner_loop_validator.js'));\nconst contractEngine = require(path.join(SCRIPT_DIR, 'contract_engine.js'));\nconst promptCompiler = require(path.join(SCRIPT_DIR, 'prompt_compiler.js'));\nconst _graphBuilder = require(path.join(SCRIPT_DIR, 'graph_builder.js'));\nconst swarmDispatcher = require(path.join(SCRIPT_DIR, 'swarm_dispatcher.js'));\n\nasync function runStressSuite() {\n console.log('');\n console.log(bold(` 🚀 Tribunal-Kit Governance Stress & Optimization Benchmark`));\n console.log(c('gray', ` ─────────────────────────────────────────────────────────────`));\n console.log(\n c(\n 'gray',\n ` Platform: ${os.platform()} ${os.arch()} | Node: ${process.version} | CPUs: ${os.cpus().length}`,\n ),\n );\n console.log(c('gray', ` ─────────────────────────────────────────────────────────────`));\n console.log('');\n\n const results = {\n concurrency: null,\n scale: null,\n token_compression: null,\n anti_hallucination: null,\n };\n\n // ── 1. High Concurrency Stress Test ─────────────────────────────────────────\n console.log(\n c('cyan', ' ▸ [STRESS 1/4] High-Concurrency Engine Dispatch (50 Parallel Requests)...'),\n );\n {\n const CONCURRENCY_COUNT = 50;\n const startMem = process.memoryUsage().heapUsed;\n const startTime = performance.now();\n\n const tasks = Array.from({ length: CONCURRENCY_COUNT }, (_, i) => {\n return (async () => {\n // Run context broker lookup\n const cbRes = contextBroker.resolveContext({\n task: `Task ${i}: Build secure authentication with JWT and React`,\n model: i % 2 === 0 ? 'large' : 'small',\n });\n\n // Run inner loop validator snippet check\n const snippet = [\n 'const jwt = req' + 'uire(\"jsonwebtoken\");',\n 'function login(user) {',\n ' if (!user) throw new Error(\"User required\");',\n ' return jwt.sign({ id: user.id }, \"secret\", { expiresIn: \"1h\" });',\n '}',\n ].join('\\n');\n const valRes = innerLoopValidator.validateSnippet(snippet, 'ts');\n\n // Run pipeline plan phase\n const planRes = pipelineEngine.planPhase(`Build API route ${i}`, [`route${i}.ts`]);\n\n return { cbRes, valRes, planRes };\n })();\n });\n\n const completed = await Promise.all(tasks);\n const endTime = performance.now();\n const endMem = process.memoryUsage().heapUsed;\n\n const totalMs = endTime - startTime;\n const opsPerSec = Math.round((CONCURRENCY_COUNT * 3 * 1000) / totalMs);\n const memDeltaMb = Math.round(((endMem - startMem) / 1024 / 1024) * 100) / 100;\n\n results.concurrency = {\n total_operations: CONCURRENCY_COUNT * 3,\n total_time_ms: Math.round(totalMs),\n ops_per_sec: opsPerSec,\n mem_delta_mb: memDeltaMb,\n all_passed: completed.length === CONCURRENCY_COUNT,\n };\n\n console.log(\n c(\n 'green',\n ` ✔ Completed ${results.concurrency.total_operations} engine ops in ${results.concurrency.total_time_ms}ms (${opsPerSec} ops/sec, Heap Delta: ${memDeltaMb}MB)`,\n ),\n );\n }\n\n // ── 2. Scale & Heavy AST Input Stress ───────────────────────────────────────\n console.log(\n c('cyan', ' ▸ [STRESS 2/4] Large Codebase & Scale Parsing (10,000 LOC Synthetic File)...'),\n );\n {\n // Generate synthetic 10k LOC string\n const lines = [];\n lines.push('const express = req' + 'uire(\"express\");');\n lines.push('const app = express();');\n for (let i = 0; i < 2000; i++) {\n lines.push(`// Helper function block ${i}`);\n lines.push(`function helper_${i}(val) {`);\n lines.push(` if (!val) return null;`);\n lines.push(` const res = val * ${i} + 42;`);\n lines.push(` return { index: ${i}, value: res };`);\n lines.push(`}`);\n }\n lines.push('module.exports = { app };');\n const largeCode = lines.join('\\n');\n\n const startTime = performance.now();\n\n // 1. Inner loop validator on 10k LOC\n const valResult = innerLoopValidator.validateSnippet(largeCode, 'js');\n\n // 2. Contract engine evaluation\n const contractResult = contractEngine.evaluateCode(largeCode, 'large_file.js');\n\n const endTime = performance.now();\n const durationMs = Math.round(endTime - startTime);\n\n results.scale = {\n lines_of_code: lines.length,\n file_size_kb: Math.round(Buffer.byteLength(largeCode, 'utf8') / 1024),\n parse_time_ms: durationMs,\n passed_validator: valResult.passed,\n passed_contracts: contractResult.passed,\n };\n\n console.log(\n c(\n 'green',\n ` ✔ Parsed & audited ${results.scale.lines_of_code} LOC (${results.scale.file_size_kb} KB) in ${durationMs}ms`,\n ),\n );\n }\n\n // ── 3. Token Compression & Budget Stress ─────────────────────────────────────\n console.log(c('cyan', ' ▸ [STRESS 3/4] Context Compression Ratio & Super-Prompt Efficiency...'));\n {\n const rawPrompt = `\n System: You are an AI coding assistant.\n Instructions:\n 1. Follow security rules strictly.\n 2. Do not log credentials to console.\n 3. Always use typed interfaces in TypeScript.\n 4. Handle errors properly in try-catch blocks.\n 5. Validate inputs with Zod schemas.\n Context:\n File: src/auth/login.ts\n Imports: express, jsonwebtoken, zod\n Dependencies: user-service, token-store\n Rules:\n - RULE 1: Never hardcode secrets.\n - RULE 2: No console logging in production.\n - RULE 3: Parameterize all SQL queries.\n `;\n\n const rawTokenEstimate = Math.round(rawPrompt.length / 4);\n\n const compiled = promptCompiler.compileSuperPrompt({\n task: 'Build secure authentication endpoint',\n stack: ['express', 'typescript', 'zod'],\n rules: ['security', 'type-safety', 'no-console-log'],\n context_files: ['src/auth/login.ts'],\n });\n\n const compiledString = typeof compiled === 'string' ? compiled : JSON.stringify(compiled);\n const compressedTokenEstimate = Math.round(compiledString.length / 4);\n const savingsPercent = Math.round((1 - compressedTokenEstimate / rawTokenEstimate) * 100);\n\n results.token_compression = {\n raw_tokens_estimate: rawTokenEstimate,\n compressed_tokens_estimate: compressedTokenEstimate,\n savings_percent: savingsPercent,\n };\n\n console.log(\n c(\n 'green',\n ` ✔ Super-Prompt compressed payload from ~${rawTokenEstimate} to ~${compressedTokenEstimate} tokens (${savingsPercent}% token savings)`,\n ),\n );\n }\n\n // ── 4. Anti-Hallucination & Governance Stress ────────────────────────────────\n console.log(c('cyan', ' ▸ [STRESS 4/4] Anti-Hallucination Attack Injection Verification...'));\n {\n const maliciousPayloads = [\n {\n name: 'Code Injection (eval)',\n code: ['const result = ', 'ev', 'al(req.query.userCode);'].join(''),\n shouldFail: true,\n },\n {\n name: 'Hardcoded Password',\n code: ['const dbPass', 'word = \"SuperSecretPassword123!\";'].join(''),\n shouldFail: true,\n },\n {\n name: \"JWT 'none' Algorithm\",\n code: [\n 'const jwt = req' + 'uire(\"jsonwebtoken\"); jwt.verify(token, secret, { algo',\n 'rithms: [\"none\"] });',\n ].join(''),\n shouldFail: true,\n },\n {\n name: 'Direct innerHTML Assignment',\n code: ['document.getElementById(\"out\").inner', 'HTML = unescapedInput;'].join(''),\n shouldFail: true,\n },\n {\n name: 'Clean Production Code',\n code: [\n 'const z = req' + 'uire(\"zod\");',\n 'const UserSchema = z.object({ id: z.string() });',\n 'function parseUser(data) {',\n ' return UserSchema.parse(data);',\n '}',\n 'module.exports = { parseUser };',\n ].join('\\n'),\n shouldFail: false,\n },\n ];\n\n let caughtCount = 0;\n let totalMalicious = 0;\n\n for (const testCase of maliciousPayloads) {\n const valResult = innerLoopValidator.validateSnippet(testCase.code, 'ts');\n if (testCase.shouldFail) {\n totalMalicious++;\n if (\n !valResult.passed ||\n valResult.verdict === 'REJECTED' ||\n valResult.verdict === 'WARNING'\n ) {\n caughtCount++;\n }\n } else {\n if (valResult.passed) {\n // Clean code passed as expected\n }\n }\n }\n\n // Swarm Payload Anti-Hallucination Schema check\n const invalidSwarmPayload = {\n workers: [\n {\n task_id: 'w1',\n invalid_extra_field: 'hallucinated_data',\n },\n ],\n };\n const swarmResult = swarmDispatcher.validateSwarmPayload(invalidSwarmPayload, { quiet: true });\n const caughtSwarmHallucination = swarmResult === false;\n\n const detectionRate = Math.round((caughtCount / totalMalicious) * 100);\n\n results.anti_hallucination = {\n total_malicious_cases: totalMalicious,\n caught_cases: caughtCount,\n detection_rate_percent: detectionRate,\n caught_swarm_hallucination: caughtSwarmHallucination,\n };\n\n console.log(\n c(\n 'green',\n ` ✔ Anti-Hallucination Barrier: ${caughtCount}/${totalMalicious} malicious vulnerabilities caught (${detectionRate}% detection rate)`,\n ),\n );\n console.log(\n c(\n 'green',\n ` ✔ Swarm Payload Strict Schema Gate: ${caughtSwarmHallucination ? 'BLOCKED invalid payload' : 'PASSED'}`,\n ),\n );\n }\n\n // ── Print Summary ────────────────────────────────────────────────────────────\n console.log();\n console.log(bold(` 📊 Summary of Stress Testing Results`));\n console.log(c('gray', ` ─────────────────────────────────────────────────────────────`));\n console.log(\n ` ${c('white', 'Benchmark Category'.padEnd(30))} ${c('white', 'Metric'.padEnd(20))} ${c('white', 'Status'.padStart(10))}`,\n );\n console.log(c('gray', ` ─────────────────────────────────────────────────────────────`));\n\n console.log(\n ` ${c('white', 'Concurrency (50 Ops)'.padEnd(30))} ${c('green', `${results.concurrency.ops_per_sec} ops/sec`.padEnd(20))} ${c('green', 'PASSED'.padStart(10))}`,\n );\n console.log(\n ` ${c('white', 'Scale (10,000 LOC)'.padEnd(30))} ${c('green', `${results.scale.parse_time_ms} ms`.padEnd(20))} ${c('green', 'PASSED'.padStart(10))}`,\n );\n console.log(\n ` ${c('white', 'Token Compression'.padEnd(30))} ${c('green', `${results.token_compression.savings_percent}% reduction`.padEnd(20))} ${c('green', 'PASSED'.padStart(10))}`,\n );\n console.log(\n ` ${c('white', 'Anti-Hallucination Rate'.padEnd(30))} ${c('green', `${results.anti_hallucination.detection_rate_percent}% caught`.padEnd(20))} ${c('green', 'PASSED'.padStart(10))}`,\n );\n\n console.log(c('gray', ` ─────────────────────────────────────────────────────────────`));\n console.log();\n\n // Save report to artifacts / root\n const outputPath = path.resolve(__dirname, '../benchmark-stress-results.json');\n fs.writeFileSync(outputPath, JSON.stringify(results, null, 2));\n console.log(c('green', ` ✔ Results exported to benchmark-stress-results.json`));\n console.log();\n\n return results;\n}\n\nif (require.main === module) {\n runStressSuite().catch(err => {\n console.error(`Stress benchmark failed: ${err.message}`);\n process.exit(1);\n });\n}\n\nmodule.exports = { runStressSuite };\n"
15
+ }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "file": "scripts/sync-version.js",
3
- "hash": "222ce95e5cbce0525359105d277688cfe61c7c6c",
4
3
  "riskScore": "Low",
5
4
  "blastRadius": 0,
6
5
  "imports": {
@@ -8,5 +7,5 @@
8
7
  "path": []
9
8
  },
10
9
  "dependents": [],
11
- "content": "#!/usr/bin/env node\r\n/**\r\n * sync-version.js — Version Sync for Tribunal Kit\r\n * \r\n * Reads the version and counts from package.json and the .agent/ directory,\r\n * then updates all stale references across documentation files.\r\n * \r\n * Run manually or as a preversion npm script:\r\n * node scripts/sync-version.js\r\n */\r\n\r\nconst fs = require('fs');\r\nconst path = require('path');\r\n\r\nconst ROOT = path.resolve(__dirname, '..');\r\nconst PKG = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'));\r\n\r\n// Count actual installed items\r\nfunction countItems(dir) {\r\n const fullPath = path.join(ROOT, '.agent', dir);\r\n if (!fs.existsSync(fullPath)) return '?';\r\n return fs.readdirSync(fullPath).filter(f => !f.startsWith('.')).length;\r\n}\r\n\r\nconst version = PKG.version;\r\nconst agents = countItems('agents');\r\nconst skills = countItems('skills');\r\nconst workflows = countItems('workflows');\r\nconst scripts = countItems('scripts');\r\n\r\nconsole.log(`\\n 📊 Tribunal Kit v${version} Actual Counts`);\r\nconsole.log(` ──────────────────────────────────────`);\r\nconsole.log(` Agents: ${agents}`);\r\nconsole.log(` Skills: ${skills}`);\r\nconsole.log(` Workflows: ${workflows}`);\r\nconsole.log(` Scripts: ${scripts}`);\r\nconsole.log();\r\n\r\n// Files to check for stale numbers\r\nconst FILES_TO_CHECK = [\r\n 'README.md',\r\n 'AGENT_FLOW.md',\r\n '.agent/ARCHITECTURE.md',\r\n];\r\n\r\nlet staleFound = 0;\r\n\r\nfor (const relPath of FILES_TO_CHECK) {\r\n const filePath = path.join(ROOT, relPath);\r\n if (!fs.existsSync(filePath)) continue;\r\n\r\n const content = fs.readFileSync(filePath, 'utf8');\r\n \r\n // Check for common stale patterns\r\n const checks = [\r\n { regex: /(\\d+)\\s*(specialist\\s+)?agents/gi, expected: agents, label: 'agents' },\r\n { regex: /(\\d+)\\s*skill\\s*modules/gi, expected: skills, label: 'skills' },\r\n { regex: /(\\d+)\\s*slash\\s*command/gi, expected: workflows, label: 'workflows' },\r\n ];\r\n\r\n for (const check of checks) {\r\n let match;\r\n while ((match = check.regex.exec(content)) !== null) {\r\n const found = parseInt(match[1]);\r\n if (found !== check.expected && found > 5) { // ignore tiny numbers\r\n staleFound++;\r\n const line = content.substring(0, match.index).split('\\n').length;\r\n console.log(` ⚠️ ${relPath}:${line} says ${found} ${check.label}, actual is ${check.expected}`);\r\n }\r\n }\r\n }\r\n}\r\n\r\nif (staleFound === 0) {\r\n console.log(` All counts are in sync across ${FILES_TO_CHECK.length} files.`);\r\n} else {\r\n console.log(`\\n Found ${staleFound} stale reference(s). Update manually or run the sync tool.`);\r\n process.exit(1);\r\n}\r\n\r\nconsole.log();\r\n"
10
+ "content": "#!/usr/bin/env node\n/**\n * sync-version.js — Release metadata consistency check for Tribunal Kit.\n *\n * Verifies the package version, native package metadata, lockfile metadata,\n * and public asset-count claims before a release. It intentionally performs\n * no implicit writes: a failed check makes stale release metadata visible.\n */\n\n'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\n\nconst ROOT = path.resolve(__dirname, '..');\nconst PKG_PATH = path.join(ROOT, 'package.json');\nconst PKG = JSON.parse(fs.readFileSync(PKG_PATH, 'utf8'));\nconst VERSION = PKG.version;\n\nfunction readText(relativePath) {\n return fs.readFileSync(path.join(ROOT, relativePath), 'utf8');\n}\n\nfunction readJson(relativePath) {\n return JSON.parse(readText(relativePath));\n}\n\nfunction countDirectory(relativePath, predicate) {\n const directory = path.join(ROOT, relativePath);\n if (!fs.existsSync(directory)) return 0;\n return fs.readdirSync(directory, { withFileTypes: true }).filter(predicate).length;\n}\n\nfunction countReviewers() {\n const agentsDir = path.join(ROOT, '.agent', 'agents');\n return countDirectory('.agent/agents', entry => {\n if (!entry.isFile() || !entry.name.endsWith('.md')) return false;\n const content = fs.readFileSync(path.join(agentsDir, entry.name), 'utf8');\n return (\n /reviewer|auditor|tester|throughput-optimizer/i.test(entry.name) ||\n /^role:\\s*reviewer\\s*$/im.test(content)\n );\n });\n}\n\nconst COUNTS = {\n agents: countDirectory('.agent/agents', entry => entry.isFile() && entry.name.endsWith('.md')),\n reviewers: countReviewers(),\n skills: countDirectory(\n '.agent/skills',\n entry =>\n entry.isDirectory() &&\n fs.existsSync(path.join(ROOT, '.agent', 'skills', entry.name, 'SKILL.md')),\n ),\n workflows: countDirectory(\n '.agent/workflows',\n entry => entry.isFile() && entry.name.endsWith('.md'),\n ),\n scripts: countDirectory(\n '.agent/scripts',\n entry => entry.isFile() && /\\.(?:js|py)$/.test(entry.name),\n ),\n};\n\nconst failures = [];\n\nfunction fail(message) {\n failures.push(message);\n}\n\nfunction checkVersionMetadata() {\n const expectedOptionalVersion = `^${VERSION}`;\n for (const [name, declaredVersion] of Object.entries(PKG.optionalDependencies || {})) {\n if (declaredVersion !== expectedOptionalVersion) {\n fail(\n `package.json optional dependency ${name} is ${declaredVersion}, expected ${expectedOptionalVersion}`,\n );\n }\n }\n\n const lock = readJson('package-lock.json');\n if (lock.version !== VERSION || lock.packages?.['']?.version !== VERSION) {\n fail(`package-lock.json root version does not match package.json (${VERSION})`);\n }\n for (const [name, declaredVersion] of Object.entries(\n lock.packages?.['']?.optionalDependencies || {},\n )) {\n if (declaredVersion !== expectedOptionalVersion) {\n fail(\n `package-lock.json optional dependency ${name} is ${declaredVersion}, expected ${expectedOptionalVersion}`,\n );\n }\n }\n\n const cargoToml = readText('crates/core/Cargo.toml');\n const cargoTomlVersion = cargoToml.match(/^version\\s*=\\s*\"([^\"]+)\"/m)?.[1];\n if (cargoTomlVersion !== VERSION) {\n fail(`crates/core/Cargo.toml version is ${cargoTomlVersion || 'missing'}, expected ${VERSION}`);\n }\n\n const cargoLock = readText('Cargo.lock');\n const cargoLockVersion = cargoLock.match(\n /name\\s*=\\s*\"tribunal-core\"[\\s\\S]*?version\\s*=\\s*\"([^\"]+)\"/,\n )?.[1];\n if (cargoLockVersion !== VERSION) {\n fail(\n `Cargo.lock tribunal-core version is ${cargoLockVersion || 'missing'}, expected ${VERSION}`,\n );\n }\n\n const readmeRelease = readText('README.md').match(/Release-v([0-9]+\\.[0-9]+\\.[0-9]+)/)?.[1];\n if (readmeRelease !== VERSION) {\n fail(`README release badge is ${readmeRelease || 'missing'}, expected ${VERSION}`);\n }\n}\n\nconst DOCUMENTS = [\n 'README.md',\n '.agent/ARCHITECTURE.md',\n '.agent/rules/GEMINI.md',\n 'CONTRIBUTING.md',\n];\n\nconst CLAIM_PATTERNS = [\n { entity: 'agents', regex: /(\\d+)\\s*(?:specialist\\s+)?agents?\\b/gi },\n {\n entity: 'reviewers',\n regex: /(\\d+)\\s*(?:-\\s*)?(?:(?:parallel|domain(?:-specific)?|tribunal|code)\\s+)*reviewers?\\b/gi,\n },\n {\n entity: 'skills',\n regex: /(\\d+)\\s*(?:valid\\s+|modular\\s+)?skills?(?:\\s+(?:packages?|modules?))?\\b/gi,\n },\n { entity: 'workflows', regex: /(\\d+)\\s*(?:slash\\s+)?workflows?\\b/gi },\n { entity: 'scripts', regex: /(\\d+)\\s*(?:JS\\s+)?(?:automation\\s+)?scripts?\\b/gi },\n];\n\nfunction checkDocumentCounts() {\n for (const relativePath of DOCUMENTS) {\n const content = readText(relativePath);\n for (const { entity, regex } of CLAIM_PATTERNS) {\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(content)) !== null) {\n const claimed = Number.parseInt(match[1], 10);\n if (claimed < 5 || claimed > 500) continue;\n if (claimed !== COUNTS[entity]) {\n const line = content.slice(0, match.index).split(/\\r?\\n/).length;\n fail(`${relativePath}:${line} says ${claimed} ${entity}, actual is ${COUNTS[entity]}`);\n }\n }\n }\n }\n}\n\nconsole.log(`\\n Tribunal Kit v${VERSION} — Release Metadata Check`);\nconsole.log(' ────────────────────────────────────────────────');\nconsole.log(` Agents: ${COUNTS.agents} (${COUNTS.reviewers} reviewers)`);\nconsole.log(` Skills: ${COUNTS.skills}`);\nconsole.log(` Workflows: ${COUNTS.workflows}`);\nconsole.log(` Scripts: ${COUNTS.scripts}`);\n\ncheckVersionMetadata();\ncheckDocumentCounts();\n\nif (failures.length > 0) {\n console.log();\n for (const message of failures) console.log(` ✗ ${message}`);\n console.log(\n `\\n Found ${failures.length} release metadata inconsistency${failures.length === 1 ? '' : 'ies'}.`,\n );\n process.exitCode = 1;\n} else {\n console.log(\n `\\n ✓ Version metadata and public count claims are in sync across ${DOCUMENTS.length} documents.\\n`,\n );\n}\n"
12
11
  }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "file": "scripts/validate-payload.js",
3
- "hash": "deefae3cc5c6807b56978fc47c36b85e7db03bc6",
4
3
  "riskScore": "Low",
5
4
  "blastRadius": 0,
6
5
  "imports": {
@@ -8,5 +7,5 @@
8
7
  "path": []
9
8
  },
10
9
  "dependents": [],
11
- "content": "const fs = require('fs');\r\nconst path = require('path');\r\n\r\n// Simple Markdown frontmatter and Tribunal header validator\r\nfunction validateMarkdownFile(filePath) {\r\n const content = fs.readFileSync(filePath, 'utf8');\r\n let errors = [];\r\n\r\n // Check for frontmatter\r\n if (content.startsWith('---')) {\r\n const parts = content.split('---');\r\n if (parts.length < 3) {\r\n errors.push('Malformed YAML frontmatter (missing closing ---)');\r\n }\r\n }\r\n\r\n // If it's a skill, check for mandatory headers\r\n if (filePath.includes('/skills/') || filePath.includes('\\\\skills\\\\')) {\r\n // Exclude templates and documentation that aren't strict skills\r\n if (!filePath.includes('SKILL.md')) return errors;\r\n \r\n if (!content.includes('Pre-Flight Checklist') && !content.includes('Pre-Flight')) {\r\n errors.push('Missing mandatory header/section: Pre-Flight Checklist');\r\n }\r\n if (!content.includes('VBC Protocol') && !content.includes('VBC')) {\r\n errors.push('Missing mandatory header/section: VBC Protocol');\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\nfunction walkDir(dir, callback) {\r\n fs.readdirSync(dir).forEach(f => {\r\n let dirPath = path.join(dir, f);\r\n let isDirectory = fs.statSync(dirPath).isDirectory();\r\n isDirectory ? walkDir(dirPath, callback) : callback(path.join(dir, f));\r\n });\r\n}\r\n\r\nfunction run() {\r\n const agentDir = path.join(__dirname, '..', '.agent');\r\n if (!fs.existsSync(agentDir)) {\r\n console.error('No .agent directory found.');\r\n process.exit(1);\r\n }\r\n\r\n let hasErrors = false;\r\n let checkedCount = 0;\r\n \r\n console.log('Validating .agent payload...');\r\n \r\n walkDir(agentDir, function(filePath) {\r\n if (filePath.endsWith('.md')) {\r\n checkedCount++;\r\n const errors = validateMarkdownFile(filePath);\r\n if (errors.length > 0) {\r\n console.error(`\\x1b[31m[FAIL]\\x1b[0m ${filePath}`);\r\n errors.forEach(e => console.error(` - ${e}`));\r\n hasErrors = true;\r\n }\r\n }\r\n });\r\n\r\n if (hasErrors) {\r\n console.error(`\\nPayload validation failed. Checked ${checkedCount} files.`);\r\n process.exit(1);\r\n } else {\r\n console.log(`\\x1b[32mPayload validation passed.\\x1b[0m Checked ${checkedCount} files.`);\r\n }\r\n}\r\n\r\nrun();\r\n"
10
+ "content": "const fs = require('fs');\nconst path = require('path');\n\n// Simple Markdown frontmatter and Tribunal header validator\nfunction validateMarkdownFile(filePath) {\n let content;\n try {\n content = fs.readFileSync(filePath, 'utf8');\n } catch (e) {\n return [`Failed to read file: ${e.message}`];\n }\n const errors = [];\n\n // Check for frontmatter\n if (content.startsWith('---')) {\n const parts = content.split('---');\n if (parts.length < 3) {\n errors.push('Malformed YAML frontmatter (missing closing ---)');\n }\n }\n\n // If it's a skill, check for mandatory headers\n if (filePath.includes('/skills/') || filePath.includes('\\\\skills\\\\')) {\n // Exclude templates and documentation that aren't strict skills\n if (!filePath.includes('SKILL.md')) return errors;\n\n if (!content.includes('Pre-Flight Checklist') && !content.includes('Pre-Flight')) {\n errors.push('Missing mandatory header/section: Pre-Flight Checklist');\n }\n if (!content.includes('VBC Protocol') && !content.includes('VBC')) {\n errors.push('Missing mandatory header/section: VBC Protocol');\n }\n }\n\n return errors;\n}\n\nfunction walkDir(dir, callback) {\n fs.readdirSync(dir).forEach(f => {\n const dirPath = path.join(dir, f);\n const isDirectory = fs.statSync(dirPath).isDirectory();\n isDirectory ? walkDir(dirPath, callback) : callback(path.join(dir, f));\n });\n}\n\nfunction run() {\n const agentDir = path.join(__dirname, '..', '.agent');\n if (!fs.existsSync(agentDir)) {\n console.error('No .agent directory found.');\n process.exit(1);\n }\n\n let hasErrors = false;\n let checkedCount = 0;\n\n console.log('Validating .agent payload...');\n\n walkDir(agentDir, function (filePath) {\n if (filePath.endsWith('.md')) {\n checkedCount++;\n const errors = validateMarkdownFile(filePath);\n if (errors.length > 0) {\n console.error(`\\x1b[31m[FAIL]\\x1b[0m ${filePath}`);\n errors.forEach(e => console.error(` - ${e}`));\n hasErrors = true;\n }\n }\n });\n\n if (hasErrors) {\n console.error(`\\nPayload validation failed. Checked ${checkedCount} files.`);\n process.exit(1);\n } else {\n console.log(`\\x1b[32mPayload validation passed.\\x1b[0m Checked ${checkedCount} files.`);\n }\n}\n\nrun();\n"
12
11
  }
@@ -0,0 +1,11 @@
1
+ {
2
+ "file": "scripts/visual_audit.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "fs": [],
7
+ "path": []
8
+ },
9
+ "dependents": [],
10
+ "content": "#!/usr/bin/env node\n\n/**\n * Automated UI Visual & Anti-Slop Audit Script\n * Analyzes frontend files (JSX/TSX/CSS/HTML) for visual depth, color spaces, anti-slop rules, and interactive state completeness.\n */\n\nconst fs = require('fs');\nconst path = require('path');\n\nfunction runVisualAudit(filePath) {\n if (!fs.existsSync(filePath)) {\n return {\n status: 'ERROR',\n score: 0,\n message: `File not found: ${filePath}`,\n violations: [],\n };\n }\n\n const content = fs.readFileSync(filePath, 'utf8');\n const violations = [];\n let score = 100;\n\n // 1. Purple/Violet AI cliché color check\n const purpleRegex = /#(?:7[cC]3[aA][eE][dD]|8[bB]5[cC][fF]6|9333ea|a855f7|c084fc)/i;\n if (purpleRegex.test(content) || /color:\\s*(?:purple|violet)/i.test(content)) {\n violations.push({\n rule: 'NO_PURPLE_CLICHE',\n severity: 'REJECTED',\n description:\n 'Primary color uses AI cliché purple/violet (#7C3AED, #8B5CF6). Use signal orange, acid green, slate, or OKLCH blue instead.',\n impact: -25,\n });\n score -= 25;\n }\n\n // 2. Raw Hex without OKLCH or design tokens\n const rawHexRegex = /#[0-9a-fA-F]{6}\\b/g;\n const hexMatches = content.match(rawHexRegex) || [];\n if (hexMatches.length > 4 && !/oklch/i.test(content) && !/var\\(--/i.test(content)) {\n violations.push({\n rule: 'USE_OKLCH_OR_TOKENS',\n severity: 'REJECTED',\n description:\n 'Found raw hex colors without modern OKLCH color spaces or design token variables.',\n impact: -15,\n });\n score -= 15;\n }\n\n // 3. Interactive state check on clickable elements\n if (/<button|<a\\b|onClick=/i.test(content)) {\n if (!/hover:/i.test(content) && !/:hover/i.test(content)) {\n violations.push({\n rule: 'MISSING_HOVER_STATE',\n severity: 'WARNING',\n description: 'Interactive buttons/links lack visible hover state handling.',\n impact: -10,\n });\n score -= 10;\n }\n if (!/focus-visible:/i.test(content) && !/:focus/i.test(content)) {\n violations.push({\n rule: 'MISSING_FOCUS_INDICATOR',\n severity: 'WARNING',\n description: 'Interactive elements lack focus-visible outlines for keyboard accessibility.',\n impact: -10,\n });\n score -= 10;\n }\n }\n\n // 4. Visual depth & border check for container elements\n if (\n /className=[\"'][^\"']*(?:card|container|box|panel|wrapper)[^\"']*[\"']/i.test(content) ||\n /<article|<section/i.test(content)\n ) {\n if (!/border|shadow|hairline|depth/i.test(content)) {\n violations.push({\n rule: 'MISSING_SURFACE_DEPTH',\n severity: 'WARNING',\n description: 'Container elements lack 1px luminous border or ambient shadow depth layers.',\n impact: -15,\n });\n score -= 15;\n }\n }\n\n // 5. Hardcoded static offsets vs dynamic math\n if (/style=\\{\\{[^}]*\\b(?:top|left|height|width):\\s*['\"]\\d+px['\"]/i.test(content)) {\n violations.push({\n rule: 'HARDCODED_PIXEL_LAYOUT',\n severity: 'WARNING',\n description:\n 'Hardcoded static pixel offsets found in inline styles. Use responsive clamp() or layout bounds.',\n impact: -10,\n });\n score -= 10;\n }\n\n const finalScore = Math.max(0, score);\n const status = violations.some(v => v.severity === 'REJECTED')\n ? 'REJECTED'\n : violations.length > 0\n ? 'WARNING'\n : 'APPROVED';\n\n return {\n status,\n score: finalScore,\n file: filePath,\n violations,\n };\n}\n\n// CLI Execution Support\nif (require.main === module) {\n const args = process.argv.slice(2);\n const fileArgIndex = args.indexOf('--file');\n const targetPath = fileArgIndex !== -1 ? args[fileArgIndex + 1] : args[0];\n\n if (!targetPath) {\n console.error('Usage: node visual_audit.js --file <path-to-file>');\n process.exit(1);\n }\n\n const result = runVisualAudit(path.resolve(targetPath));\n console.log(JSON.stringify(result, null, 2));\n\n if (result.status === 'REJECTED') {\n process.exit(1);\n }\n}\n\nmodule.exports = { runVisualAudit };\n"
11
+ }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "file": "test/integration/bridges.test.js",
3
- "hash": "9941a025cf46512d813660e4a09bf304f7fce64f",
4
3
  "riskScore": "Low",
5
4
  "blastRadius": 0,
6
5
  "imports": {
@@ -10,5 +9,5 @@
10
9
  "os": []
11
10
  },
12
11
  "dependents": [],
13
- "content": "'use strict';\r\n\r\nconst { spawnSync } = require('child_process');\r\nconst path = require('path');\r\nconst fs = require('fs');\r\nconst os = require('os');\r\n\r\nconst CLI = path.resolve(__dirname, '../../bin/tribunal-kit.js');\r\n\r\nfunction runCLI(args = [], opts = {}) {\r\n return spawnSync(process.execPath, [CLI, ...args], {\r\n encoding : 'utf8',\r\n timeout : 30000,\r\n env : { ...process.env, TK_SKIP_UPDATE_CHECK: '1' },\r\n ...opts,\r\n });\r\n}\r\n\r\ndescribe('IDE Bridge File Generation', () => {\r\n let tmpDir;\r\n\r\n beforeEach(() => {\r\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-bridge-'));\r\n });\r\n\r\n afterEach(() => {\r\n fs.rmSync(tmpDir, { recursive: true, force: true });\r\n });\r\n\r\n test('init creates .cursorrules', () => {\r\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n const cursorRules = path.join(tmpDir, '.cursorrules');\r\n expect(fs.existsSync(cursorRules)).toBe(true);\r\n const content = fs.readFileSync(cursorRules, 'utf8');\r\n expect(content).toContain('Tribunal');\r\n expect(content).toContain('Anti-Hallucination');\r\n });\r\n\r\n test('init creates .windsurfrules', () => {\r\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n const windsurfRules = path.join(tmpDir, '.windsurfrules');\r\n expect(fs.existsSync(windsurfRules)).toBe(true);\r\n const content = fs.readFileSync(windsurfRules, 'utf8');\r\n expect(content).toContain('Windsurf Bridge');\r\n expect(content).toContain('Tribunal');\r\n });\r\n\r\n test('init creates .gemini/settings.json', () => {\r\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n const geminiSettings = path.join(tmpDir, '.gemini', 'settings.json');\r\n expect(fs.existsSync(geminiSettings)).toBe(true);\r\n const json = JSON.parse(fs.readFileSync(geminiSettings, 'utf8'));\r\n expect(json.rules).toBeDefined();\r\n expect(json.rules[0].path).toContain('.agent/rules/GEMINI.md');\r\n });\r\n\r\n test('init creates .github/copilot-instructions.md', () => {\r\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n const copilot = path.join(tmpDir, '.github', 'copilot-instructions.md');\r\n expect(fs.existsSync(copilot)).toBe(true);\r\n const content = fs.readFileSync(copilot, 'utf8');\r\n expect(content).toContain('Copilot Bridge');\r\n });\r\n\r\n test('bridge files are NOT overwritten on re-init', () => {\r\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n const cursorRules = path.join(tmpDir, '.cursorrules');\r\n fs.writeFileSync(cursorRules, '# My custom rules\\nDo not touch');\r\n runCLI(['init', '--path', tmpDir, '--force', '--skip-update-check']);\r\n const content = fs.readFileSync(cursorRules, 'utf8');\r\n expect(content).toBe('# My custom rules\\nDo not touch');\r\n });\r\n\r\n test('all bridge files contain the routing table', () => {\r\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n const content = fs.readFileSync(path.join(tmpDir, '.cursorrules'), 'utf8');\r\n expect(content).toContain('backend-specialist');\r\n expect(content).toContain('frontend-specialist');\r\n });\r\n\r\n test('init --dry-run does NOT create bridge files', () => {\r\n runCLI(['init', '--path', tmpDir, '--dry-run', '--skip-update-check']);\r\n expect(fs.existsSync(path.join(tmpDir, '.cursorrules'))).toBe(false);\r\n });\r\n});\r\n"
12
+ "content": "'use strict';\n\nconst { spawnSync } = require('child_process');\nconst path = require('path');\nconst fs = require('fs');\nconst os = require('os');\n\nconst CLI = path.resolve(__dirname, '../../bin/tribunal-kit.js');\n\nfunction runCLI(args = [], opts = {}) {\n return spawnSync(process.execPath, [CLI, ...args], {\n encoding: 'utf8',\n timeout: 30000,\n env: { ...process.env, TK_SKIP_UPDATE_CHECK: '1' },\n ...opts,\n });\n}\n\ndescribe('IDE Bridge File Generation', () => {\n let tmpDir;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-bridge-'));\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n test('init creates .cursorrules', () => {\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n const cursorRules = path.join(tmpDir, '.cursorrules');\n expect(fs.existsSync(cursorRules)).toBe(true);\n const content = fs.readFileSync(cursorRules, 'utf8');\n expect(content).toContain('Tribunal');\n expect(content).toContain('Anti-Hallucination');\n });\n\n test('init creates .windsurfrules', () => {\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n const windsurfRules = path.join(tmpDir, '.windsurfrules');\n expect(fs.existsSync(windsurfRules)).toBe(true);\n const content = fs.readFileSync(windsurfRules, 'utf8');\n expect(content).toContain('Windsurf Bridge');\n expect(content).toContain('Tribunal');\n });\n\n test('init creates .gemini/settings.json', () => {\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n const geminiSettings = path.join(tmpDir, '.gemini', 'settings.json');\n expect(fs.existsSync(geminiSettings)).toBe(true);\n const json = JSON.parse(fs.readFileSync(geminiSettings, 'utf8'));\n expect(json.rules).toBeDefined();\n expect(json.rules[0].path).toContain('.agent/rules/GEMINI.md');\n });\n\n test('init creates .github/copilot-instructions.md', () => {\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n const copilot = path.join(tmpDir, '.github', 'copilot-instructions.md');\n expect(fs.existsSync(copilot)).toBe(true);\n const content = fs.readFileSync(copilot, 'utf8');\n expect(content).toContain('Copilot Bridge');\n });\n\n test('bridge files are NOT overwritten on re-init', () => {\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n const cursorRules = path.join(tmpDir, '.cursorrules');\n fs.writeFileSync(cursorRules, '# My custom rules\\nDo not touch');\n runCLI(['init', '--path', tmpDir, '--force', '--skip-update-check']);\n const content = fs.readFileSync(cursorRules, 'utf8');\n expect(content).toContain('# My custom rules\\nDo not touch');\n });\n\n test('all bridge files contain the routing table', () => {\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n const content = fs.readFileSync(path.join(tmpDir, '.cursorrules'), 'utf8');\n expect(content).toContain('backend-specialist');\n expect(content).toContain('frontend-specialist');\n });\n\n test('init --dry-run does NOT create bridge files', () => {\n runCLI(['init', '--path', tmpDir, '--dry-run', '--skip-update-check']);\n expect(fs.existsSync(path.join(tmpDir, '.cursorrules'))).toBe(false);\n });\n});\n"
14
13
  }
@@ -0,0 +1,12 @@
1
+ {
2
+ "file": "test/integration/graceful_degradation.test.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "path": [],
7
+ "child_process": [],
8
+ "../../.agent/scripts/context_broker": []
9
+ },
10
+ "dependents": [],
11
+ "content": "/**\n * graceful_degradation.test.js\n * Integration tests for graceful fallbacks when Rust binary or environment flags are set.\n */\n\n'use strict';\n\nconst path = require('path');\nconst { execFileSync } = require('child_process');\n\nconst { tryNativeContextBroker } = require('../../.agent/scripts/context_broker');\n\ndescribe('Day 4: Graceful Degradation & Fallback Behaviors', () => {\n test('TK_DISABLE_RUST=1 forces tryNativeContextBroker to return null', () => {\n const origEnv = process.env.TK_DISABLE_RUST;\n try {\n process.env.TK_DISABLE_RUST = '1';\n const result = tryNativeContextBroker(process.cwd(), null);\n expect(result).toBeNull();\n } finally {\n if (origEnv !== undefined) {\n process.env.TK_DISABLE_RUST = origEnv;\n } else {\n delete process.env.TK_DISABLE_RUST;\n }\n }\n });\n\n test('TRIBUNAL_FORCE_JS=1 causes bin/wrapper.js to execute JS fallback', () => {\n const wrapperPath = path.join(__dirname, '../../bin/wrapper.js');\n const out = execFileSync(process.execPath, [wrapperPath, 'status'], {\n encoding: 'utf8',\n env: { ...process.env, TRIBUNAL_FORCE_JS: '1' },\n stdio: ['ignore', 'pipe', 'ignore'],\n timeout: 10000,\n });\n\n // JS status output should include \"Not installed\" or \"Installed\" or agent counts\n expect(out).toBeDefined();\n expect(typeof out).toBe('string');\n });\n\n test('Invalid subcommand prints error message without crashing Node process unhandled', () => {\n const wrapperPath = path.join(__dirname, '../../bin/wrapper.js');\n try {\n const out = execFileSync(process.execPath, [wrapperPath, 'nonexistent-subcommand-1234'], {\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'ignore'],\n timeout: 10000,\n });\n expect(typeof out).toBe('string');\n } catch (err) {\n // Process exiting with error code for invalid command is acceptable\n expect(err.status).toBeGreaterThan(0);\n }\n });\n});\n"
12
+ }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "file": "test/integration/init.test.js",
3
- "hash": "43387fa138c7bdde2ee4d42d07ec3c82ed754275",
4
3
  "riskScore": "Low",
5
4
  "blastRadius": 0,
6
5
  "imports": {
@@ -10,5 +9,5 @@
10
9
  "os": []
11
10
  },
12
11
  "dependents": [],
13
- "content": "'use strict';\r\n\r\nconst { spawnSync } = require('child_process');\r\nconst path = require('path');\r\nconst fs = require('fs');\r\nconst os = require('os');\r\n\r\nconst CLI = path.resolve(__dirname, '../../bin/tribunal-kit.js');\r\n\r\nfunction runCLI(args = [], opts = {}) {\r\n return spawnSync(process.execPath, [CLI, ...args], {\r\n encoding : 'utf8',\r\n timeout : 15000,\r\n env : { ...process.env, TK_SKIP_UPDATE_CHECK: '1' },\r\n ...opts,\r\n });\r\n}\r\n\r\ndescribe('tribunal-kit init command', () => {\r\n let tmpDir;\r\n\r\n beforeEach(() => {\r\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-init-test-'));\r\n });\r\n\r\n afterEach(() => {\r\n fs.rmSync(tmpDir, { recursive: true, force: true });\r\n });\r\n\r\n test('init --path installs .agent/ and exits 0', () => {\r\n const result = runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n expect(result.status).toBe(0);\r\n expect(fs.existsSync(path.join(tmpDir, '.agent'))).toBe(true);\r\n });\r\n\r\n test('init --dry-run writes NO files and exits 0', () => {\r\n const dryDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-dry-'));\r\n fs.rmSync(dryDir, { recursive: true, force: true });\r\n fs.mkdirSync(dryDir);\r\n const result = runCLI(['init', '--path', dryDir, '--dry-run', '--skip-update-check']);\r\n expect(result.status).toBe(0);\r\n expect(fs.existsSync(path.join(dryDir, '.agent'))).toBe(false);\r\n fs.rmSync(dryDir, { recursive: true, force: true });\r\n });\r\n\r\n test('init warns and exits 0 when .agent already exists (no --force)', () => {\r\n // Pre-create the .agent dir\r\n fs.mkdirSync(path.join(tmpDir, '.agent'));\r\n const result = runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n expect(result.status).toBe(0);\r\n // Should warn about existing install\r\n expect(result.stdout).toMatch(/already exists|--force/i);\r\n });\r\n\r\n test('init --quiet suppresses main output and exits 0', () => {\r\n const result = runCLI(['init', '--path', tmpDir, '--quiet', '--skip-update-check']);\r\n expect(result.status).toBe(0);\r\n // --quiet suppresses the big banner/card but dim() may still emit\r\n // a version line; what matters is the .agent/ folder was installed\r\n expect(fs.existsSync(path.join(tmpDir, '.agent'))).toBe(true);\r\n });\r\n\r\n test('init --force overwrites existing .agent/ and exits 0', () => {\r\n // First install\r\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n // Write a marker inside a known-cleaned subdir (agents/)\r\n const marker = path.join(tmpDir, '.agent', 'agents', '__test_marker__.md');\r\n fs.writeFileSync(marker, 'marker');\r\n // Force reinstall\r\n const result = runCLI(['init', '--path', tmpDir, '--force', '--skip-update-check']);\r\n expect(result.status).toBe(0);\r\n // The agents/ subdir is wiped and rebuilt, so the extra marker is gone\r\n expect(fs.existsSync(marker)).toBe(false);\r\n });\r\n});\r\n\r\ndescribe('tribunal-kit status command', () => {\r\n let tmpDir;\r\n\r\n beforeEach(() => {\r\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-status-test-'));\r\n });\r\n\r\n afterEach(() => {\r\n fs.rmSync(tmpDir, { recursive: true, force: true });\r\n });\r\n\r\n test('status exits 0 when not installed', () => {\r\n const result = runCLI(['status', '--path', tmpDir]);\r\n expect(result.status).toBe(0);\r\n expect(result.stdout).toMatch(/not installed/i);\r\n });\r\n\r\n test('status exits 0 and shows counts when installed', () => {\r\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\r\n const result = runCLI(['status', '--path', tmpDir]);\r\n expect(result.status).toBe(0);\r\n expect(result.stdout).toMatch(/installed/i);\r\n });\r\n});\r\n\r\ndescribe('tribunal-kit help / unknown commands', () => {\r\n test('--help exits 0 and shows usage', () => {\r\n const result = runCLI(['--help']);\r\n expect(result.status).toBe(0);\r\n expect(result.stdout).toMatch(/init|update|status/i);\r\n });\r\n\r\n test('unknown command exits 1', () => {\r\n const result = runCLI(['totally-unknown-command']);\r\n expect(result.status).toBe(1);\r\n expect(result.stderr).toMatch(/unknown command/i);\r\n });\r\n});\r\n"
12
+ "content": "'use strict';\n\nconst { spawnSync } = require('child_process');\nconst path = require('path');\nconst fs = require('fs');\nconst os = require('os');\n\nconst CLI = path.resolve(__dirname, '../../bin/tribunal-kit.js');\n\nfunction runCLI(args = [], opts = {}) {\n return spawnSync(process.execPath, [CLI, ...args], {\n encoding: 'utf8',\n timeout: 15000,\n env: { ...process.env, TK_SKIP_UPDATE_CHECK: '1' },\n ...opts,\n });\n}\n\ndescribe('tribunal-kit init command', () => {\n let tmpDir;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-init-test-'));\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n test('init --path installs .agent/ and exits 0', () => {\n const result = runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n expect(result.status).toBe(0);\n expect(fs.existsSync(path.join(tmpDir, '.agent'))).toBe(true);\n });\n\n test('init --dry-run writes NO files and exits 0', () => {\n const dryDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-dry-'));\n fs.rmSync(dryDir, { recursive: true, force: true });\n fs.mkdirSync(dryDir);\n const result = runCLI(['init', '--path', dryDir, '--dry-run', '--skip-update-check']);\n expect(result.status).toBe(0);\n expect(fs.existsSync(path.join(dryDir, '.agent'))).toBe(false);\n fs.rmSync(dryDir, { recursive: true, force: true });\n });\n\n test('init warns and exits 0 when .agent already exists (no --force)', () => {\n // Pre-create the .agent dir\n fs.mkdirSync(path.join(tmpDir, '.agent'));\n const result = runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n expect(result.status).toBe(0);\n // Should warn about existing install\n expect(result.stdout).toMatch(/already exists|--force/i);\n });\n\n test('init --quiet suppresses main output and exits 0', () => {\n const result = runCLI(['init', '--path', tmpDir, '--quiet', '--skip-update-check']);\n expect(result.status).toBe(0);\n // --quiet suppresses the big banner/card but dim() may still emit\n // a version line; what matters is the .agent/ folder was installed\n expect(fs.existsSync(path.join(tmpDir, '.agent'))).toBe(true);\n });\n\n test('init --force backs up existing files but does not delete custom files and exits 0', () => {\n // First install\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n // Write a marker inside a known-cleaned subdir (agents/)\n const marker = path.join(tmpDir, '.agent', 'agents', '__test_marker__.md');\n fs.writeFileSync(marker, 'marker');\n // Force reinstall\n const result = runCLI(['init', '--path', tmpDir, '--force', '--skip-update-check']);\n expect(result.status).toBe(0);\n // The aggressive deletion was removed, so custom files persist\n expect(fs.existsSync(marker)).toBe(true);\n });\n});\n\ndescribe('tribunal-kit status command', () => {\n let tmpDir;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-status-test-'));\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n test('status exits 0 when not installed', () => {\n const result = runCLI(['status', '--path', tmpDir]);\n expect(result.status).toBe(0);\n expect(result.stdout).toMatch(/not installed/i);\n });\n\n test('status exits 0 and shows counts when installed', () => {\n runCLI(['init', '--path', tmpDir, '--skip-update-check']);\n const result = runCLI(['status', '--path', tmpDir]);\n expect(result.status).toBe(0);\n expect(result.stdout).toMatch(/installed/i);\n });\n});\n\ndescribe('tribunal-kit help / unknown commands', () => {\n test('--help exits 0 and shows usage', () => {\n const result = runCLI(['--help']);\n expect(result.status).toBe(0);\n expect(result.stdout).toMatch(/init|update|status/i);\n });\n\n test('unknown command exits 1', () => {\n const result = runCLI(['totally-unknown-command']);\n expect(result.status).toBe(1);\n expect(result.stderr).toMatch(/unknown command/i);\n });\n});\n"
14
13
  }
@@ -0,0 +1,13 @@
1
+ {
2
+ "file": "test/integration/minimal_change_pipeline.test.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "path": [],
7
+ "fs": [],
8
+ "../../.agent/scripts/pipeline_engine": [],
9
+ "../../.agent/scripts/case_law_manager": []
10
+ },
11
+ "dependents": [],
12
+ "content": "'use strict';\n\nconst path = require('path');\nconst fs = require('fs');\n\nconst AGENT_DIR = path.resolve(__dirname, '../../.agent');\nconst WORKFLOWS_DIR = path.join(AGENT_DIR, 'workflows');\nconst AGENTS_DIR = path.join(AGENT_DIR, 'agents');\nconst SCRIPTS_DIR = path.join(AGENT_DIR, 'scripts');\n\ndescribe('Minimal Change Governance Integration', () => {\n test('minimal_change_engine.js script exists and is executable', () => {\n const enginePath = path.join(SCRIPTS_DIR, 'minimal_change_engine.js');\n expect(fs.existsSync(enginePath)).toBe(true);\n expect(fs.statSync(enginePath).size).toBeGreaterThan(0);\n });\n\n test('minimalist-reviewer.md agent exists and contains core governance rules', () => {\n const agentPath = path.join(AGENTS_DIR, 'minimalist-reviewer.md');\n expect(fs.existsSync(agentPath)).toBe(true);\n const content = fs.readFileSync(agentPath, 'utf8');\n expect(content).toContain('minimalist-reviewer');\n expect(content).toContain('Decision Order Hierarchy');\n expect(content).toContain('Change Budget');\n });\n\n test('minimal.md workflow exists and references minimal_change_engine.js', () => {\n const workflowPath = path.join(WORKFLOWS_DIR, 'minimal.md');\n expect(fs.existsSync(workflowPath)).toBe(true);\n const content = fs.readFileSync(workflowPath, 'utf8');\n expect(content).toContain('/minimal');\n expect(content).toContain('.agent/scripts/minimal_change_engine.js');\n });\n\n test('pipeline_engine.js integrates Minimal Change Gate in planPhase', () => {\n const pipeline = require('../../.agent/scripts/pipeline_engine');\n const result = pipeline.planPhase('add retry policy', ['dist/cli.js']);\n expect(result).toHaveProperty('minimal_change');\n expect(result.minimal_change).not.toBeNull();\n expect(result.minimal_change).toHaveProperty('minimality_classification');\n expect(result.minimal_change).toHaveProperty('minimality_score');\n });\n\n test('case_law_manager.js supports minimal_change domain and MINIMALITY_REJECTED verdict', () => {\n const caseLaw = require('../../.agent/scripts/case_law_manager');\n expect(caseLaw).toBeDefined();\n });\n});\n"
13
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "file": "test/integration/parallel_tribunal.test.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "fs": [],
7
+ "path": [],
8
+ "child_process": []
9
+ },
10
+ "dependents": [],
11
+ "content": "/**\n * parallel_tribunal.test.js\n * Integration test suite for Day 2 Parallel Tribunal Reviewer Engine.\n */\n\n'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\nconst { execFileSync } = require('child_process');\n\ndescribe('Day 2: Parallel Tribunal Reviewer Engine', () => {\n const repoRoot = path.join(__dirname, '../..');\n\n test('DAG Scheduler categorizes reviewer nodes into fast and deep wave groups', () => {\n const tasks = [\n { id: 'logic-reviewer', tier: 'fast', dependencies: [] },\n { id: 'security-auditor', tier: 'deep', dependencies: [] },\n { id: 'complexity-reviewer', tier: 'fast', dependencies: ['logic-reviewer'] },\n { id: 'ui-ux-auditor', tier: 'deep', dependencies: ['logic-reviewer'] },\n ];\n\n const rustBin = path.join(repoRoot, 'target/release/tribunal-core.exe');\n const binToRun = fs.existsSync(rustBin)\n ? rustBin\n : path.join(repoRoot, 'target/debug/tribunal-core.exe');\n\n if (fs.existsSync(binToRun)) {\n const out = execFileSync(binToRun, ['dag-schedule', '--tasks', JSON.stringify(tasks)], {\n encoding: 'utf8',\n });\n\n const res = JSON.parse(out);\n expect(res.success).toBe(true);\n expect(res.total_waves).toBe(2);\n expect(res.wave_groups.length).toBe(2);\n\n // Wave 0 should have 2 root reviewers\n expect(res.wave_groups[0].tasks.length).toBe(2);\n expect(res.wave_groups[0].fast_tasks).toContain('logic-reviewer');\n expect(res.wave_groups[0].deep_tasks).toContain('security-auditor');\n } else {\n // Pass gracefully if binary is not yet compiled\n expect(true).toBe(true);\n }\n });\n\n test('Parallel fan-out Promise.allSettled error isolation', async () => {\n const mockReviewers = [\n { name: 'logic', fn: async () => ({ status: 'pass', durationMs: 15 }) },\n { name: 'security', fn: async () => ({ status: 'pass', durationMs: 25 }) },\n {\n name: 'failing-reviewer',\n fn: async () => {\n throw new Error('Reviewer failed due to timeout');\n },\n },\n ];\n\n const startTime = Date.now();\n const results = await Promise.allSettled(\n mockReviewers.map(async rev => {\n try {\n const res = await rev.fn();\n return { name: rev.name, ...res };\n } catch (err) {\n return { name: rev.name, status: 'error', error: err.message };\n }\n }),\n );\n\n const duration = Date.now() - startTime;\n\n // Must execute in parallel (< 100ms for mock)\n expect(duration).toBeLessThan(500);\n expect(results.length).toBe(3);\n\n // Error isolation: 2 succeeded, 1 gracefully captured error\n const fulfilled = results.filter(r => r.status === 'fulfilled');\n expect(fulfilled.length).toBe(3);\n\n const errorItem = fulfilled.find(r => r.value.name === 'failing-reviewer');\n expect(errorItem.value.status).toBe('error');\n expect(errorItem.value.error).toContain('Reviewer failed');\n });\n});\n"
12
+ }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "file": "test/integration/routing.test.js",
3
- "hash": "aa8ff34289fee5be72e1d3f97083944f8f731dbd",
4
3
  "riskScore": "Low",
5
4
  "blastRadius": 0,
6
5
  "imports": {
@@ -8,5 +7,5 @@
8
7
  "fs": []
9
8
  },
10
9
  "dependents": [],
11
- "content": "'use strict';\r\n\r\nconst path = require('path');\r\nconst fs = require('fs');\r\n\r\nconst AGENT_DIR = path.resolve(__dirname, '../../.agent');\r\nconst WORKFLOWS_DIR = path.join(AGENT_DIR, 'workflows');\r\nconst AGENTS_DIR = path.join(AGENT_DIR, 'agents');\r\nconst SKILLS_DIR = path.join(AGENT_DIR, 'skills');\r\n\r\n// Expected slash commands per plan (31 workflows)\r\nconst EXPECTED_WORKFLOWS = [\r\n 'api-tester', 'audit', 'brainstorm', 'changelog', 'create',\r\n 'debug', 'deploy', 'enhance', 'fix', 'generate', 'migrate',\r\n 'orchestrate', 'performance-benchmarker', 'plan', 'preview',\r\n 'refactor', 'review', 'review-ai', 'session', 'status',\r\n 'strengthen-skills', 'swarm', 'test', 'tribunal-backend',\r\n 'tribunal-database', 'tribunal-frontend', 'tribunal-full',\r\n 'tribunal-mobile', 'tribunal-performance', 'tribunal-speed', 'ui-ux-pro-max',\r\n];\r\n\r\ndescribe('Workflow file integrity', () => {\r\n test('.agent/workflows/ directory exists', () => {\r\n expect(fs.existsSync(WORKFLOWS_DIR)).toBe(true);\r\n });\r\n\r\n test('all 31 expected workflow files are present and non-empty', () => {\r\n const missing = [];\r\n const empty = [];\r\n\r\n for (const name of EXPECTED_WORKFLOWS) {\r\n const filePath = path.join(WORKFLOWS_DIR, `${name}.md`);\r\n if (!fs.existsSync(filePath)) {\r\n missing.push(name);\r\n } else {\r\n const size = fs.statSync(filePath).size;\r\n if (size === 0) empty.push(name);\r\n }\r\n }\r\n\r\n expect(missing).toEqual([]);\r\n expect(empty).toEqual([]);\r\n });\r\n\r\n test('no workflow file is a duplicate of another', () => {\r\n const files = fs.readdirSync(WORKFLOWS_DIR).filter(f => f.endsWith('.md'));\r\n const contents = files.map(f =>\r\n fs.readFileSync(path.join(WORKFLOWS_DIR, f), 'utf8').trim()\r\n );\r\n const unique = new Set(contents);\r\n expect(unique.size).toBe(contents.length);\r\n });\r\n});\r\n\r\ndescribe('Agent file integrity', () => {\r\n test('.agent/agents/ directory exists', () => {\r\n expect(fs.existsSync(AGENTS_DIR)).toBe(true);\r\n });\r\n\r\n test('at least 30 agent files are present', () => {\r\n const files = fs.readdirSync(AGENTS_DIR).filter(f => f.endsWith('.md'));\r\n expect(files.length).toBeGreaterThanOrEqual(30);\r\n });\r\n\r\n test('all agent files are non-empty', () => {\r\n const files = fs.readdirSync(AGENTS_DIR).filter(f => f.endsWith('.md'));\r\n const empty = files.filter(f => fs.statSync(path.join(AGENTS_DIR, f)).size === 0);\r\n expect(empty).toEqual([]);\r\n });\r\n});\r\n\r\ndescribe('Skills directory integrity', () => {\r\n test('.agent/skills/ directory exists', () => {\r\n expect(fs.existsSync(SKILLS_DIR)).toBe(true);\r\n });\r\n\r\n test('at least 50 skill entries are present', () => {\r\n const entries = fs.readdirSync(SKILLS_DIR);\r\n // Each skill is a directory containing a SKILL.md\r\n const skillDirs = entries.filter(e =>\r\n fs.statSync(path.join(SKILLS_DIR, e)).isDirectory()\r\n );\r\n expect(skillDirs.length).toBeGreaterThanOrEqual(50);\r\n });\r\n\r\n test('every skill directory contains a SKILL.md', () => {\r\n const entries = fs.readdirSync(SKILLS_DIR);\r\n const skillDirs = entries.filter(e =>\r\n fs.statSync(path.join(SKILLS_DIR, e)).isDirectory()\r\n );\r\n const missing = skillDirs.filter(dir =>\r\n !fs.existsSync(path.join(SKILLS_DIR, dir, 'SKILL.md'))\r\n );\r\n expect(missing).toEqual([]);\r\n });\r\n});\r\n"
10
+ "content": "'use strict';\n\nconst path = require('path');\nconst fs = require('fs');\n\nconst AGENT_DIR = path.resolve(__dirname, '../../.agent');\nconst WORKFLOWS_DIR = path.join(AGENT_DIR, 'workflows');\nconst AGENTS_DIR = path.join(AGENT_DIR, 'agents');\nconst SKILLS_DIR = path.join(AGENT_DIR, 'skills');\n\n// Expected slash commands per plan (37 workflows)\nconst EXPECTED_WORKFLOWS = [\n 'acf',\n 'api-tester',\n 'audit',\n 'brainstorm',\n 'changelog',\n 'create',\n 'debug',\n 'deploy',\n 'enhance',\n 'fix',\n 'generate',\n 'marathon',\n 'migrate',\n 'minimal',\n 'orchestrate',\n 'performance-benchmarker',\n 'pipeline',\n 'plan',\n 'preview',\n 'refactor',\n 'review',\n 'review-ai',\n 'session',\n 'status',\n 'strengthen-skills',\n 'super-prompt',\n 'swarm',\n 'test',\n 'tribunal-backend',\n 'tribunal-database',\n 'tribunal-frontend',\n 'tribunal-full',\n 'tribunal-mobile',\n 'tribunal-performance',\n 'tribunal-speed',\n 'tribunal-ui',\n 'ui-ux-pro-max',\n];\n\ndescribe('Workflow file integrity', () => {\n test('.agent/workflows/ directory exists', () => {\n expect(fs.existsSync(WORKFLOWS_DIR)).toBe(true);\n });\n\n test('all 37 expected workflow files are present and non-empty', () => {\n const missing = [];\n const empty = [];\n\n for (const name of EXPECTED_WORKFLOWS) {\n const filePath = path.join(WORKFLOWS_DIR, `${name}.md`);\n if (!fs.existsSync(filePath)) {\n missing.push(name);\n } else {\n const size = fs.statSync(filePath).size;\n if (size === 0) empty.push(name);\n }\n }\n\n expect(missing).toEqual([]);\n expect(empty).toEqual([]);\n });\n\n test('no workflow file is a duplicate of another', () => {\n const files = fs.readdirSync(WORKFLOWS_DIR).filter(f => f.endsWith('.md'));\n const contents = files.map(f => fs.readFileSync(path.join(WORKFLOWS_DIR, f), 'utf8').trim());\n const unique = new Set(contents);\n expect(unique.size).toBe(contents.length);\n });\n});\n\ndescribe('Agent file integrity', () => {\n test('.agent/agents/ directory exists', () => {\n expect(fs.existsSync(AGENTS_DIR)).toBe(true);\n });\n\n test('at least 30 agent files are present', () => {\n const files = fs.readdirSync(AGENTS_DIR).filter(f => f.endsWith('.md'));\n expect(files.length).toBeGreaterThanOrEqual(30);\n });\n\n test('all agent files are non-empty', () => {\n const files = fs.readdirSync(AGENTS_DIR).filter(f => f.endsWith('.md'));\n const empty = files.filter(f => fs.statSync(path.join(AGENTS_DIR, f)).size === 0);\n expect(empty).toEqual([]);\n });\n});\n\ndescribe('Skills directory integrity', () => {\n test('.agent/skills/ directory exists', () => {\n expect(fs.existsSync(SKILLS_DIR)).toBe(true);\n });\n\n test('at least 50 skill entries are present', () => {\n const entries = fs.readdirSync(SKILLS_DIR);\n // Each skill is a directory containing a SKILL.md\n const skillDirs = entries.filter(e => fs.statSync(path.join(SKILLS_DIR, e)).isDirectory());\n expect(skillDirs.length).toBeGreaterThanOrEqual(50);\n });\n\n test('every non-empty skill package directory contains a SKILL.md', () => {\n const entries = fs.readdirSync(SKILLS_DIR);\n const skillDirs = entries.filter(e => fs.statSync(path.join(SKILLS_DIR, e)).isDirectory());\n const missing = skillDirs.filter(dir => {\n const skillDir = path.join(SKILLS_DIR, dir);\n return fs.readdirSync(skillDir).length > 0 && !fs.existsSync(path.join(skillDir, 'SKILL.md'));\n });\n expect(missing).toEqual([]);\n });\n});\n"
12
11
  }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "file": "test/integration/swarm_dispatcher.test.js",
3
- "hash": "959cf59504544f624aea7ccad55fe2d9dc25ca4d",
4
3
  "riskScore": "Low",
5
4
  "blastRadius": 0,
6
5
  "imports": {
@@ -10,5 +9,5 @@
10
9
  "../../.agent/scripts/swarm_dispatcher.js": []
11
10
  },
12
11
  "dependents": [],
13
- "content": "const path = require('path');\r\nconst fs = require('fs');\r\nconst os = require('os');\r\nconst {\r\n findAgentDir,\r\n validatePayload,\r\n validateWorkerRequest,\r\n validateSwarmPayload\r\n} = require('../../.agent/scripts/swarm_dispatcher.js');\r\n\r\ndescribe('swarm_dispatcher.js legacy mode', () => {\r\n let tmpDir;\r\n\r\n beforeEach(() => {\r\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'swarm-test-'));\r\n });\r\n\r\n afterEach(() => {\r\n fs.rmSync(tmpDir, { recursive: true, force: true });\r\n });\r\n\r\n test('findAgentDir finds .agent directory', () => {\r\n const agentDir = path.join(tmpDir, '.agent');\r\n fs.mkdirSync(agentDir);\r\n const subDir = path.join(tmpDir, 'src', 'deep', 'folder');\r\n fs.mkdirSync(subDir, { recursive: true });\r\n\r\n const result = findAgentDir(subDir);\r\n expect(result).not.toBeNull();\r\n expect(path.resolve(result)).toBe(path.resolve(agentDir));\r\n });\r\n\r\n test('findAgentDir returns null if not found', () => {\r\n const subDir = path.join(tmpDir, 'src', 'deep');\r\n fs.mkdirSync(subDir, { recursive: true });\r\n\r\n expect(findAgentDir(subDir)).toBeNull();\r\n });\r\n\r\n test('validatePayload valid', () => {\r\n const agentsDir = path.join(tmpDir, 'agents');\r\n fs.mkdirSync(agentsDir);\r\n fs.writeFileSync(path.join(agentsDir, 'test_agent.md'), '');\r\n\r\n const workspace = path.join(tmpDir, 'workspace');\r\n fs.mkdirSync(workspace);\r\n fs.writeFileSync(path.join(workspace, 'file1.txt'), '');\r\n\r\n const payload = {\r\n dispatch_micro_workers: [\r\n {\r\n target_agent: \"test_agent\",\r\n files_attached: [\"file1.txt\"]\r\n }\r\n ]\r\n };\r\n\r\n expect(validatePayload(payload, workspace, agentsDir)).toBe(true);\r\n });\r\n\r\n test('validatePayload missing workers', () => {\r\n expect(validatePayload({}, tmpDir, tmpDir)).toBe(false);\r\n });\r\n\r\n test('validatePayload files not a list', () => {\r\n const agentsDir = path.join(tmpDir, 'agents');\r\n fs.mkdirSync(agentsDir);\r\n fs.writeFileSync(path.join(agentsDir, 'test_agent.md'), '');\r\n\r\n const payload = {\r\n dispatch_micro_workers: [\r\n {\r\n target_agent: \"test_agent\",\r\n files_attached: \"a single file string\"\r\n }\r\n ]\r\n };\r\n\r\n expect(validatePayload(payload, tmpDir, agentsDir)).toBe(false);\r\n });\r\n\r\n test('validateSwarmPayload validates WorkerRequest correctly', () => {\r\n const agentsDir = path.join(tmpDir, 'agents');\r\n fs.mkdirSync(agentsDir);\r\n fs.writeFileSync(path.join(agentsDir, 'research.md'), '');\r\n\r\n const req = {\r\n task_id: \"t123\",\r\n type: \"research\",\r\n agent: \"research\",\r\n goal: \"Find the root cause\",\r\n context: \"We have a bug here.\",\r\n max_retries: 2\r\n };\r\n\r\n const errors = validateWorkerRequest(req, 0, agentsDir);\r\n expect(errors).toHaveLength(0);\r\n\r\n expect(validateSwarmPayload([req], agentsDir)).toBe(true);\r\n });\r\n});\r\n"
12
+ "content": "const path = require('path');\nconst fs = require('fs');\nconst os = require('os');\nconst {\n findAgentDir,\n validatePayload,\n validateWorkerRequest,\n validateSwarmPayload,\n} = require('../../.agent/scripts/swarm_dispatcher.js');\n\ndescribe('swarm_dispatcher.js legacy mode', () => {\n let tmpDir;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'swarm-test-'));\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n test('findAgentDir finds .agent directory', () => {\n const agentDir = path.join(tmpDir, '.agent');\n fs.mkdirSync(agentDir);\n const subDir = path.join(tmpDir, 'src', 'deep', 'folder');\n fs.mkdirSync(subDir, { recursive: true });\n\n const result = findAgentDir(subDir);\n expect(result).not.toBeNull();\n expect(path.resolve(result)).toBe(path.resolve(agentDir));\n });\n\n test('findAgentDir returns null if not found', () => {\n const subDir = path.join(tmpDir, 'src', 'deep');\n fs.mkdirSync(subDir, { recursive: true });\n\n expect(findAgentDir(subDir)).toBeNull();\n });\n\n test('validatePayload valid', () => {\n const agentsDir = path.join(tmpDir, 'agents');\n fs.mkdirSync(agentsDir);\n fs.writeFileSync(path.join(agentsDir, 'test_agent.md'), '');\n\n const workspace = path.join(tmpDir, 'workspace');\n fs.mkdirSync(workspace);\n fs.writeFileSync(path.join(workspace, 'file1.txt'), '');\n\n const payload = {\n dispatch_micro_workers: [\n {\n target_agent: 'test_agent',\n files_attached: ['file1.txt'],\n },\n ],\n };\n\n expect(validatePayload(payload, workspace, agentsDir)).toBe(true);\n });\n\n test('validatePayload missing workers', () => {\n expect(validatePayload({}, tmpDir, tmpDir)).toBe(false);\n });\n\n test('validatePayload files not a list', () => {\n const agentsDir = path.join(tmpDir, 'agents');\n fs.mkdirSync(agentsDir);\n fs.writeFileSync(path.join(agentsDir, 'test_agent.md'), '');\n\n const payload = {\n dispatch_micro_workers: [\n {\n target_agent: 'test_agent',\n files_attached: 'a single file string',\n },\n ],\n };\n\n expect(validatePayload(payload, tmpDir, agentsDir)).toBe(false);\n });\n\n test('validateSwarmPayload validates WorkerRequest correctly', () => {\n const agentsDir = path.join(tmpDir, 'agents');\n fs.mkdirSync(agentsDir);\n fs.writeFileSync(path.join(agentsDir, 'research.md'), '');\n\n const req = {\n task_id: 't123',\n type: 'research',\n agent: 'research',\n goal: 'Find the root cause',\n context: 'We have a bug here.',\n max_retries: 2,\n };\n\n const errors = validateWorkerRequest(req, 0, agentsDir);\n expect(errors).toHaveLength(0);\n\n expect(validateSwarmPayload([req], agentsDir)).toBe(true);\n });\n});\n"
14
13
  }
@@ -0,0 +1,13 @@
1
+ {
2
+ "file": "test/integration/sync_status.test.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "fs": [],
7
+ "path": [],
8
+ "os": [],
9
+ "child_process": []
10
+ },
11
+ "dependents": [],
12
+ "content": "/**\n * sync_status.test.js\n * Integration tests for Day 3: Multi-IDE Rule Sync Engine & Status Dashboard.\n */\n\n'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\nconst os = require('os');\nconst { execFileSync } = require('child_process');\n\n/**\n * Helper: Find the compiled Rust binary.\n */\nfunction findBinary() {\n const repoRoot = path.join(__dirname, '../..');\n const isWindows = os.platform() === 'win32';\n const ext = isWindows ? '.exe' : '';\n const candidates = [\n path.join(repoRoot, 'target/release', `tribunal-core${ext}`),\n path.join(repoRoot, 'target/debug', `tribunal-core${ext}`),\n ];\n for (const c of candidates) {\n if (fs.existsSync(c)) return c;\n }\n return null;\n}\n\n/**\n * Helper: Create a temporary project directory with .agent/ scaffolding.\n */\nfunction createTempProject() {\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-sync-test-'));\n const agentDir = path.join(tempDir, '.agent');\n const rulesDir = path.join(agentDir, 'rules');\n const agentsDir = path.join(agentDir, 'agents');\n fs.mkdirSync(rulesDir, { recursive: true });\n fs.mkdirSync(agentsDir, { recursive: true });\n fs.writeFileSync(\n path.join(rulesDir, 'GEMINI.md'),\n '# Test Governance Rules\\n\\nRule content for sync testing.',\n );\n // Create a couple of reviewer agent files for readiness testing\n fs.writeFileSync(path.join(agentsDir, 'logic-reviewer.md'), '# Logic Reviewer');\n fs.writeFileSync(path.join(agentsDir, 'security-auditor.md'), '# Security Auditor');\n return tempDir;\n}\n\n/**\n * Helper: Cleanup temp directory.\n */\nfunction cleanupTempProject(tempDir) {\n fs.rmSync(tempDir, { recursive: true, force: true });\n}\n\ndescribe('Day 3: Multi-IDE Sync Engine & Status Dashboard', () => {\n const bin = findBinary();\n const skipRust = !bin;\n\n test('sync writes all 6 IDE bridge files from .agent/rules/GEMINI.md', () => {\n if (skipRust) {\n // Graceful skip if binary not compiled\n expect(true).toBe(true);\n return;\n }\n\n const tempDir = createTempProject();\n try {\n const out = execFileSync(bin, ['sync', '--quiet', tempDir], {\n encoding: 'utf8',\n });\n const res = JSON.parse(out.trim());\n\n expect(res.success).toBe(true);\n expect(res.bridges_synced).toBe(6);\n\n // Verify all bridge files were actually written\n expect(fs.existsSync(path.join(tempDir, '.cursorrules'))).toBe(true);\n expect(fs.existsSync(path.join(tempDir, '.windsurfrules'))).toBe(true);\n expect(fs.existsSync(path.join(tempDir, '.gemini', 'GEMINI.md'))).toBe(true);\n expect(fs.existsSync(path.join(tempDir, '.gemini', 'settings.json'))).toBe(true);\n expect(fs.existsSync(path.join(tempDir, '.github', 'copilot-instructions.md'))).toBe(true);\n expect(fs.existsSync(path.join(tempDir, '.claude', 'CLAUDE.md'))).toBe(true);\n\n // Verify bridge content contains the rules\n const cursorContent = fs.readFileSync(path.join(tempDir, '.cursorrules'), 'utf8');\n expect(cursorContent).toContain('Test Governance Rules');\n expect(cursorContent).toContain('tribunal-kit sync');\n } finally {\n cleanupTempProject(tempDir);\n }\n });\n\n test('status reports bridge health and reviewer readiness', () => {\n if (skipRust) {\n expect(true).toBe(true);\n return;\n }\n\n const tempDir = createTempProject();\n try {\n // First sync to create bridges\n execFileSync(bin, ['sync', '--quiet', tempDir], { encoding: 'utf8' });\n\n // Now check status\n const out = execFileSync(bin, ['status', tempDir], {\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n const res = JSON.parse(out.trim());\n\n expect(res.installed).toBe(true);\n expect(res.bridges).toBeDefined();\n expect(res.bridges.length).toBe(6);\n expect(res.reviewers).toBeDefined();\n expect(res.reviewers.ready).toBeGreaterThanOrEqual(2); // logic-reviewer + security-auditor\n expect(res.context_tokens_estimate).toBeDefined();\n } finally {\n cleanupTempProject(tempDir);\n }\n });\n\n test('status reports missing bridges when none exist', () => {\n if (skipRust) {\n expect(true).toBe(true);\n return;\n }\n\n const tempDir = createTempProject();\n try {\n // Don't sync — bridges should be missing\n const out = execFileSync(bin, ['status', tempDir], {\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'ignore'],\n });\n const res = JSON.parse(out.trim());\n\n expect(res.installed).toBe(true);\n expect(res.bridges).toBeDefined();\n const missingBridges = (res.bridges || []).filter(b => b.status === 'missing');\n expect(missingBridges.length).toBe(6);\n } finally {\n cleanupTempProject(tempDir);\n }\n });\n\n test('sync errors gracefully when .agent/ does not exist', () => {\n if (skipRust) {\n expect(true).toBe(true);\n return;\n }\n\n const emptyDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-empty-'));\n try {\n expect(() => {\n execFileSync(bin, ['sync', '--quiet', emptyDir], { encoding: 'utf8' });\n }).toThrow();\n } finally {\n fs.rmSync(emptyDir, { recursive: true, force: true });\n }\n });\n});\n"
13
+ }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "file": "test/integration/wave2.test.js",
3
- "hash": "703c635a4a0091e20785c3418b1ab294607a1635",
4
3
  "riskScore": "Low",
5
4
  "blastRadius": 0,
6
5
  "imports": {
@@ -10,5 +9,5 @@
10
9
  "../../.agent/scripts/case_law_manager.js": []
11
10
  },
12
11
  "dependents": [],
13
- "content": "const { getAssociatedScript } = require('../../.agent/scripts/skill_integrator.js');\r\nconst { architecturalWeight, semanticDelta } = require('../../.agent/scripts/skill_evolution.js');\r\nconst { findAgentDir } = require('../../.agent/scripts/case_law_manager.js');\r\n\r\ndescribe('Wave 2 Scripts (Evolving Brain)', () => {\r\n describe('skill_integrator.js', () => {\r\n it('should correctly identify implicit JS scripts', () => {\r\n // we mock fs internally if we wanted to true unit test, but for now just check exports\r\n expect(typeof getAssociatedScript).toBe('function');\r\n });\r\n });\r\n\r\n describe('skill_evolution.js', () => {\r\n it('should assign higher architectural weight to classes and interfaces', () => {\r\n expect(architecturalWeight('class User {')).toBeGreaterThanOrEqual(2);\r\n expect(architecturalWeight('interface Data {')).toBeGreaterThanOrEqual(2);\r\n });\r\n\r\n it('should assign 0 weight to noise patterns like comments and imports', () => {\r\n expect(architecturalWeight('// this is a comment')).toBe(0);\r\n expect(architecturalWeight('import { foo } from \"fs\";')).toBe(0);\r\n expect(architecturalWeight('')).toBe(0);\r\n });\r\n\r\n it('should successfully filter a semantic delta', () => {\r\n const rawDiff = `\r\n@@ -1,3 +1,4 @@\r\n import { foo } from 'fs';\r\n+import { baz } from 'fs';\r\n class Foo {\r\n- // old comment\r\n+ // new comment\r\n+ export class Baz {}\r\n }\r\n `.trim();\r\n\r\n const delta = semanticDelta(rawDiff, 2);\r\n // It gets kept because the hunk contains 'export class Baz {}'\r\n expect(delta).toContain('import { baz }');\r\n expect(delta).toContain('export class Baz {}');\r\n });\r\n });\r\n\r\n describe('case_law_manager.js', () => {\r\n it('should extract tags', () => {\r\n const { extractTags } = require('../../.agent/scripts/case_law_manager.js');\r\n expect(typeof extractTags).toBe('function');\r\n expect(extractTags('hello world and foo bar')).toContain('hello');\r\n expect(extractTags('hello world and foo bar')).not.toContain('and');\r\n });\r\n it('should find agent diff', () => {\r\n expect(typeof findAgentDir).toBe('function');\r\n });\r\n });\r\n});\r\n"
12
+ "content": "const { getAssociatedScript } = require('../../.agent/scripts/skill_integrator.js');\nconst { architecturalWeight, semanticDelta } = require('../../.agent/scripts/skill_evolution.js');\nconst { findAgentDir } = require('../../.agent/scripts/case_law_manager.js');\n\ndescribe('Wave 2 Scripts (Evolving Brain)', () => {\n describe('skill_integrator.js', () => {\n it('should correctly identify implicit JS scripts', () => {\n // we mock fs internally if we wanted to true unit test, but for now just check exports\n expect(typeof getAssociatedScript).toBe('function');\n });\n });\n\n describe('skill_evolution.js', () => {\n it('should assign higher architectural weight to classes and interfaces', () => {\n expect(architecturalWeight('class User {')).toBeGreaterThanOrEqual(2);\n expect(architecturalWeight('interface Data {')).toBeGreaterThanOrEqual(2);\n });\n\n it('should assign 0 weight to noise patterns like comments and imports', () => {\n expect(architecturalWeight('// this is a comment')).toBe(0);\n expect(architecturalWeight('import { foo } from \"fs\";')).toBe(0);\n expect(architecturalWeight('')).toBe(0);\n });\n\n it('should successfully filter a semantic delta', () => {\n const rawDiff = `\n@@ -1,3 +1,4 @@\n import { foo } from 'fs';\n+import { baz } from 'fs';\n class Foo {\n- // old comment\n+ // new comment\n+ export class Baz {}\n }\n `.trim();\n\n const delta = semanticDelta(rawDiff, 2);\n // It gets kept because the hunk contains 'export class Baz {}'\n expect(delta).toContain('import { baz }');\n expect(delta).toContain('export class Baz {}');\n });\n });\n\n describe('case_law_manager.js', () => {\n it('should extract tags', () => {\n const { extractTags } = require('../../.agent/scripts/case_law_manager.js');\n expect(typeof extractTags).toBe('function');\n expect(extractTags('hello world and foo bar')).toContain('hello');\n expect(extractTags('hello world and foo bar')).not.toContain('and');\n });\n it('should find agent diff', () => {\n expect(typeof findAgentDir).toBe('function');\n });\n });\n});\n"
14
13
  }
@@ -0,0 +1,13 @@
1
+ {
2
+ "file": "test/integration/wrapper.test.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "child_process": [],
7
+ "path": [],
8
+ "fs": [],
9
+ "os": []
10
+ },
11
+ "dependents": [],
12
+ "content": "'use strict';\n\nconst { spawnSync } = require('child_process');\nconst path = require('path');\nconst fs = require('fs');\nconst os = require('os');\n\nconst WRAPPER = path.resolve(__dirname, '../../bin/wrapper.js');\n\nfunction runWrapper(args = [], extraEnv = {}) {\n return spawnSync(process.execPath, [WRAPPER, ...args], {\n encoding: 'utf8',\n timeout: 5000,\n env: { ...process.env, TK_SKIP_UPDATE_CHECK: '1', ...extraEnv },\n });\n}\n\ndescribe('wrapper.js fallback routing', () => {\n test('routes unknown commands to JS implementation directly', () => {\n const result = runWrapper(['unknown-command-test']);\n // The JS implementation outputs 'Tribunal Kit' when run without args or unhandled command\n expect(result.stdout).toContain('Run tribunal-kit --help for usage');\n });\n\n test('warns and falls back to JS when Rust binary is not found for supported command', () => {\n const result = runWrapper(['status'], { TRIBUNAL_FORCE_JS: '1', TK_VERBOSE: '1' });\n // Since the binary doesn't exist yet, it should log the warning and then run JS status\n expect(result.stderr).toContain('Rust binary not found');\n // Check that the JS status command actually runs (it usually prints the agent config status)\n // We look for any known output from JS cmdStatus or at least lack of Rust execution\n expect(result.stdout).not.toContain('Executing via Rust Core Engine');\n });\n\n test('runs validate through the JavaScript fallback', () => {\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tk-wrapper-validate-'));\n const payloadPath = path.join(tempDir, 'payload.json');\n fs.writeFileSync(\n payloadPath,\n JSON.stringify({ dispatch_micro_workers: [{ target_agent: 'logic-reviewer' }] }),\n );\n\n try {\n const result = runWrapper(['validate', '--file', payloadPath, '--schema', 'micro-worker'], {\n TRIBUNAL_FORCE_JS: '1',\n TK_VERBOSE: '1',\n });\n expect(result.status).toBe(0);\n expect(result.stderr).toContain('Rust binary not found');\n } finally {\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n });\n});\n"
13
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "file": "test/unit/align.test.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "../../dist/commands/align": []
7
+ },
8
+ "dependents": [],
9
+ "content": "'use strict';\n\nconst { alignText, validateCodeContent } = require('../../dist/commands/align');\n\ndescribe('alignText', () => {\n test('strips standard conversational intro slop', () => {\n const input = \"Certainly! I'd be happy to help with that. Here is the code:\\n\\nconst x = 42;\\n\";\n expect(alignText(input)).toBe('const x = 42;');\n });\n\n test('strips other common greetings and intros', () => {\n const input = \"Sure, let's implement this feature. Here are the details:\\n\\nHello world\";\n expect(alignText(input)).toBe('Hello world');\n });\n\n test('strips standard conversational outro slop', () => {\n const input = 'const x = 42;\\n\\nI hope this helps! Let me know if you need anything else.';\n expect(alignText(input)).toBe('const x = 42;');\n });\n\n test('collapses single-item bullet lists to clean prose', () => {\n const input = 'We need to do the following:\\n- run npm install\\n';\n // - run npm install should collapse to \"Run npm install.\"\n expect(alignText(input)).toBe('We need to do the following:\\nRun npm install.');\n });\n\n test('collapses double-item bullet lists to clean prose', () => {\n const input = 'Next steps:\\n- do first step\\n- do second step';\n // Should collapse to \"Do first step. Do second step.\"\n expect(alignText(input)).toBe('Next steps:\\nDo first step. Do second step.');\n });\n\n test('leaves lists with 3 or more items intact', () => {\n const input = 'Steps:\\n- item one\\n- item two\\n- item three';\n expect(alignText(input)).toBe('Steps:\\n- item one\\n- item two\\n- item three');\n });\n});\n\ndescribe('validateCodeContent', () => {\n test('detects unawaited Next.js 15 cookies()/headers()/params() calls', () => {\n const code = \"const token = cookies().get('session');\";\n const warnings = validateCodeContent(code);\n expect(warnings.length).toBe(1);\n expect(warnings[0]).toContain('Next.js 15: Found unawaited call to cookies()');\n });\n\n test('does not warn on awaited Next.js 15 calls', () => {\n const code = \"const token = await cookies().get('session');\";\n const warnings = validateCodeContent(code);\n expect(warnings.length).toBe(0);\n });\n\n test('detects React 19 useFormState calls', () => {\n const code = 'const [state, dispatch] = useFormState(action, initialState);';\n const warnings = validateCodeContent(code);\n expect(warnings.length).toBe(1);\n expect(warnings[0]).toContain('React 19: Found useFormState');\n });\n\n test('detects Drizzle .filter() calls', () => {\n const code = 'const users = db.select().from(usersTable).filter(eq(usersTable.id, 1));';\n const warnings = validateCodeContent(code);\n expect(warnings.length).toBe(1);\n expect(warnings[0]).toContain('Drizzle ORM: Found .from().filter()');\n });\n\n test('detects non-existent LLM models', () => {\n const code = \"const model = 'gpt-5';\";\n const warnings = validateCodeContent(code);\n expect(warnings.length).toBe(1);\n expect(warnings[0]).toContain('LLM Models: Found references to non-existent models');\n });\n});\n"
10
+ }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "file": "test/unit/args.test.js",
3
- "hash": "b5863d3402957aae7315537ff9845c99899eeb50",
4
3
  "riskScore": "Low",
5
4
  "blastRadius": 0,
6
5
  "imports": {
@@ -12,9 +11,10 @@
12
11
  "isSelfInstall",
13
12
  "CORE_AGENTS",
14
13
  "CORE_SKILLS",
15
- "generateIDEBridges"
14
+ "generateIDEBridges",
15
+ "cmdMarathon"
16
16
  ]
17
17
  },
18
18
  "dependents": [],
19
- "content": "'use strict';\r\n\r\nconst { parseArgs } = require('../../bin/tribunal-kit');\r\n\r\ndescribe('parseArgs', () => {\r\n test('parses \"init\" command', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'init']);\r\n expect(result.command).toBe('init');\r\n expect(result.flags).toEqual({});\r\n });\r\n\r\n test('parses \"update\" command', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'update']);\r\n expect(result.command).toBe('update');\r\n });\r\n\r\n test('parses \"status\" command', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'status']);\r\n expect(result.command).toBe('status');\r\n });\r\n\r\n test('returns null command when no args given', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js']);\r\n expect(result.command).toBeNull();\r\n });\r\n\r\n test('parses --force flag', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--force']);\r\n expect(result.flags.force).toBe(true);\r\n });\r\n\r\n test('parses --quiet flag', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--quiet']);\r\n expect(result.flags.quiet).toBe(true);\r\n });\r\n\r\n test('parses --dry-run flag', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--dry-run']);\r\n expect(result.flags.dryRun).toBe(true);\r\n });\r\n\r\n test('parses --skip-update-check flag', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--skip-update-check']);\r\n expect(result.flags.skipUpdateCheck).toBe(true);\r\n });\r\n\r\n test('parses --path=<value> flag', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--path=./my-app']);\r\n expect(result.flags.path).toBe('./my-app');\r\n });\r\n\r\n test('parses --path <value> flag (space separated)', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--path', './my-app']);\r\n expect(result.flags.path).toBe('./my-app');\r\n });\r\n\r\n test('ignores unknown flags gracefully', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--unknown-flag']);\r\n expect(result.command).toBe('init');\r\n // Unknown flags don't throw, just get silently ignored\r\n expect(result.flags.unknownFlag).toBeUndefined();\r\n });\r\n\r\n test('multiple flags together', () => {\r\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--force', '--quiet', '--dry-run']);\r\n expect(result.flags.force).toBe(true);\r\n expect(result.flags.quiet).toBe(true);\r\n expect(result.flags.dryRun).toBe(true);\r\n });\r\n});\r\n"
19
+ "content": "'use strict';\n\nconst { parseArgs } = require('../../bin/tribunal-kit');\n\ndescribe('parseArgs', () => {\n test('parses \"init\" command', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'init']);\n expect(result.command).toBe('init');\n expect(result.flags).toEqual({});\n });\n\n test('parses \"update\" command', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'update']);\n expect(result.command).toBe('update');\n });\n\n test('parses \"status\" command', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'status']);\n expect(result.command).toBe('status');\n });\n\n test('returns null command when no args given', () => {\n const result = parseArgs(['node', 'tribunal-kit.js']);\n expect(result.command).toBeNull();\n });\n\n test('parses --force flag', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--force']);\n expect(result.flags.force).toBe(true);\n });\n\n test('parses --quiet flag', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--quiet']);\n expect(result.flags.quiet).toBe(true);\n });\n\n test('parses --dry-run flag', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--dry-run']);\n expect(result.flags.dryRun).toBe(true);\n });\n\n test('parses --skip-update-check flag', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--skip-update-check']);\n expect(result.flags.skipUpdateCheck).toBe(true);\n });\n\n test('parses --path=<value> flag', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--path=./my-app']);\n expect(result.flags.path).toBe('./my-app');\n });\n\n test('parses --path <value> flag (space separated)', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--path', './my-app']);\n expect(result.flags.path).toBe('./my-app');\n });\n\n test('ignores unknown flags gracefully', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--unknown-flag']);\n expect(result.command).toBe('init');\n // Unknown flags don't throw, just get silently ignored\n expect(result.flags.unknownFlag).toBeUndefined();\n });\n\n test('parses --token-optimized flag', () => {\n const result = parseArgs(['node', 'tribunal-kit.js', 'init', '--token-optimized']);\n expect(result.flags.tokenOptimized).toBe(true);\n });\n\n test('multiple flags together', () => {\n const result = parseArgs([\n 'node',\n 'tribunal-kit.js',\n 'init',\n '--force',\n '--quiet',\n '--dry-run',\n '--token-optimized',\n ]);\n expect(result.flags.force).toBe(true);\n expect(result.flags.quiet).toBe(true);\n expect(result.flags.dryRun).toBe(true);\n expect(result.flags.tokenOptimized).toBe(true);\n });\n});\n"
20
20
  }
@@ -0,0 +1,16 @@
1
+ {
2
+ "file": "test/unit/audit_release.test.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "fs": [],
7
+ "path": [],
8
+ "../../bin/mcp-server": [
9
+ "handleRequest",
10
+ "stripBoilerplate",
11
+ "runTribunalAudit"
12
+ ]
13
+ },
14
+ "dependents": [],
15
+ "content": "'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\n\nprocess.env.NODE_ENV = 'test';\nconst { handleRequest } = require('../../bin/mcp-server');\n\ndescribe('Release Audit Verification & Counts', () => {\n const rootDir = path.join(__dirname, '../..');\n const agentDir = path.join(rootDir, '.agent');\n const routingIndexPath = path.join(agentDir, 'routing_index.json');\n\n test('routing_index.json summary counts match actual filesystem totals', async () => {\n expect(fs.existsSync(routingIndexPath)).toBe(true);\n\n const routingIndex = JSON.parse(fs.readFileSync(routingIndexPath, 'utf8'));\n const { summary } = routingIndex;\n\n const agentFiles = fs.readdirSync(path.join(agentDir, 'agents')).filter(f => f.endsWith('.md'));\n const workflowFiles = fs\n .readdirSync(path.join(agentDir, 'workflows'))\n .filter(f => f.endsWith('.md'));\n const skillDirs = fs\n .readdirSync(path.join(agentDir, 'skills'), { withFileTypes: true })\n .filter(\n d => d.isDirectory() && fs.existsSync(path.join(agentDir, 'skills', d.name, 'SKILL.md')),\n );\n\n expect(summary.total_agents).toBe(agentFiles.length);\n expect(summary.total_workflows).toBe(workflowFiles.length);\n expect(summary.total_skills).toBe(skillDirs.length);\n });\n\n test('MCP Server handles resources/list and prompts/list correctly according to spec', async () => {\n const resListReq = { jsonrpc: '2.0', id: 101, method: 'resources/list', params: {} };\n const resListResult = await handleRequest(resListReq);\n expect(Array.isArray(resListResult.resources)).toBe(true);\n expect(resListResult.resources.length).toBeGreaterThan(0);\n\n const promptListReq = { jsonrpc: '2.0', id: 102, method: 'prompts/list', params: {} };\n const promptListResult = await handleRequest(promptListReq);\n expect(Array.isArray(promptListResult.prompts)).toBe(true);\n expect(promptListResult.prompts.length).toBeGreaterThan(0);\n });\n});\n"
16
+ }
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "file": "test/unit/case_law_manager.test.js",
3
- "hash": "172bdb2790ea2305d176f44b4d48826343e3fdc0",
4
3
  "riskScore": "Low",
5
4
  "blastRadius": 0,
6
5
  "imports": {
7
6
  "../../.agent/scripts/case_law_manager": []
8
7
  },
9
8
  "dependents": [],
10
- "content": "const {\r\n semanticDelta,\r\n extractTags,\r\n isNoiseRejection,\r\n isTrivialLine\r\n} = require('../../.agent/scripts/case_law_manager');\r\n\r\ndescribe('case_law_manager.js', () => {\r\n describe('Noise Filter', () => {\r\n it('should identify noise rejections', () => {\r\n expect(isNoiseRejection('Please fix formatting')).toBe(true);\r\n expect(isNoiseRejection('Trailing whitespace detected')).toBe(true);\r\n expect(isNoiseRejection('Run prettier')).toBe(true);\r\n });\r\n\r\n it('should allow valid rejections', () => {\r\n expect(isNoiseRejection('Missing SQL injection protection')).toBe(false);\r\n expect(isNoiseRejection('Type error in React component')).toBe(false);\r\n });\r\n });\r\n\r\n describe('Semantic Delta', () => {\r\n it('should identify trivial lines', () => {\r\n expect(isTrivialLine('// just a comment')).toBe(true);\r\n expect(isTrivialLine('import { foo } from \"bar\"')).toBe(true);\r\n expect(isTrivialLine('const a = 1;')).toBe(false);\r\n });\r\n\r\n it('should filter trivial changes from diff', () => {\r\n const diff = `--- file.js\\n+++ file.js\\n-import a from 'a'\\n+// a comment\\n+const a = 1;`;\r\n const delta = semanticDelta(diff);\r\n expect(delta).toContain('+const a = 1;');\r\n expect(delta).not.toContain('// a comment');\r\n expect(delta).not.toContain('import a');\r\n });\r\n });\r\n\r\n describe('Extract Tags', () => {\r\n it('should extract meaningful tags and ignore stop words', () => {\r\n const tags = extractTags('The React component has a missing key prop');\r\n expect(tags).toContain('react');\r\n expect(tags).toContain('component');\r\n expect(tags).toContain('missing');\r\n expect(tags).toContain('key');\r\n expect(tags).toContain('prop');\r\n expect(tags).not.toContain('the');\r\n expect(tags).not.toContain('has');\r\n expect(tags).not.toContain('a');\r\n });\r\n });\r\n});\r\n"
9
+ "content": "const {\n semanticDelta,\n extractTags,\n isNoiseRejection,\n isTrivialLine,\n} = require('../../.agent/scripts/case_law_manager');\n\ndescribe('case_law_manager.js', () => {\n describe('Noise Filter', () => {\n it('should identify noise rejections', () => {\n expect(isNoiseRejection('Please fix formatting')).toBe(true);\n expect(isNoiseRejection('Trailing whitespace detected')).toBe(true);\n expect(isNoiseRejection('Run prettier')).toBe(true);\n });\n\n it('should allow valid rejections', () => {\n expect(isNoiseRejection('Missing SQL injection protection')).toBe(false);\n expect(isNoiseRejection('Type error in React component')).toBe(false);\n });\n });\n\n describe('Semantic Delta', () => {\n it('should identify trivial lines', () => {\n expect(isTrivialLine('// just a comment')).toBe(true);\n expect(isTrivialLine('import { foo } from \"bar\"')).toBe(true);\n expect(isTrivialLine('const a = 1;')).toBe(false);\n });\n\n it('should filter trivial changes from diff', () => {\n const diff = `--- file.js\\n+++ file.js\\n-import a from 'a'\\n+// a comment\\n+const a = 1;`;\n const delta = semanticDelta(diff);\n expect(delta).toContain('+const a = 1;');\n expect(delta).not.toContain('// a comment');\n expect(delta).not.toContain('import a');\n });\n });\n\n describe('Extract Tags', () => {\n it('should extract meaningful tags and ignore stop words', () => {\n const tags = extractTags('The React component has a missing key prop');\n expect(tags).toContain('react');\n expect(tags).toContain('component');\n expect(tags).toContain('missing');\n expect(tags).toContain('key');\n expect(tags).toContain('prop');\n expect(tags).not.toContain('the');\n expect(tags).not.toContain('has');\n expect(tags).not.toContain('a');\n });\n });\n});\n"
11
10
  }
@@ -0,0 +1,12 @@
1
+ {
2
+ "file": "test/unit/cicd_validator.test.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "path": [],
7
+ "fs": [],
8
+ "../../.agent/scripts/cicd_validator.js": []
9
+ },
10
+ "dependents": [],
11
+ "content": "const path = require('path');\nconst fs = require('fs');\nconst {\n auditWorkflowContent,\n findWorkflowFiles,\n} = require('../../.agent/scripts/cicd_validator.js');\n\ndescribe('cicd_validator.js', () => {\n it('should be a valid javascript module exporting audit functions', () => {\n const filePath = path.join(__dirname, '../../.agent/scripts/cicd_validator.js');\n expect(fs.existsSync(filePath)).toBe(true);\n expect(typeof auditWorkflowContent).toBe('function');\n expect(typeof findWorkflowFiles).toBe('function');\n });\n\n it('should detect deprecated actions/checkout@v2 and @v3', () => {\n const yaml = `\nname: Test\non: [push]\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v2\n - uses: actions/setup-node@v3\n `;\n const issues = auditWorkflowContent('.github/workflows/ci.yml', yaml);\n const codes = issues.map(i => i.code);\n expect(codes).toContain('CI-01');\n expect(issues.filter(i => i.code === 'CI-01').length).toBe(2);\n });\n\n it('should flag dangerous pull_request_target with head.sha checkout', () => {\n const yaml = `\nname: PR\non: pull_request_target\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n with:\n ref: \\${{ github.event.pull_request.head.sha }}\n `;\n const issues = auditWorkflowContent('.github/workflows/pr.yml', yaml);\n const pwnIssues = issues.filter(i => i.code === 'CI-02');\n expect(pwnIssues.length).toBeGreaterThan(0);\n expect(pwnIssues[0].level).toBe('FAIL');\n });\n\n it('should flag permissions: write-all', () => {\n const yaml = `\nname: CI\non: push\npermissions: write-all\njobs:\n test:\n runs-on: ubuntu-latest\n `;\n const issues = auditWorkflowContent('.github/workflows/ci.yml', yaml);\n const permIssues = issues.filter(i => i.code === 'CI-04');\n expect(permIssues.length).toBe(1);\n expect(permIssues[0].level).toBe('FAIL');\n });\n\n it('should flag script injection into inline run commands', () => {\n const yaml = `\nname: Comment\non: issue_comment\njobs:\n notify:\n runs-on: ubuntu-latest\n steps:\n - run: echo \"\\${{ github.event.issue.title }}\"\n `;\n const issues = auditWorkflowContent('.github/workflows/comment.yml', yaml);\n const injectionIssues = issues.filter(i => i.code === 'CI-10');\n expect(injectionIssues.length).toBe(1);\n });\n\n it('should pass for a clean, hardened workflow', () => {\n const yaml = `\nname: CI\non:\n push:\n branches: [main]\nconcurrency:\n group: \\${{ github.workflow }}-\\${{ github.ref }}\n cancel-in-progress: true\npermissions:\n contents: read\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-node@v4\n with:\n node-version: 22\n cache: npm\n - run: npm ci\n - run: npm test\n `;\n const issues = auditWorkflowContent('.github/workflows/ci.yml', yaml);\n expect(issues.length).toBe(0);\n });\n});\n"
12
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "file": "test/unit/compile.test.js",
3
+ "riskScore": "Low",
4
+ "blastRadius": 0,
5
+ "imports": {
6
+ "../../dist/commands/compile": []
7
+ },
8
+ "dependents": [],
9
+ "content": "'use strict';\n\nconst { cmdCompile } = require('../../dist/commands/compile');\n\ndescribe('cmdCompile command', () => {\n test('exports cmdCompile function', () => {\n expect(typeof cmdCompile).toBe('function');\n });\n\n test('returns prompt compile structure for target agent', async () => {\n const flags = { target: 'aider', quiet: true };\n await expect(cmdCompile(flags, true)).resolves.not.toThrow();\n });\n});\n"
10
+ }