tribunal-kit 4.6.1 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/.agent/ARCHITECTURE.md +6 -7
  2. package/.agent/agents/frontend-reviewer.md +13 -0
  3. package/.agent/agents/frontend-specialist.md +14 -0
  4. package/.agent/agents/logic-reviewer.md +11 -0
  5. package/.agent/agents/orchestrator.md +15 -0
  6. package/.agent/agents/security-auditor.md +13 -0
  7. package/.agent/agents/ui-ux-auditor.md +7 -31
  8. package/.agent/history/memory/.memory.idx +766 -0
  9. package/.agent/history/memory/MEMORY.md +62 -0
  10. package/.agent/routing_index.json +694 -714
  11. package/.agent/rules/GEMINI.md +58 -8
  12. package/.agent/scripts/_colors.js +131 -89
  13. package/.agent/scripts/_utils.js +163 -128
  14. package/.agent/scripts/auto_preview.js +207 -197
  15. package/.agent/scripts/bundle_analyzer.js +227 -192
  16. package/.agent/scripts/case_law_manager.js +991 -689
  17. package/.agent/scripts/checklist.js +233 -190
  18. package/.agent/scripts/context_broker.js +930 -605
  19. package/.agent/scripts/dependency_analyzer.js +275 -184
  20. package/.agent/scripts/graph_builder.js +412 -341
  21. package/.agent/scripts/graph_visualizer.js +392 -390
  22. package/.agent/scripts/graph_zoom.js +198 -156
  23. package/.agent/scripts/inner_loop_validator.js +523 -445
  24. package/.agent/scripts/lint_runner.js +199 -157
  25. package/.agent/scripts/marathon_harness.js +819 -661
  26. package/.agent/scripts/minify_context.js +115 -100
  27. package/.agent/scripts/mutation_runner.js +321 -280
  28. package/.agent/scripts/prompt_compiler.js +62 -42
  29. package/.agent/scripts/schema_validator.js +373 -280
  30. package/.agent/scripts/security_scan.js +333 -190
  31. package/.agent/scripts/session_manager.js +306 -270
  32. package/.agent/scripts/skill_evolution.js +810 -637
  33. package/.agent/scripts/skill_integrator.js +327 -307
  34. package/.agent/scripts/strengthen_skills.js +203 -193
  35. package/.agent/scripts/swarm_dispatcher.js +558 -457
  36. package/.agent/scripts/test_runner.js +178 -152
  37. package/.agent/scripts/verify_all.js +200 -168
  38. package/.agent/skills/fabel-protocol/SKILL.md +235 -0
  39. package/.agent/skills/thinking-protocol/SKILL.md +27 -0
  40. package/.agent/workflows/generate.md +1 -1
  41. package/.agent/workflows/tribunal-speed.md +1 -1
  42. package/README.md +61 -47
  43. package/bin/mcp-server.js +476 -121
  44. package/bin/tribunal-kit.js +1245 -987
  45. package/bin/wrapper.js +104 -73
  46. package/dist/cli.js +265 -0
  47. package/dist/commands/case.js +71 -0
  48. package/dist/commands/compile.js +84 -0
  49. package/dist/commands/context.js +66 -0
  50. package/dist/commands/graph.js +38 -0
  51. package/dist/commands/hook.js +28 -0
  52. package/dist/commands/init.js +339 -0
  53. package/dist/commands/learn.js +117 -0
  54. package/dist/commands/marathon.js +45 -0
  55. package/dist/commands/memory.js +456 -0
  56. package/dist/commands/mutate.js +30 -0
  57. package/dist/commands/status.js +35 -0
  58. package/dist/commands/sync.js +25 -0
  59. package/dist/commands/uninstall.js +42 -0
  60. package/dist/commands/update.js +37 -0
  61. package/dist/mcp/server.js +142 -0
  62. package/dist/types.js +8 -0
  63. package/dist/utils/fs.js +96 -0
  64. package/dist/utils/hasher.js +142 -0
  65. package/dist/utils/helpers.js +68 -0
  66. package/dist/utils/logger.js +54 -0
  67. package/dist/utils/version.js +150 -0
  68. package/package.json +3 -2
  69. package/scripts/benchmark.js +197 -0
  70. package/scripts/changelog.js +196 -168
  71. package/scripts/sync-version.js +94 -81
  72. package/scripts/validate-payload.js +85 -78
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cmdContext = cmdContext;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const logger_1 = require("../utils/logger");
10
+ function cmdContext(flags, processArgs) {
11
+ const targetDir = flags.path ? path_1.default.resolve(flags.path) : process.cwd();
12
+ const agentDest = path_1.default.join(targetDir, '.agent');
13
+ if (!fs_1.default.existsSync(agentDest)) {
14
+ (0, logger_1.err)('.agent/ not found. Run: npx tribunal-kit init');
15
+ process.exit(1);
16
+ }
17
+ const args = processArgs.slice(3);
18
+ if (args.length === 0 || args[0] === 'help' || args[0] === '--help') {
19
+ console.error('Usage: npx tribunal-kit context <target_file>');
20
+ process.exit(1);
21
+ }
22
+ const targetFile = args[0].replace(/\\/g, '/');
23
+ const snapshotName = targetFile.replace(/[\\\/]/g, '__') + '.json';
24
+ const snapshotPath = path_1.default.join(agentDest, 'history', 'snapshots', snapshotName);
25
+ if (!fs_1.default.existsSync(snapshotPath)) {
26
+ console.error(' \x1b[91m✖\x1b[0m Context Snapshot not found for: ' + targetFile);
27
+ console.log(' Run: npx tribunal-kit graph (to generate snapshots)');
28
+ process.exit(1);
29
+ }
30
+ try {
31
+ const snapshot = JSON.parse(fs_1.default.readFileSync(snapshotPath, 'utf8'));
32
+ console.log('\n# Context Snapshot: ' + snapshot.file);
33
+ process.stdout.write('> Size Estimate: ' + (snapshot['estimatedTokens'] || 'Unknown') + '\n');
34
+ console.log('> Risk Score: ' + snapshot.riskScore + ' (Blast Radius: ' + snapshot.blastRadius + ')\n');
35
+ if (Object.keys(snapshot.imports).length > 0) {
36
+ console.log('## Imports');
37
+ for (const [imp, exports] of Object.entries(snapshot.imports)) {
38
+ if (Array.isArray(exports) && exports.length > 0) {
39
+ console.log('- `' + imp + '` (exports: ' + exports.join(', ') + ')');
40
+ }
41
+ else {
42
+ console.log('- `' + imp + '`');
43
+ }
44
+ }
45
+ console.log();
46
+ }
47
+ if (snapshot.dependents && snapshot.dependents.length > 0) {
48
+ console.log('## Dependents');
49
+ for (const dep of snapshot.dependents) {
50
+ console.log('- `' + dep + '`');
51
+ }
52
+ console.log();
53
+ }
54
+ console.log('## Source Code');
55
+ console.log('```javascript\n' + snapshot.content + '\n```\n');
56
+ }
57
+ catch (e) {
58
+ if (e instanceof Error) {
59
+ console.error('Failed to read snapshot: ' + e.message);
60
+ }
61
+ else {
62
+ console.error('Failed to read snapshot: ' + String(e));
63
+ }
64
+ process.exit(1);
65
+ }
66
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cmdGraph = cmdGraph;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const logger_1 = require("../utils/logger");
10
+ const helpers_1 = require("../utils/helpers");
11
+ async function cmdGraph(flags, quiet = false) {
12
+ const targetDir = flags.path ? path_1.default.resolve(flags.path) : process.cwd();
13
+ const agentDest = path_1.default.join(targetDir, '.agent');
14
+ if (!fs_1.default.existsSync(agentDest)) {
15
+ (0, logger_1.err)('.agent/ not found. Run: npx tribunal-kit init');
16
+ process.exit(1);
17
+ }
18
+ (0, helpers_1.banner)(quiet);
19
+ const builderScript = path_1.default.join(agentDest, 'scripts', 'graph_builder.js');
20
+ const visualizerScript = path_1.default.join(agentDest, 'scripts', 'graph_visualizer.js');
21
+ const htmlFile = path_1.default.join(agentDest, 'history', 'architecture-explorer.html');
22
+ try {
23
+ await (0, helpers_1.runShellAsync)(`node "${builderScript}"`, { stdio: 'inherit', cwd: targetDir });
24
+ await (0, helpers_1.runShellAsync)(`node "${visualizerScript}"`, { stdio: 'inherit', cwd: targetDir });
25
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '▸')} Opening visualizer in browser...`);
26
+ const opener = process.platform === 'win32' ? 'start' : process.platform === 'darwin' ? 'open' : 'xdg-open';
27
+ await (0, helpers_1.runShellAsync)(`${opener} "${htmlFile}"`, { stdio: 'ignore' });
28
+ }
29
+ catch (e) {
30
+ if (e instanceof Error) {
31
+ (0, logger_1.err)(`Graph generation failed: ${e.message}`);
32
+ }
33
+ else {
34
+ (0, logger_1.err)(`Graph generation failed: ${String(e)}`);
35
+ }
36
+ process.exit(1);
37
+ }
38
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cmdHook = cmdHook;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const logger_1 = require("../utils/logger");
10
+ function cmdHook(flags) {
11
+ const targetDir = flags.path ? path_1.default.resolve(flags.path) : process.cwd();
12
+ const gitDir = path_1.default.join(targetDir, '.git');
13
+ if (!fs_1.default.existsSync(gitDir)) {
14
+ (0, logger_1.err)('Not a git repository. Cannot install git hooks here.');
15
+ process.exit(1);
16
+ }
17
+ const hooksDir = path_1.default.join(gitDir, 'hooks');
18
+ if (!fs_1.default.existsSync(hooksDir)) {
19
+ fs_1.default.mkdirSync(hooksDir, { recursive: true });
20
+ }
21
+ const prePushPath = path_1.default.join(hooksDir, 'pre-push');
22
+ const hookScript = `#!/bin/sh\n# Supreme Court - Auto Learn on Push\necho "⚖️ Tribunal Supreme Court: Evolving Skills..."\nnpx tribunal-kit learn --head\necho "✦ Synchronizing IDE bridges..."\nnpx tribunal-kit sync\n`;
23
+ fs_1.default.writeFileSync(prePushPath, hookScript, { mode: 0o755 });
24
+ console.log();
25
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', '✔')} Installed pre-push git hook.`);
26
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▸')} Skill Evolution and IDE Sync will now run automatically every time you git push.`);
27
+ console.log();
28
+ }
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cmdInit = cmdInit;
7
+ exports.generateIDEBridges = generateIDEBridges;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const logger_1 = require("../utils/logger");
11
+ const fs_2 = require("../utils/fs");
12
+ const helpers_1 = require("../utils/helpers");
13
+ const hasher_1 = require("../utils/hasher");
14
+ // Core agents to install in --minimal mode
15
+ const CORE_AGENTS = new Set([
16
+ 'backend-specialist.md',
17
+ 'frontend-specialist.md',
18
+ 'database-architect.md',
19
+ 'debugger.md',
20
+ 'security-auditor.md',
21
+ 'logic-reviewer.md',
22
+ 'dependency-reviewer.md',
23
+ 'type-safety-reviewer.md',
24
+ 'performance-reviewer.md',
25
+ 'orchestrator.md',
26
+ 'explorer-agent.md',
27
+ 'project-planner.md',
28
+ 'test-engineer.md',
29
+ ]);
30
+ // Core skills to install in --minimal mode
31
+ const CORE_SKILLS = new Set([
32
+ 'clean-code', 'architecture', 'testing-patterns', 'systematic-debugging',
33
+ 'frontend-design', 'database-design', 'api-patterns', 'nodejs-best-practices',
34
+ 'vulnerability-scanner', 'typescript-advanced', 'python-pro', 'nextjs-react-expert',
35
+ 'react-specialist', 'performance-profiling', 'lint-and-validate',
36
+ ]);
37
+ async function cmdInit(flags, quiet = false) {
38
+ const agentSrc = (0, helpers_1.getKitAgent)();
39
+ const targetDir = flags.path ? path_1.default.resolve(flags.path) : process.cwd();
40
+ const agentDest = path_1.default.join(targetDir, '.agent');
41
+ const dryRun = flags.dryRun || false;
42
+ const pkgStr = fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../package.json'), 'utf8');
43
+ const pkg = JSON.parse(pkgStr);
44
+ // ── Self-install guard ──────────────────────────────────
45
+ if ((0, fs_2.isSelfInstall)(targetDir, pkg.name, path_1.default.resolve(__dirname, '../..'))) {
46
+ (0, logger_1.err)('Cannot run init/update inside the tribunal-kit package itself.');
47
+ (0, logger_1.err)(`Target: ${targetDir}`);
48
+ (0, logger_1.err)(`Package: ${path_1.default.resolve(__dirname, '../..')}`);
49
+ console.log();
50
+ (0, logger_1.dim)('This command is designed to install .agent/ into OTHER projects.');
51
+ (0, logger_1.dim)('Run it from the root of the project you want to set up:');
52
+ (0, logger_1.dim)(' cd /path/to/your-project');
53
+ (0, logger_1.dim)(' npx tribunal-kit init');
54
+ console.log();
55
+ process.exit(1);
56
+ }
57
+ // ────────────────────────────────────────────────────────
58
+ let diff = null;
59
+ let incremental = false;
60
+
61
+ if (!dryRun && fs_1.default.existsSync(agentDest) && flags.force) {
62
+ const oldManifest = (0, hasher_1.readManifest)(agentDest);
63
+ if (oldManifest) {
64
+ const newManifest = await (0, hasher_1.generateManifest)(agentSrc);
65
+ diff = (0, hasher_1.diffManifests)(oldManifest, newManifest);
66
+ incremental = true;
67
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '✦')} Performing incremental update (${diff.added.length} added, ${diff.changed.length} changed, ${diff.removed.length} removed)`);
68
+
69
+ // Backup ONLY changed or removed files
70
+ const toBackup = [...diff.changed, ...diff.removed];
71
+ if (toBackup.length > 0) {
72
+ const backupDir = path_1.default.join(agentDest, '.backups', `backup-${Date.now()}`);
73
+ fs_1.default.mkdirSync(backupDir, { recursive: true });
74
+ let backedUpCount = 0;
75
+ for (const file of toBackup) {
76
+ const srcPath = path_1.default.join(agentDest, file);
77
+ const destPath = path_1.default.join(backupDir, file);
78
+ if (fs_1.default.existsSync(srcPath)) {
79
+ fs_1.default.mkdirSync(path_1.default.dirname(destPath), { recursive: true });
80
+ fs_1.default.copyFileSync(srcPath, destPath);
81
+ backedUpCount++;
82
+ }
83
+ }
84
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', `✦ Backed up ${backedUpCount} modified/removed files to .backups/`)}`);
85
+ }
86
+
87
+ // Remove removed files
88
+ for (const file of diff.removed) {
89
+ const target = path_1.default.join(agentDest, file);
90
+ if (fs_1.default.existsSync(target)) {
91
+ fs_1.default.rmSync(target);
92
+ }
93
+ }
94
+ } else {
95
+ // Legacy full backup
96
+ const backupDir = path_1.default.join(agentDest, '.backups', `backup-${Date.now()}`);
97
+ fs_1.default.mkdirSync(backupDir, { recursive: true });
98
+ const subdirs = ['agents', 'workflows', 'skills', 'scripts', '.shared', 'rules'];
99
+ for (const sub of subdirs) {
100
+ const subPath = path_1.default.join(agentDest, sub);
101
+ if (fs_1.default.existsSync(subPath)) {
102
+ await (0, fs_2.copyDir)(subPath, path_1.default.join(backupDir, sub), false);
103
+ await fs_1.default.promises.rm(subPath, { recursive: true, force: true });
104
+ }
105
+ }
106
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '✦ Backed up existing configurations to .agent/.backups/')}`);
107
+ }
108
+ }
109
+ // ────────────────────────────────────────────────────────
110
+ (0, helpers_1.banner)(quiet);
111
+ if (dryRun) {
112
+ (0, logger_1.log)((0, logger_1.colorize)('yellow', ' DRY RUN — no files will be written'));
113
+ console.log();
114
+ }
115
+ // Check target exists
116
+ if (!fs_1.default.existsSync(targetDir)) {
117
+ (0, logger_1.err)(`Target directory not found: ${targetDir}`);
118
+ process.exit(1);
119
+ }
120
+ // Check if .agent already exists
121
+ if (fs_1.default.existsSync(agentDest) && !flags.force) {
122
+ (0, logger_1.warn)('.agent/ already exists in this project.');
123
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▸')} To refresh or update it, run: ${(0, logger_1.colorize)('white', 'tribunal-kit init --force')}`);
124
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▸')} Or check status with: ${(0, logger_1.colorize)('cyan', 'tribunal-kit status')}`);
125
+ console.log();
126
+ process.exit(0);
127
+ }
128
+ // Ensure history dirs exist (Case Law + Skill Evolution)
129
+ if (!dryRun) {
130
+ const caseDir = path_1.default.join(agentDest, 'history', 'case-law', 'cases');
131
+ const evoDir = path_1.default.join(agentDest, 'history', 'skill-evolution');
132
+ fs_1.default.mkdirSync(caseDir, { recursive: true });
133
+ fs_1.default.mkdirSync(evoDir, { recursive: true });
134
+ const gkCase = path_1.default.join(caseDir, '.gitkeep');
135
+ const gkEvo = path_1.default.join(evoDir, '.gitkeep');
136
+ if (!fs_1.default.existsSync(gkCase))
137
+ fs_1.default.writeFileSync(gkCase, '');
138
+ if (!fs_1.default.existsSync(gkEvo))
139
+ fs_1.default.writeFileSync(gkEvo, '');
140
+ }
141
+ // Count what we're installing
142
+ const isMinimal = flags.minimal || false;
143
+ if (isMinimal) {
144
+ (0, logger_1.log)(` ${(0, logger_1.c)('yellow', '⚡')} ${(0, logger_1.bold)('Minimal mode')} — installing core agents and skills only`);
145
+ console.log();
146
+ }
147
+ const totalFiles = await (0, fs_2.countDir)(agentSrc);
148
+ (0, logger_1.dbg)(`Source: ${agentSrc}`);
149
+ (0, logger_1.dbg)(`Target: ${agentDest}`);
150
+ (0, logger_1.dbg)(`Total source files: ${totalFiles}`);
151
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '▸')} Scanning ${(0, logger_1.c)('white', String(totalFiles))} files ${(0, logger_1.c)('gray', '→')} ${(0, logger_1.c)('gray', agentDest)}`);
152
+ try {
153
+ // Build filter for --minimal mode
154
+ let filterFunc = isMinimal ? (name, parentDir, isDir) => {
155
+ if (isDir) return true; // always traverse directories
156
+ const parentName = path_1.default.basename(parentDir);
157
+ if (parentName === 'agents')
158
+ return CORE_AGENTS.has(name);
159
+ if (parentName === 'skills')
160
+ return CORE_SKILLS.has(name);
161
+ return true; // everything else passes
162
+ } : null;
163
+
164
+ if (incremental && diff) {
165
+ const addedSet = new Set(diff.added);
166
+ const changedSet = new Set(diff.changed);
167
+ const baseFilter = filterFunc;
168
+ filterFunc = (name, parentDir, isDir) => {
169
+ if (isDir) return true;
170
+ if (baseFilter && !baseFilter(name, parentDir, isDir)) return false;
171
+
172
+ const relativePath = path_1.default.relative(agentSrc, path_1.default.join(parentDir, name)).replace(/\\/g, '/');
173
+ return addedSet.has(relativePath) || changedSet.has(relativePath);
174
+ };
175
+ }
176
+
177
+ const copied = await (0, fs_2.copyDir)(agentSrc, agentDest, dryRun, filterFunc);
178
+ // Generate and save hash manifest for incremental future updates
179
+ if (!dryRun) {
180
+ try {
181
+ const manifest = await (0, hasher_1.generateManifest)(agentSrc);
182
+ (0, hasher_1.writeManifest)(agentDest, manifest);
183
+ (0, logger_1.dbg)(` Manifest saved: ${Object.keys(manifest).length} files hashed`);
184
+ } catch (e) {
185
+ (0, logger_1.dbg)(` Manifest generation skipped: ${e.message}`);
186
+ }
187
+ }
188
+ console.log();
189
+ if (dryRun) {
190
+ (0, logger_1.ok)(`${(0, logger_1.bold)('DRY RUN')} complete — would install ${(0, logger_1.c)('cyan', String(copied))} files`);
191
+ (0, logger_1.dim)(`Target: ${agentDest}`);
192
+ }
193
+ else {
194
+ // ── Success card — W=62, rows padded by plain-text length ──
195
+ const W = 62;
196
+ const agentsCount = fs_1.default.readdirSync(path_1.default.join(agentDest, 'agents')).length;
197
+ const workflowsCount = fs_1.default.readdirSync(path_1.default.join(agentDest, 'workflows')).length;
198
+ const skillsCount = fs_1.default.readdirSync(path_1.default.join(agentDest, 'skills')).length;
199
+ const scriptsCount = fs_1.default.readdirSync(path_1.default.join(agentDest, 'scripts')).length;
200
+ // Stat rows: compute trailing spaces from plain text so right ║ aligns
201
+ const statRow = (icon, label, val, col) => {
202
+ const plain = ` ${icon} ${label.padEnd(10)}${String(val).padStart(3)} installed`;
203
+ const trail = ' '.repeat(Math.max(0, W - plain.length));
204
+ return ` ${(0, logger_1.c)('cyan', '║')} ${icon} ${(0, logger_1.c)('white', label.padEnd(10))}${(0, logger_1.c)(col, String(val).padStart(3))} ${(0, logger_1.c)('gray', 'installed')}${trail}${(0, logger_1.c)('cyan', '║')}`;
205
+ };
206
+ // Plain-text rows (header / blank)
207
+ const plainRow = (text, wrapFn) => {
208
+ const trail = ' '.repeat(Math.max(0, W - text.length));
209
+ return ` ${(0, logger_1.c)('cyan', '║')}${wrapFn(text)}${trail}${(0, logger_1.c)('cyan', '║')}`;
210
+ };
211
+ // Next-step rows: fixed cmd column + description
212
+ const stepRow = (cmd, desc) => {
213
+ const plain = ` ${cmd.padEnd(16)}${desc}`;
214
+ const trail = ' '.repeat(Math.max(0, W - plain.length));
215
+ return ` ${(0, logger_1.c)('cyan', '║')} ${(0, logger_1.c)('white', cmd.padEnd(16))}${(0, logger_1.c)('gray', desc)}${trail}${(0, logger_1.c)('cyan', '║')}`;
216
+ };
217
+ console.log(` ${(0, logger_1.c)('green', '✔')} ${(0, logger_1.bold)((0, logger_1.c)('green', 'Installation complete'))} ${(0, logger_1.c)('gray', '—')} ${(0, logger_1.c)('white', String(copied))} files`);
218
+ console.log(` ${(0, logger_1.c)('gray', ' ╰─')} ${(0, logger_1.c)('gray', agentDest)}`);
219
+ console.log();
220
+ console.log(` ${(0, logger_1.c)('cyan', '╔' + '═'.repeat(W) + '╗')}`);
221
+ console.log(plainRow(` What's inside:`, s => (0, logger_1.bold)((0, logger_1.c)('white', s))));
222
+ console.log(` ${(0, logger_1.c)('cyan', '╠' + '═'.repeat(W) + '╣')}`);
223
+ console.log(statRow('🤖', 'Agents', agentsCount, 'magenta'));
224
+ console.log(statRow('⚡', 'Workflows', workflowsCount, 'yellow'));
225
+ console.log(statRow('🧠', 'Skills', skillsCount, 'blue'));
226
+ console.log(statRow('🔧', 'Scripts', scriptsCount, 'green'));
227
+ console.log(` ${(0, logger_1.c)('cyan', '╠' + '═'.repeat(W) + '╣')}`);
228
+ console.log(plainRow('', () => ''));
229
+ console.log(plainRow(` Next steps:`, s => (0, logger_1.c)('gray', s)));
230
+ console.log(stepRow('/generate', 'Generate code with anti-hallucination'));
231
+ console.log(stepRow('/review', 'Audit existing code for issues'));
232
+ console.log(stepRow('/tribunal-full', 'Run all 16 reviewers in parallel'));
233
+ console.log(plainRow('', () => ''));
234
+ console.log(` ${(0, logger_1.c)('cyan', '╚' + '═'.repeat(W) + '╝')}`);
235
+ console.log();
236
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '✦ Generating IDE bridge files...')}`);
237
+ await generateIDEBridges(targetDir, agentDest, dryRun);
238
+ }
239
+ console.log();
240
+ }
241
+ catch (e) {
242
+ if (e instanceof Error) {
243
+ (0, logger_1.err)(`Failed to install: ${e.message}`);
244
+ }
245
+ else {
246
+ (0, logger_1.err)(`Failed to install: ${String(e)}`);
247
+ }
248
+ process.exit(1);
249
+ }
250
+ }
251
+ async function generateIDEBridges(targetDir, agentDest, dryRun = false) {
252
+ const rulesFile = path_1.default.join(agentDest, 'rules', 'GEMINI.md');
253
+ let rulesContent = '';
254
+ try {
255
+ rulesContent = await fs_1.default.promises.readFile(rulesFile, 'utf8');
256
+ }
257
+ catch {
258
+ // rules file doesn't exist
259
+ }
260
+ // Helper: write a bridge file only if it doesn't already exist
261
+ const writeBridge = async (filePath, content, label) => {
262
+ if (dryRun) {
263
+ (0, logger_1.dbg)(` would create: ${filePath}`);
264
+ return;
265
+ }
266
+ const dir = path_1.default.dirname(filePath);
267
+ try {
268
+ await fs_1.default.promises.mkdir(dir, { recursive: true });
269
+ await fs_1.default.promises.stat(filePath);
270
+ (0, logger_1.dbg)(` skip (exists): ${path_1.default.basename(filePath)}`);
271
+ }
272
+ catch (statErr) {
273
+ if (statErr instanceof Error && statErr.code === 'ENOENT') {
274
+ await fs_1.default.promises.writeFile(filePath, content, 'utf8');
275
+ (0, logger_1.ok)(`${label} → ${(0, logger_1.c)('gray', path_1.default.relative(targetDir, filePath))}`);
276
+ }
277
+ }
278
+ };
279
+ // ── 1. Cursor (.cursorrules) ──────────────────────────
280
+ const cursorRules = `# Tribunal Kit — Cursor Bridge
281
+ # Auto-generated by tribunal-kit init. Do not edit manually.
282
+ # Source: .agent/rules/GEMINI.md
283
+
284
+ ${rulesContent}
285
+ `;
286
+ // ── 2. Windsurf (.windsurfrules) ─────────────────────
287
+ const windsurfRules = `# Tribunal Kit — Windsurf Bridge
288
+ # Auto-generated by tribunal-kit init. Do not edit manually.
289
+ # Source: .agent/rules/GEMINI.md
290
+
291
+ ${rulesContent}
292
+ `;
293
+ // ── 3. Gemini / Antigravity (.gemini/settings.json) ──
294
+ const geminiSettings = JSON.stringify({
295
+ "rules": [
296
+ { "path": "../.agent/rules/GEMINI.md", "trigger": "always_on" }
297
+ ],
298
+ "agents": { "directory": "../.agent/agents" },
299
+ "skills": { "directory": "../.agent/skills" },
300
+ "workflows": { "directory": "../.agent/workflows" }
301
+ }, null, 2) + '\n';
302
+ // ── Also create .gemini/GEMINI.md as a direct rules file ──
303
+ const geminiRulesBridge = `---
304
+ trigger: always_on
305
+ ---
306
+
307
+ # Tribunal Kit — Gemini Bridge
308
+ # Auto-generated by tribunal-kit init.
309
+ # Full rules: .agent/rules/GEMINI.md
310
+
311
+ ${rulesContent}
312
+ `;
313
+ // ── 4. GitHub Copilot (.github/copilot-instructions.md) ──
314
+ const copilotInstructions = `# Tribunal Kit — Copilot Bridge
315
+ # Auto-generated by tribunal-kit init. Do not edit manually.
316
+ # Source: .agent/rules/GEMINI.md
317
+
318
+ ${rulesContent}
319
+ `;
320
+ // ── 5. Claude (.claude/CLAUDE.md) ─────────────────────
321
+ const claudeRules = `# Tribunal Kit — Claude Bridge
322
+ # Auto-generated by tribunal-kit init. Do not edit manually.
323
+ # Source: .agent/rules/GEMINI.md
324
+
325
+ ${rulesContent}
326
+ `;
327
+ // Fire ALL bridge writes concurrently via Promise.all
328
+ const bridges = [
329
+ { path: path_1.default.join(targetDir, '.cursorrules'), content: cursorRules, label: 'Cursor' },
330
+ { path: path_1.default.join(targetDir, '.windsurfrules'), content: windsurfRules, label: 'Windsurf' },
331
+ { path: path_1.default.join(targetDir, '.gemini', 'settings.json'), content: geminiSettings, label: 'Gemini/Antigravity' },
332
+ { path: path_1.default.join(targetDir, '.gemini', 'GEMINI.md'), content: geminiRulesBridge, label: 'Gemini rules' },
333
+ { path: path_1.default.join(targetDir, '.github', 'copilot-instructions.md'), content: copilotInstructions, label: 'GitHub Copilot' },
334
+ { path: path_1.default.join(targetDir, '.claude', 'CLAUDE.md'), content: claudeRules, label: 'Claude' },
335
+ ];
336
+ await Promise.all(bridges.map(b => writeBridge(b.path, b.content, b.label)));
337
+ console.log();
338
+ }
339
+
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cmdLearn = cmdLearn;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const logger_1 = require("../utils/logger");
10
+ const helpers_1 = require("../utils/helpers");
11
+ async function cmdLearn(flags, quiet = false) {
12
+ const targetDir = flags.path ? path_1.default.resolve(flags.path) : process.cwd();
13
+ const agentDest = path_1.default.join(targetDir, '.agent');
14
+ if (!fs_1.default.existsSync(agentDest)) {
15
+ (0, logger_1.err)('.agent/ not found. Run: npx tribunal-kit init');
16
+ process.exit(1);
17
+ }
18
+ (0, helpers_1.banner)(quiet);
19
+ const W = 62;
20
+ const title = ' Tribunal Learn — Supreme Court Mode';
21
+ const trail = ' '.repeat(Math.max(0, W - title.length));
22
+ console.log(` ${(0, logger_1.c)('cyan', '\u2554' + '\u2550'.repeat(W) + '\u2557')}`);
23
+ console.log(` ${(0, logger_1.c)('cyan', '\u2551')}${(0, logger_1.bold)((0, logger_1.c)('white', title))}${trail}${(0, logger_1.c)('cyan', '\u2551')}`);
24
+ console.log(` ${(0, logger_1.c)('cyan', '\u255a' + '\u2550'.repeat(W) + '\u255d')}`);
25
+ console.log();
26
+ const dryRun = flags.dryRun ? '--dry-run' : '';
27
+ const useHead = flags.head ? '--head' : '';
28
+ // Phase 1: Skill Evolution
29
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '\u229b')} ${(0, logger_1.bold)('Phase 1')} \u2014 Skill Evolution Forge (auto-generating project idioms)`);
30
+ const evoScript = path_1.default.join(agentDest, 'scripts', 'skill_evolution.js');
31
+ if (!fs_1.default.existsSync(evoScript)) {
32
+ (0, logger_1.warn)('skill_evolution.js not found \u2014 run: npx tribunal-kit update');
33
+ }
34
+ else {
35
+ try {
36
+ const cmd = `node "${evoScript}" digest ${dryRun} ${useHead}`.trim();
37
+ await (0, helpers_1.runShellAsync)(cmd, { stdio: 'inherit', cwd: targetDir });
38
+ }
39
+ catch (e) {
40
+ if (e instanceof Error) {
41
+ (0, logger_1.warn)(`Skill Evolution error: ${e.message}`);
42
+ }
43
+ else {
44
+ (0, logger_1.warn)(`Skill Evolution error: ${String(e)}`);
45
+ }
46
+ }
47
+ }
48
+ console.log();
49
+ // Phase 2: Case Law prompt
50
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '\u229b')} ${(0, logger_1.bold)('Phase 2')} \u2014 Case Law Engine (building precedence record)`);
51
+ console.log();
52
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '\u25b8')} Record a new rejection precedent:`);
53
+ (0, logger_1.log)(` ${(0, logger_1.c)('white', 'npx tribunal-kit case add')}`);
54
+ console.log();
55
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '\u25b8')} Search existing case law:`);
56
+ (0, logger_1.log)(` ${(0, logger_1.c)('white', 'npx tribunal-kit case search "your query"')}`);
57
+ console.log();
58
+ // Phase 3: Memory Distillation
59
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '\u229b')} ${(0, logger_1.bold)('Phase 3')} \u2014 Memory Distillation (storing project knowledge)`);
60
+ try {
61
+ const { _memoryStore } = require('./memory');
62
+ // Auto-extract SEMANTIC memories from project-idioms if it exists
63
+ const idiomsPath = path_1.default.join(agentDest, 'skills', 'project-idioms', 'SKILL.md');
64
+ let memoriesStored = 0;
65
+ if (fs_1.default.existsSync(idiomsPath)) {
66
+ const idiomsContent = fs_1.default.readFileSync(idiomsPath, 'utf8');
67
+ // Extract lines that look like project rules (lines starting with - or * that contain actionable content)
68
+ const ruleLines = idiomsContent.split('\n')
69
+ .filter(line => /^[\s]*[-*]\s+/.test(line) && line.trim().length > 20)
70
+ .map(line => line.replace(/^[\s]*[-*]\s+/, '').trim())
71
+ .slice(0, 10); // Cap at 10 to prevent bloat
72
+
73
+ for (const rule of ruleLines) {
74
+ try {
75
+ _memoryStore(agentDest, 'semantic', rule, ['project-idiom', 'auto-learned'], null);
76
+ memoriesStored++;
77
+ } catch {
78
+ // Skip duplicates or capacity errors silently
79
+ }
80
+ }
81
+ }
82
+ // Auto-extract PROCEDURAL memories from package.json scripts
83
+ const pkgPath = path_1.default.join(targetDir, 'package.json');
84
+ if (fs_1.default.existsSync(pkgPath)) {
85
+ try {
86
+ const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf8'));
87
+ if (pkg.scripts) {
88
+ const importantScripts = ['build', 'test', 'dev', 'start', 'deploy', 'lint'];
89
+ for (const key of importantScripts) {
90
+ if (pkg.scripts[key]) {
91
+ try {
92
+ _memoryStore(agentDest, 'procedural',
93
+ `Run \`${pkg.scripts[key]}\` to ${key} the project`,
94
+ ['build-script', key, 'auto-learned'], null);
95
+ memoriesStored++;
96
+ } catch {
97
+ // Skip
98
+ }
99
+ }
100
+ }
101
+ }
102
+ } catch {
103
+ // Unreadable package.json
104
+ }
105
+ }
106
+ if (memoriesStored > 0) {
107
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', '\u2714')} ${memoriesStored} memories auto-stored (semantic + procedural)`);
108
+ } else {
109
+ (0, logger_1.log)(` ${(0, logger_1.c)('gray', '\u25b8')} No new memories to distill (run again after committing changes)`);
110
+ }
111
+ } catch (e) {
112
+ (0, logger_1.log)(` ${(0, logger_1.c)('yellow', '\u26a0')} Memory distillation skipped: ${e.message || String(e)}`);
113
+ }
114
+ console.log();
115
+ (0, logger_1.log)(` ${(0, logger_1.c)('green', '\u2714')} ${(0, logger_1.bold)('Learn cycle complete.')} Your Tribunal grows smarter with every commit.`);
116
+ console.log();
117
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cmdMarathon = cmdMarathon;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const logger_1 = require("../utils/logger");
10
+ const helpers_1 = require("../utils/helpers");
11
+ async function cmdMarathon(flags, processArgs, quiet = false) {
12
+ const targetDir = flags.path ? path_1.default.resolve(flags.path) : process.cwd();
13
+ const agentDest = path_1.default.join(targetDir, '.agent');
14
+ if (!fs_1.default.existsSync(agentDest)) {
15
+ (0, logger_1.err)('.agent/ not found. Run: npx tribunal-kit init');
16
+ process.exit(1);
17
+ }
18
+ const args = processArgs.slice(3);
19
+ const argsStr = args.join(' ');
20
+ if (args.length === 0 || args[0] === 'help' || args[0] === '--help' || args[0] === '-h') {
21
+ (0, helpers_1.banner)(quiet);
22
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '╔' + '═'.repeat(60) + '╗')}`);
23
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '║')}\x1b[1m\x1b[97m Marathon — Long-Running Agent Harness \x1b[0m${(0, logger_1.c)('cyan', '║')}`);
24
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', '╚' + '═'.repeat(60) + '╝')}`);
25
+ console.log();
26
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'init'.padEnd(16))} ${(0, logger_1.c)('gray', 'Start a new marathon (init "spec")')}`);
27
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'status'.padEnd(16))} ${(0, logger_1.c)('gray', 'Show progress dashboard')}`);
28
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'next'.padEnd(16))} ${(0, logger_1.c)('gray', 'Show next unfinished feature')}`);
29
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'mark'.padEnd(16))} ${(0, logger_1.c)('gray', 'Mark feature pass/fail (mark <id> pass)')}`);
30
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'log'.padEnd(16))} ${(0, logger_1.c)('gray', 'Add a progress note')}`);
31
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'session-start'.padEnd(16))} ${(0, logger_1.c)('gray', 'Begin a new work session')}`);
32
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'session-end'.padEnd(16))} ${(0, logger_1.c)('gray', 'End session with summary')}`);
33
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'add-feature'.padEnd(16))} ${(0, logger_1.c)('gray', 'Add feature: "category" "desc" "step1" ...')}`);
34
+ (0, logger_1.log)(` ${(0, logger_1.c)('cyan', 'reset'.padEnd(16))} ${(0, logger_1.c)('gray', 'Archive and start fresh')}`);
35
+ console.log();
36
+ return;
37
+ }
38
+ const marathonScript = path_1.default.join(agentDest, 'scripts', 'marathon_harness.js');
39
+ try {
40
+ await (0, helpers_1.runShellAsync)(`node "${marathonScript}" ${argsStr}`, { stdio: 'inherit', cwd: targetDir });
41
+ }
42
+ catch {
43
+ process.exit(1);
44
+ }
45
+ }