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.
- package/.agent/ARCHITECTURE.md +6 -7
- package/.agent/agents/frontend-reviewer.md +13 -0
- package/.agent/agents/frontend-specialist.md +14 -0
- package/.agent/agents/logic-reviewer.md +11 -0
- package/.agent/agents/orchestrator.md +15 -0
- package/.agent/agents/security-auditor.md +13 -0
- package/.agent/agents/ui-ux-auditor.md +7 -31
- package/.agent/history/memory/.memory.idx +766 -0
- package/.agent/history/memory/MEMORY.md +62 -0
- package/.agent/routing_index.json +694 -714
- package/.agent/rules/GEMINI.md +58 -8
- package/.agent/scripts/_colors.js +131 -89
- package/.agent/scripts/_utils.js +163 -128
- package/.agent/scripts/auto_preview.js +207 -197
- package/.agent/scripts/bundle_analyzer.js +227 -192
- package/.agent/scripts/case_law_manager.js +991 -689
- package/.agent/scripts/checklist.js +233 -190
- package/.agent/scripts/context_broker.js +930 -605
- package/.agent/scripts/dependency_analyzer.js +275 -184
- package/.agent/scripts/graph_builder.js +412 -341
- package/.agent/scripts/graph_visualizer.js +392 -390
- package/.agent/scripts/graph_zoom.js +198 -156
- package/.agent/scripts/inner_loop_validator.js +523 -445
- package/.agent/scripts/lint_runner.js +199 -157
- package/.agent/scripts/marathon_harness.js +819 -661
- package/.agent/scripts/minify_context.js +115 -100
- package/.agent/scripts/mutation_runner.js +321 -280
- package/.agent/scripts/prompt_compiler.js +62 -42
- package/.agent/scripts/schema_validator.js +373 -280
- package/.agent/scripts/security_scan.js +333 -190
- package/.agent/scripts/session_manager.js +306 -270
- package/.agent/scripts/skill_evolution.js +810 -637
- package/.agent/scripts/skill_integrator.js +327 -307
- package/.agent/scripts/strengthen_skills.js +203 -193
- package/.agent/scripts/swarm_dispatcher.js +558 -457
- package/.agent/scripts/test_runner.js +178 -152
- package/.agent/scripts/verify_all.js +200 -168
- package/.agent/skills/fabel-protocol/SKILL.md +235 -0
- package/.agent/skills/thinking-protocol/SKILL.md +27 -0
- package/.agent/workflows/generate.md +1 -1
- package/.agent/workflows/tribunal-speed.md +1 -1
- package/README.md +61 -47
- package/bin/mcp-server.js +476 -121
- package/bin/tribunal-kit.js +1245 -987
- package/bin/wrapper.js +104 -73
- package/dist/cli.js +265 -0
- package/dist/commands/case.js +71 -0
- package/dist/commands/compile.js +84 -0
- package/dist/commands/context.js +66 -0
- package/dist/commands/graph.js +38 -0
- package/dist/commands/hook.js +28 -0
- package/dist/commands/init.js +339 -0
- package/dist/commands/learn.js +117 -0
- package/dist/commands/marathon.js +45 -0
- package/dist/commands/memory.js +456 -0
- package/dist/commands/mutate.js +30 -0
- package/dist/commands/status.js +35 -0
- package/dist/commands/sync.js +25 -0
- package/dist/commands/uninstall.js +42 -0
- package/dist/commands/update.js +37 -0
- package/dist/mcp/server.js +142 -0
- package/dist/types.js +8 -0
- package/dist/utils/fs.js +96 -0
- package/dist/utils/hasher.js +142 -0
- package/dist/utils/helpers.js +68 -0
- package/dist/utils/logger.js +54 -0
- package/dist/utils/version.js +150 -0
- package/package.json +3 -2
- package/scripts/benchmark.js +197 -0
- package/scripts/changelog.js +196 -168
- package/scripts/sync-version.js +94 -81
- 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
|
+
}
|