tribunal-kit 7.0.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/config/claude.json +18 -0
- package/.agent/config/plugin.json +102 -0
- package/.agent/config/slash-commands.json +103 -0
- package/.agent/config/specialist-registry.json +415 -0
- package/.agent/config/system-prompt.md +191 -0
- package/.agent/history/architecture-graph.yaml +302 -3
- package/.agent/history/graph-cache.json +515 -45
- package/.agent/history/memory.db +0 -0
- package/.agent/history/snapshots/bin__adapter-install.js.json +13 -0
- package/.agent/history/snapshots/bin__global-store.js.json +15 -0
- package/.agent/history/snapshots/bin__mcp-server.js.json +19 -0
- package/.agent/history/snapshots/bin__proxy-server.js.json +20 -0
- package/.agent/history/snapshots/bin__spawn-agent.js.json +12 -0
- package/.agent/history/snapshots/bin__tk-proxy.js.json +21 -0
- package/.agent/history/snapshots/bin__tribunal-kit.js.json +9 -7
- package/.agent/history/snapshots/bin__wrapper.js.json +14 -0
- package/.agent/history/snapshots/eslint.config.js.json +1 -2
- package/.agent/history/snapshots/scripts__benchmark.js.json +14 -0
- package/.agent/history/snapshots/scripts__changelog.js.json +1 -2
- package/.agent/history/snapshots/scripts__fix-vbc.js.json +11 -0
- package/.agent/history/snapshots/scripts__stress_benchmark.js.json +15 -0
- package/.agent/history/snapshots/scripts__sync-version.js.json +1 -2
- package/.agent/history/snapshots/scripts__validate-payload.js.json +1 -2
- package/.agent/history/snapshots/scripts__visual_audit.js.json +11 -0
- package/.agent/history/snapshots/test__integration__bridges.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__graceful_degradation.test.js.json +12 -0
- package/.agent/history/snapshots/test__integration__init.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__minimal_change_pipeline.test.js.json +13 -0
- package/.agent/history/snapshots/test__integration__parallel_tribunal.test.js.json +12 -0
- package/.agent/history/snapshots/test__integration__routing.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__swarm_dispatcher.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__sync_status.test.js.json +13 -0
- package/.agent/history/snapshots/test__integration__wave2.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__wrapper.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__align.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__args.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__audit_release.test.js.json +16 -0
- package/.agent/history/snapshots/test__unit__case_law_manager.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__cicd_validator.test.js.json +12 -0
- package/.agent/history/snapshots/test__unit__compile.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__context_broker.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__contract_engine.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__copyDir.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__graph_tools.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__guardrail_engine.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__impact_classifier.test.js.json +12 -0
- package/.agent/history/snapshots/test__unit__init.test.js.json +14 -0
- package/.agent/history/snapshots/test__unit__inner_loop_validator.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__integrity_manifest.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__learn.test.js.json +11 -0
- package/.agent/history/snapshots/test__unit__marathon.test.js.json +22 -0
- package/.agent/history/snapshots/test__unit__mcp_server.test.js.json +16 -0
- package/.agent/history/snapshots/test__unit__memory.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__minimal_change.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__native.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__optimize.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__path_resolution.test.js.json +14 -0
- package/.agent/history/snapshots/test__unit__production_readiness_evidence.test.js.json +21 -0
- package/.agent/history/snapshots/test__unit__selfInstall.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__semver.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__skill_evolution.test.js.json +11 -0
- package/.agent/history/snapshots/test__unit__stress.test.js.json +15 -0
- package/.agent/history/snapshots/test__unit__swarm_dispatcher.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__utils.test.js.json +10 -0
- package/.agent/scripts/ast_context_loader.js +137 -0
- package/.agent/scripts/memory_engine.js +581 -0
- package/.agent/scripts/payload_schemas.js +146 -0
- package/.agent/scripts/prompt_compiler.js +59 -11
- package/.agent/scripts/swarm_dispatcher.js +295 -67
- package/.agent/scripts/token_budget_broker.js +117 -6
- package/.claude/CLAUDE.md +442 -0
- package/README.md +22 -12
- package/SECURITY.md +3 -3
- package/bin/adapter-install.js +240 -0
- package/bin/global-store.js +48 -0
- package/bin/mcp-server.js +568 -252
- package/bin/proxy-server.js +113 -0
- package/bin/spawn-agent.js +39 -0
- package/bin/tk-proxy.js +34 -0
- package/dist/commands/init.js +8 -51
- package/dist/commands/status.js +61 -36
- package/dist/commands/validate.js +22 -31
- package/dist/tui/banner.js +77 -0
- package/dist/tui/index.js +21 -0
- package/dist/tui/reviewer-grid.js +90 -0
- package/dist/tui/shimmer.js +91 -0
- package/dist/tui/theme.js +130 -0
- package/dist/tui/tree.js +93 -0
- package/dist/tui/wizard.js +148 -0
- package/dist/utils/helpers.js +5 -41
- package/package.json +27 -10
- package/scripts/build-graph.js +71 -0
- package/.agent/history/snapshots/migrate_refs.js.json +0 -11
- package/.agent/scripts/compile_router.py +0 -5
- package/.agent/scripts/migrate_skills_frontmatter.py +0 -5
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shimmering gradient text animation & zero-flicker Braille spinner.
|
|
5
|
+
* Mirrors the Brainless CSS shimmer effect in Node.js ANSI TrueColor.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { isTTY, hasColor, hasTrueColor, RGB, GLYPHS, color, bold } = require('./theme');
|
|
9
|
+
|
|
10
|
+
function renderShimmerText(text, frame) {
|
|
11
|
+
let out = '';
|
|
12
|
+
const numChars = text.length;
|
|
13
|
+
const wavePos = ((frame * 0.18) % (numChars + 4)) - 2;
|
|
14
|
+
|
|
15
|
+
for (let i = 0; i < numChars; i++) {
|
|
16
|
+
const dist = Math.abs(i - wavePos);
|
|
17
|
+
const intensity = Math.max(0, Math.min(1, 1.0 - dist / 3.0));
|
|
18
|
+
|
|
19
|
+
// Interpolate between FLAME #cd694a and bright CORAL #ffe4d6
|
|
20
|
+
const r = Math.floor(205 + intensity * 50);
|
|
21
|
+
const g = Math.floor(105 + intensity * 123);
|
|
22
|
+
const b = Math.floor(74 + intensity * 140);
|
|
23
|
+
|
|
24
|
+
out += `\x1b[38;2;${r};${g};${b}m\x1b[1m${text[i]}\x1b[0m`;
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class ShimmerSpinner {
|
|
30
|
+
constructor(verb, details = '') {
|
|
31
|
+
this.verb = verb;
|
|
32
|
+
this.details = details;
|
|
33
|
+
this.timer = null;
|
|
34
|
+
this.frame = 0;
|
|
35
|
+
this.startTime = Date.now();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
start() {
|
|
39
|
+
if (!isTTY || !hasColor) {
|
|
40
|
+
console.log(` · ${this.verb} (${this.details})`);
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const braille = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
45
|
+
|
|
46
|
+
// Hide cursor to prevent flicker
|
|
47
|
+
process.stderr.write('\x1b[?25l');
|
|
48
|
+
|
|
49
|
+
this.timer = setInterval(() => {
|
|
50
|
+
const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
51
|
+
const spinnerChar = braille[this.frame % braille.length];
|
|
52
|
+
|
|
53
|
+
const shimmerVerb = hasTrueColor
|
|
54
|
+
? renderShimmerText(this.verb, this.frame)
|
|
55
|
+
: bold(this.verb);
|
|
56
|
+
|
|
57
|
+
const dot = color(RGB.FLAME, '·');
|
|
58
|
+
const timerText = color(RGB.ZINC_500, `(${elapsed}s · ${this.details})`);
|
|
59
|
+
const spinColored = color(RGB.FLAME, spinnerChar);
|
|
60
|
+
|
|
61
|
+
process.stderr.write(`\r\x1b[2K ${dot} ${spinColored} ${shimmerVerb} ${timerText}`);
|
|
62
|
+
this.frame++;
|
|
63
|
+
}, 60);
|
|
64
|
+
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
finish(successMsg = null) {
|
|
69
|
+
if (this.timer) {
|
|
70
|
+
clearInterval(this.timer);
|
|
71
|
+
this.timer = null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (isTTY && hasColor) {
|
|
75
|
+
// Clear line and restore cursor
|
|
76
|
+
process.stderr.write('\r\x1b[2K\x1b[?25h');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (successMsg) {
|
|
80
|
+
const g = GLYPHS;
|
|
81
|
+
const check = color(RGB.EMERALD, g.success);
|
|
82
|
+
const boldMsg = bold(successMsg);
|
|
83
|
+
console.log(` ${check} ${color(RGB.WHITE, boldMsg)}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
ShimmerSpinner,
|
|
90
|
+
renderShimmerText,
|
|
91
|
+
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Terminal theme, TrueColor palette, and Unicode glyph tokens.
|
|
5
|
+
* Parity with Rust core TUI & Brainless (Claude Code / Codex / Grok) design system.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const isTTY = Boolean(process.stdout && process.stdout.isTTY);
|
|
9
|
+
const noColor = Boolean(process.env.NO_COLOR || process.env.CI);
|
|
10
|
+
const colorTerm = (process.env.COLORTERM || '').toLowerCase();
|
|
11
|
+
const term = (process.env.TERM || '').toLowerCase();
|
|
12
|
+
|
|
13
|
+
const hasColor = !noColor && (isTTY || Boolean(process.env.FORCE_COLOR));
|
|
14
|
+
const hasTrueColor = hasColor && (
|
|
15
|
+
colorTerm === 'truecolor' ||
|
|
16
|
+
colorTerm === '24bit' ||
|
|
17
|
+
term.includes('256color') ||
|
|
18
|
+
term.includes('xterm') ||
|
|
19
|
+
process.platform === 'win32'
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const isUtf8 = !noColor && (
|
|
23
|
+
Boolean(process.env.WT_SESSION) ||
|
|
24
|
+
Boolean(process.env.TERM_PROGRAM) ||
|
|
25
|
+
(process.env.LANG || '').toLowerCase().includes('utf') ||
|
|
26
|
+
process.platform !== 'win32'
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const RGB = {
|
|
30
|
+
SLATE_900: [13, 13, 15],
|
|
31
|
+
SLATE_800: [30, 30, 34],
|
|
32
|
+
SLATE_700: [47, 47, 51],
|
|
33
|
+
ZINC_600: [86, 95, 137],
|
|
34
|
+
ZINC_500: [122, 122, 122],
|
|
35
|
+
ZINC_400: [161, 161, 170],
|
|
36
|
+
ZINC_200: [228, 228, 231],
|
|
37
|
+
WHITE: [237, 237, 237],
|
|
38
|
+
|
|
39
|
+
// Accents (Flame / Amber / Coral)
|
|
40
|
+
FLAME: [205, 105, 74], // #cd694a
|
|
41
|
+
CORAL_BRIGHT: [231, 148, 117], // #e79475
|
|
42
|
+
AMBER: [245, 158, 11], // #f59e0b
|
|
43
|
+
GOLD: [255, 215, 0], // #ffd700
|
|
44
|
+
|
|
45
|
+
// Status
|
|
46
|
+
EMERALD: [78, 169, 111], // #4ea96f
|
|
47
|
+
CYAN: [125, 207, 255], // #7dcfff
|
|
48
|
+
ROSE: [244, 63, 94], // #f43f5e
|
|
49
|
+
PURPLE: [177, 167, 255], // #b1a7ff
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const UTF8_GLYPHS = {
|
|
53
|
+
bullet: '⏺',
|
|
54
|
+
success: '✔',
|
|
55
|
+
failure: '✖',
|
|
56
|
+
warning: '⚠',
|
|
57
|
+
branch: '⎿',
|
|
58
|
+
treeMid: '├──',
|
|
59
|
+
treeEnd: '└──',
|
|
60
|
+
chevron: '❯',
|
|
61
|
+
diamond: '◆',
|
|
62
|
+
boxTl: '╭',
|
|
63
|
+
boxTr: '╮',
|
|
64
|
+
boxBl: '╰',
|
|
65
|
+
boxBr: '╯',
|
|
66
|
+
boxH: '─',
|
|
67
|
+
boxV: '│',
|
|
68
|
+
dot: '·',
|
|
69
|
+
check: '[✔]',
|
|
70
|
+
uncheck: '[ ]',
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const ASCII_GLYPHS = {
|
|
74
|
+
bullet: '*',
|
|
75
|
+
success: '+',
|
|
76
|
+
failure: 'x',
|
|
77
|
+
warning: '!',
|
|
78
|
+
branch: '\\-',
|
|
79
|
+
treeMid: '|--',
|
|
80
|
+
treeEnd: '`--',
|
|
81
|
+
chevron: '>',
|
|
82
|
+
diamond: '*',
|
|
83
|
+
boxTl: '+',
|
|
84
|
+
boxTr: '+',
|
|
85
|
+
boxBl: '+',
|
|
86
|
+
boxBr: '+',
|
|
87
|
+
boxH: '-',
|
|
88
|
+
boxV: '|',
|
|
89
|
+
dot: '.',
|
|
90
|
+
check: '[x]',
|
|
91
|
+
uncheck: '[ ]',
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const GLYPHS = isUtf8 ? UTF8_GLYPHS : ASCII_GLYPHS;
|
|
95
|
+
|
|
96
|
+
function color(rgb, text) {
|
|
97
|
+
if (!hasColor) return String(text);
|
|
98
|
+
if (hasTrueColor && Array.isArray(rgb)) {
|
|
99
|
+
return `\x1b[38;2;${rgb[0]};${rgb[1]};${rgb[2]}m${text}\x1b[0m`;
|
|
100
|
+
}
|
|
101
|
+
// Fallback ANSI 16-color
|
|
102
|
+
return `\x1b[96m${text}\x1b[0m`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function bold(text) {
|
|
106
|
+
if (!hasColor) return String(text);
|
|
107
|
+
return `\x1b[1m${text}\x1b[0m`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function dim(text) {
|
|
111
|
+
if (!hasColor) return String(text);
|
|
112
|
+
return `\x1b[90m${text}\x1b[0m`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function getColumns() {
|
|
116
|
+
return (process.stdout && process.stdout.columns) || 80;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
module.exports = {
|
|
120
|
+
isTTY,
|
|
121
|
+
hasColor,
|
|
122
|
+
hasTrueColor,
|
|
123
|
+
isUtf8,
|
|
124
|
+
RGB,
|
|
125
|
+
GLYPHS,
|
|
126
|
+
color,
|
|
127
|
+
bold,
|
|
128
|
+
dim,
|
|
129
|
+
getColumns,
|
|
130
|
+
};
|
package/dist/tui/tree.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hierarchical action tree nodes (⏺ / ⎿) matching the Brainless agent specification.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { isTTY, RGB, GLYPHS, color, bold } = require('./theme');
|
|
8
|
+
|
|
9
|
+
class ActionTree {
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
this.staggerMs = isTTY ? (options.staggerMs ?? 15) : 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
sleep(ms) {
|
|
15
|
+
if (ms <= 0) return Promise.resolve();
|
|
16
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async action(verb, target = null) {
|
|
20
|
+
const g = GLYPHS;
|
|
21
|
+
const bullet = color(RGB.EMERALD, g.bullet);
|
|
22
|
+
const coloredVerb = color(RGB.WHITE, bold(verb));
|
|
23
|
+
|
|
24
|
+
if (target) {
|
|
25
|
+
const openParen = color(RGB.ZINC_600, '(');
|
|
26
|
+
const coloredTarget = color(RGB.CYAN, target);
|
|
27
|
+
const closeParen = color(RGB.ZINC_600, ')');
|
|
28
|
+
console.log(` ${bullet} ${coloredVerb}${openParen}${coloredTarget}${closeParen}`);
|
|
29
|
+
} else {
|
|
30
|
+
console.log(` ${bullet} ${coloredVerb}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (this.staggerMs > 0) {
|
|
34
|
+
await this.sleep(this.staggerMs);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async branch(message) {
|
|
39
|
+
const g = GLYPHS;
|
|
40
|
+
const branchGlyph = color(RGB.ZINC_600, g.branch);
|
|
41
|
+
const coloredMsg = color(RGB.ZINC_400, message);
|
|
42
|
+
console.log(` ${branchGlyph} ${coloredMsg}`);
|
|
43
|
+
|
|
44
|
+
if (this.staggerMs > 0) {
|
|
45
|
+
await this.sleep(this.staggerMs);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async itemSuccess(title, detail = null) {
|
|
50
|
+
const g = GLYPHS;
|
|
51
|
+
const check = color(RGB.EMERALD, g.success);
|
|
52
|
+
const coloredTitle = color(RGB.WHITE, title);
|
|
53
|
+
|
|
54
|
+
if (detail) {
|
|
55
|
+
const coloredDetail = color(RGB.ZINC_500, detail);
|
|
56
|
+
console.log(` ${check} ${coloredTitle} ${coloredDetail}`);
|
|
57
|
+
} else {
|
|
58
|
+
console.log(` ${check} ${coloredTitle}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (this.staggerMs > 0) {
|
|
62
|
+
await this.sleep(this.staggerMs);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
itemWarning(message) {
|
|
67
|
+
const g = GLYPHS;
|
|
68
|
+
const warn = color(RGB.AMBER, g.warning);
|
|
69
|
+
const coloredMsg = color(RGB.AMBER, message);
|
|
70
|
+
console.log(` ${warn} ${coloredMsg}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
itemError(message) {
|
|
74
|
+
const g = GLYPHS;
|
|
75
|
+
const err = color(RGB.ROSE, g.failure);
|
|
76
|
+
const coloredMsg = color(RGB.ROSE, message);
|
|
77
|
+
console.log(` ${err} ${coloredMsg}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
complete(message) {
|
|
81
|
+
const g = GLYPHS;
|
|
82
|
+
const check = color(RGB.EMERALD, g.success);
|
|
83
|
+
const boldMsg = bold(message);
|
|
84
|
+
const colored = color(RGB.WHITE, boldMsg);
|
|
85
|
+
console.log();
|
|
86
|
+
console.log(` ${check} ${colored}`);
|
|
87
|
+
console.log();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = {
|
|
92
|
+
ActionTree,
|
|
93
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Zero-dependency interactive terminal multi-select wizard.
|
|
5
|
+
* Handles keyboard navigation, space-to-toggle, and non-TTY fallback.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const readline = require('readline');
|
|
9
|
+
const { isTTY, hasColor, RGB, GLYPHS, color, bold } = require('./theme');
|
|
10
|
+
|
|
11
|
+
class WizardPrompt {
|
|
12
|
+
displaySummary(question, options) {
|
|
13
|
+
const g = GLYPHS;
|
|
14
|
+
const prefix = color(RGB.AMBER, '?');
|
|
15
|
+
const boldQ = bold(question);
|
|
16
|
+
console.log(` ${prefix} ${boldQ}`);
|
|
17
|
+
|
|
18
|
+
for (const opt of options) {
|
|
19
|
+
const check = opt.selected
|
|
20
|
+
? color(RGB.EMERALD, g.check)
|
|
21
|
+
: color(RGB.ZINC_600, g.uncheck);
|
|
22
|
+
|
|
23
|
+
const labelColored = opt.selected
|
|
24
|
+
? color(RGB.WHITE, opt.label)
|
|
25
|
+
: color(RGB.ZINC_500, opt.label);
|
|
26
|
+
|
|
27
|
+
const detailColored = color(RGB.ZINC_600, opt.detail || '');
|
|
28
|
+
|
|
29
|
+
console.log(` ${check} ${labelColored} ${detailColored}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const hint = '[Space] Toggle · [Enter] Confirm · [A] Select All';
|
|
33
|
+
console.log(` ${color(RGB.ZINC_600, hint)}`);
|
|
34
|
+
console.log();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async selectMultiple(question, initialOptions) {
|
|
38
|
+
if (!isTTY || !process.stdin.isTTY) {
|
|
39
|
+
this.displaySummary(question, initialOptions);
|
|
40
|
+
return initialOptions;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const options = initialOptions.map(opt => ({ ...opt }));
|
|
44
|
+
let cursor = 0;
|
|
45
|
+
const g = GLYPHS;
|
|
46
|
+
|
|
47
|
+
return new Promise(resolve => {
|
|
48
|
+
readline.emitKeypressEvents(process.stdin);
|
|
49
|
+
if (process.stdin.isTTY) {
|
|
50
|
+
process.stdin.setRawMode(true);
|
|
51
|
+
}
|
|
52
|
+
process.stdin.resume();
|
|
53
|
+
|
|
54
|
+
// Hide cursor
|
|
55
|
+
process.stdout.write('\x1b[?25l');
|
|
56
|
+
|
|
57
|
+
const render = (isFinal = false) => {
|
|
58
|
+
// Move back up lines if not initial render
|
|
59
|
+
const totalLines = options.length + 3;
|
|
60
|
+
|
|
61
|
+
let out = '';
|
|
62
|
+
const prefix = color(RGB.AMBER, '?');
|
|
63
|
+
out += ` ${prefix} ${bold(question)}\n`;
|
|
64
|
+
|
|
65
|
+
options.forEach((opt, idx) => {
|
|
66
|
+
const isCursor = idx === cursor;
|
|
67
|
+
const pointer = isCursor ? color(RGB.FLAME, g.chevron) : ' ';
|
|
68
|
+
const check = opt.selected
|
|
69
|
+
? color(RGB.EMERALD, g.check)
|
|
70
|
+
: color(RGB.ZINC_600, g.uncheck);
|
|
71
|
+
|
|
72
|
+
const labelColored = opt.selected
|
|
73
|
+
? color(RGB.WHITE, bold(opt.label))
|
|
74
|
+
: color(RGB.ZINC_400, opt.label);
|
|
75
|
+
|
|
76
|
+
const detailColored = color(RGB.ZINC_600, opt.detail || '');
|
|
77
|
+
out += ` ${pointer} ${check} ${labelColored} ${detailColored}\n`;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (isFinal) {
|
|
81
|
+
out += ` ${color(RGB.EMERALD, '✔ Configuration selected.')}\n`;
|
|
82
|
+
} else {
|
|
83
|
+
const hint = '[Space] Toggle · [Enter] Confirm · [A] All · [↑/↓] Move';
|
|
84
|
+
out += ` ${color(RGB.ZINC_600, hint)}\n`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { out, totalLines };
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
let renderedOnce = false;
|
|
91
|
+
|
|
92
|
+
const draw = (isFinal = false) => {
|
|
93
|
+
const { out } = render(isFinal);
|
|
94
|
+
if (renderedOnce) {
|
|
95
|
+
// Clear and rewrite lines
|
|
96
|
+
process.stdout.write(`\x1b[${options.length + 2}A\r`);
|
|
97
|
+
}
|
|
98
|
+
process.stdout.write(out);
|
|
99
|
+
renderedOnce = true;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
draw();
|
|
103
|
+
|
|
104
|
+
const onKeypress = (str, key) => {
|
|
105
|
+
if (!key) return;
|
|
106
|
+
|
|
107
|
+
if (key.ctrl && key.name === 'c') {
|
|
108
|
+
cleanup();
|
|
109
|
+
process.exit(130);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (key.name === 'up' || key.name === 'k') {
|
|
113
|
+
cursor = (cursor - 1 + options.length) % options.length;
|
|
114
|
+
draw();
|
|
115
|
+
} else if (key.name === 'down' || key.name === 'j') {
|
|
116
|
+
cursor = (cursor + 1) % options.length;
|
|
117
|
+
draw();
|
|
118
|
+
} else if (key.name === 'space') {
|
|
119
|
+
options[cursor].selected = !options[cursor].selected;
|
|
120
|
+
draw();
|
|
121
|
+
} else if (str === 'a' || str === 'A') {
|
|
122
|
+
const allSelected = options.every(o => o.selected);
|
|
123
|
+
options.forEach(o => (o.selected = !allSelected));
|
|
124
|
+
draw();
|
|
125
|
+
} else if (key.name === 'return' || key.name === 'enter') {
|
|
126
|
+
cleanup();
|
|
127
|
+
draw(true);
|
|
128
|
+
resolve(options);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const cleanup = () => {
|
|
133
|
+
process.stdin.removeListener('keypress', onKeypress);
|
|
134
|
+
if (process.stdin.isTTY) {
|
|
135
|
+
process.stdin.setRawMode(false);
|
|
136
|
+
}
|
|
137
|
+
process.stdin.pause();
|
|
138
|
+
process.stdout.write('\x1b[?25h'); // restore cursor
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
process.stdin.on('keypress', onKeypress);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = {
|
|
147
|
+
WizardPrompt,
|
|
148
|
+
};
|
package/dist/utils/helpers.js
CHANGED
|
@@ -43,47 +43,11 @@ function getKitAgent() {
|
|
|
43
43
|
}
|
|
44
44
|
return agentDir;
|
|
45
45
|
}
|
|
46
|
+
const { renderBanner } = require('../tui/banner');
|
|
47
|
+
|
|
46
48
|
function banner(quiet) {
|
|
47
|
-
if (quiet)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const art = String.raw `
|
|
51
|
-
████████╗██████╗ ██╗██████╗ ██╗ ██╗███╗ ██╗ █████╗ ██╗ ██╗ ██╗██╗████████╗
|
|
52
|
-
╚══██╔══╝██╔══██╗██║██╔══██╗██║ ██║████╗ ██║██╔══██╗██║ ██║ ██╔╝██║╚══██╔══╝
|
|
53
|
-
██║ ██████╔╝██║██████╔╝██║ ██║██╔██╗ ██║███████║██║█████╗█████╔╝ ██║ ██║
|
|
54
|
-
██║ ██╔══██╗██║██╔══██╗██║ ██║██║╚██╗██║██╔══██║██║╚════╝██╔═██╗ ██║ ██║
|
|
55
|
-
██║ ██║ ██║██║██████╔╝╚██████╔╝██║ ╚████║██║ ██║███████╗ ██║ ██╗██║ ██║
|
|
56
|
-
╚═╝ ╚═╝ ╚═╝╚═╝╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ `.split('\n').filter(Boolean);
|
|
57
|
-
console.log();
|
|
58
|
-
for (const line of art) {
|
|
59
|
-
let gradientLine = ' \x1b[1m';
|
|
60
|
-
const len = line.length;
|
|
61
|
-
for (let i = 0; i < len; i++) {
|
|
62
|
-
const char = line[i];
|
|
63
|
-
if (char === ' ') {
|
|
64
|
-
gradientLine += ' ';
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
// Horizontal gradient: flame red (left) to coral/orange (right)
|
|
68
|
-
const ratio = i / len;
|
|
69
|
-
const r = 255;
|
|
70
|
-
const g = Math.floor(30 + ratio * 100);
|
|
71
|
-
const b = Math.floor(60 - ratio * 40);
|
|
72
|
-
gradientLine += `\x1b[38;2;${r};${g};${b}m${char}`;
|
|
73
|
-
}
|
|
74
|
-
gradientLine += '\x1b[0m';
|
|
75
|
-
(0, logger_1.log)(gradientLine);
|
|
76
|
-
}
|
|
77
|
-
console.log();
|
|
78
|
-
// Subtitle strip
|
|
79
|
-
const W = 84;
|
|
80
|
-
const plainSub = '🛡️ ANTI-HALLUCINATION AGENT SYSTEM';
|
|
81
|
-
const coloredSub = `${(0, logger_1.bold)((0, logger_1.c)('white', '🛡️ ANTI-HALLUCINATION AGENT SYSTEM'))}`;
|
|
82
|
-
const sp = Math.max(0, W - plainSub.length);
|
|
83
|
-
const centred = ' '.repeat(Math.floor(sp / 2)) + coloredSub + ' '.repeat(Math.ceil(sp / 2));
|
|
84
|
-
(0, logger_1.log)(` ${(0, logger_1.c)('gray', `✦ ${'━'.repeat(W - 6)} ✦`)}`);
|
|
85
|
-
(0, logger_1.log)(` ${centred}`);
|
|
86
|
-
(0, logger_1.log)(` ${(0, logger_1.c)('gray', `✦ ${'━'.repeat(W - 6)} ✦`)}`);
|
|
87
|
-
console.log();
|
|
49
|
+
if (quiet) return;
|
|
50
|
+
const PKG = require('../../package.json');
|
|
51
|
+
renderBanner(PKG.version, quiet);
|
|
88
52
|
}
|
|
89
53
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tribunal-kit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "Your AI writes code that doesn't exist. Tribunal Kit stops it. The governance layer for AI coding agents — 52 specialists, 28 parallel reviewers, 183 skills, Rust core, MCP server. Works with Cursor, VSCode, Windsurf, Claude Code, and Aider.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -43,13 +43,19 @@
|
|
|
43
43
|
"ai-code-reviewer",
|
|
44
44
|
"hallucination-mitigation",
|
|
45
45
|
"autonomous-workflows",
|
|
46
|
-
"code-correctness"
|
|
46
|
+
"code-correctness",
|
|
47
|
+
"claude-code-plugin",
|
|
48
|
+
"claude-plugin"
|
|
47
49
|
],
|
|
48
50
|
"homepage": "https://github.com/Harmitx7/tribunal-kit",
|
|
49
51
|
"repository": {
|
|
50
52
|
"type": "git",
|
|
51
53
|
"url": "git+https://github.com/Harmitx7/tribunal-kit.git"
|
|
52
54
|
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/Harmitx7/tribunal-kit/issues"
|
|
57
|
+
},
|
|
58
|
+
"author": "Harmitx7",
|
|
53
59
|
"license": "MIT",
|
|
54
60
|
"types": "dist/index.d.ts",
|
|
55
61
|
"main": "dist/cli.js",
|
|
@@ -63,18 +69,25 @@
|
|
|
63
69
|
},
|
|
64
70
|
"bin": {
|
|
65
71
|
"tribunal-kit": "bin/wrapper.js",
|
|
66
|
-
"tk": "bin/wrapper.js"
|
|
72
|
+
"tk": "bin/wrapper.js",
|
|
73
|
+
"tk-proxy": "bin/tk-proxy.js",
|
|
74
|
+
"tk-adapt": "bin/adapter-install.js"
|
|
67
75
|
},
|
|
68
76
|
"files": [
|
|
69
77
|
"bin/",
|
|
70
78
|
"dist/",
|
|
71
79
|
"scripts/",
|
|
72
80
|
".agent/",
|
|
81
|
+
".claude/CLAUDE.md",
|
|
73
82
|
"README.md",
|
|
74
83
|
"LICENSE",
|
|
75
84
|
"SECURITY.md",
|
|
76
85
|
"CONTRIBUTING.md",
|
|
77
|
-
"mcp_config.json"
|
|
86
|
+
"mcp_config.json",
|
|
87
|
+
".agent/config/plugin.json",
|
|
88
|
+
".agent/config/system-prompt.md",
|
|
89
|
+
".agent/config/slash-commands.json",
|
|
90
|
+
".agent/config/specialist-registry.json"
|
|
78
91
|
],
|
|
79
92
|
"engines": {
|
|
80
93
|
"node": ">=18.0.0"
|
|
@@ -107,12 +120,12 @@
|
|
|
107
120
|
"typescript": "^5.4.5"
|
|
108
121
|
},
|
|
109
122
|
"optionalDependencies": {
|
|
110
|
-
"@tribunal-kit/core-darwin-arm64": "^
|
|
111
|
-
"@tribunal-kit/core-darwin-x64": "^
|
|
112
|
-
"@tribunal-kit/core-linux-arm64": "^
|
|
113
|
-
"@tribunal-kit/core-linux-x64": "^
|
|
114
|
-
"@tribunal-kit/core-win32-arm64": "^
|
|
115
|
-
"@tribunal-kit/core-win32-x64": "^
|
|
123
|
+
"@tribunal-kit/core-darwin-arm64": "^8.0.0",
|
|
124
|
+
"@tribunal-kit/core-darwin-x64": "^8.0.0",
|
|
125
|
+
"@tribunal-kit/core-linux-arm64": "^8.0.0",
|
|
126
|
+
"@tribunal-kit/core-linux-x64": "^8.0.0",
|
|
127
|
+
"@tribunal-kit/core-win32-arm64": "^8.0.0",
|
|
128
|
+
"@tribunal-kit/core-win32-x64": "^8.0.0"
|
|
116
129
|
},
|
|
117
130
|
"jest": {
|
|
118
131
|
"testMatch": [
|
|
@@ -125,5 +138,9 @@
|
|
|
125
138
|
".agent/scripts/**/*.js",
|
|
126
139
|
"dist/**/*.js"
|
|
127
140
|
]
|
|
141
|
+
},
|
|
142
|
+
"dependencies": {
|
|
143
|
+
"better-sqlite3": "^13.0.3",
|
|
144
|
+
"zod": "^4.5.4"
|
|
128
145
|
}
|
|
129
146
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
|
|
6
|
+
async function buildSemanticGraph(targetPath = process.cwd()) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
// Determine platform-specific binary
|
|
9
|
+
const platform = os.platform();
|
|
10
|
+
const _arch = os.arch();
|
|
11
|
+
|
|
12
|
+
let binaryName = 'tribunal-core';
|
|
13
|
+
if (platform === 'win32') binaryName += '.exe';
|
|
14
|
+
|
|
15
|
+
// For development, try to use the locally compiled debug/release binary
|
|
16
|
+
let binaryPath = path.join(__dirname, '..', 'target', 'release', binaryName);
|
|
17
|
+
if (!fs.existsSync(binaryPath)) {
|
|
18
|
+
binaryPath = path.join(__dirname, '..', 'target', 'debug', binaryName);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!fs.existsSync(binaryPath)) {
|
|
22
|
+
console.error("Tribunal Core binary not found. Please run 'npm run build:core'.");
|
|
23
|
+
return reject(new Error('Tribunal Core binary not found.'));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`Building Semantic Context Graph for ${targetPath}...`);
|
|
27
|
+
|
|
28
|
+
const coreProcess = spawn(binaryPath, ['graph', targetPath], {
|
|
29
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
let stdoutData = '';
|
|
33
|
+
let stderrData = '';
|
|
34
|
+
|
|
35
|
+
coreProcess.stdout.on('data', data => {
|
|
36
|
+
stdoutData += data.toString();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
coreProcess.stderr.on('data', data => {
|
|
40
|
+
stderrData += data.toString();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
coreProcess.on('close', code => {
|
|
44
|
+
if (code !== 0) {
|
|
45
|
+
console.error(`Graph generation failed with code ${code}`);
|
|
46
|
+
console.error(stderrData);
|
|
47
|
+
return reject(new Error(`Graph generation failed: ${stderrData}`));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const result = JSON.parse(stdoutData.trim());
|
|
52
|
+
console.log(`Graph built successfully: ${result.nodes} nodes parsed.`);
|
|
53
|
+
console.log(`Graph saved to: ${result.graph_path}`);
|
|
54
|
+
resolve(result);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
console.error('Failed to parse core engine output:', stdoutData);
|
|
57
|
+
reject(err);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Allow running directly from CLI
|
|
64
|
+
if (require.main === module) {
|
|
65
|
+
const targetDir = process.argv[2] || process.cwd();
|
|
66
|
+
buildSemanticGraph(targetDir).catch(_err => {
|
|
67
|
+
process.exit(1);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = { buildSemanticGraph };
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"file": "migrate_refs.js",
|
|
3
|
-
"hash": "35b39052ff45b0b768fced3417c6245d9637ac18",
|
|
4
|
-
"riskScore": "Low",
|
|
5
|
-
"blastRadius": 0,
|
|
6
|
-
"imports": {
|
|
7
|
-
"fs": []
|
|
8
|
-
},
|
|
9
|
-
"dependents": [],
|
|
10
|
-
"content": "const fs = require('fs');\r\n\r\nconst filesToUpdate = [\r\n \".agent/workflows/swarm.md\",\r\n \".agent/workflows/session.md\",\r\n \".agent/rules/GEMINI.md\",\r\n \".agent/ARCHITECTURE.md\",\r\n \".agent/agents/swarm-worker-contracts.md\",\r\n \"AGENT_FLOW.md\",\r\n \"CHANGELOG.md\"\r\n];\r\n\r\nlet totalChanges = 0;\r\n\r\nfor (const filepath of filesToUpdate) {\r\n if (!fs.existsSync(filepath)) continue;\r\n let content = fs.readFileSync(filepath, 'utf8');\r\n \r\n // Explicit python calls\r\n content = content.replace(/python \\.agent\\/scripts\\/swarm_dispatcher\\.py/g, 'node .agent/scripts/swarm_dispatcher.js');\r\n content = content.replace(/python \\.agent\\/scripts\\/session_manager\\.py/g, 'node .agent/scripts/session_manager.js');\r\n content = content.replace(/python \\.agent\\/scripts\\/minify_context\\.py/g, 'node .agent/scripts/minify_context.js');\r\n content = content.replace(/python \\.agent\\/scripts\\/test_swarm_dispatcher\\.py/g, 'npx jest test/integration/swarm_dispatcher.test.js');\r\n \r\n // General filename references\r\n content = content.replace(/swarm_dispatcher\\.py/g, 'swarm_dispatcher.js');\r\n content = content.replace(/session_manager\\.py/g, 'session_manager.js');\r\n content = content.replace(/minify_context\\.py/g, 'minify_context.js');\r\n content = content.replace(/test_swarm_dispatcher\\.py/g, 'swarm_dispatcher.test.js');\r\n\r\n fs.writeFileSync(filepath, content, 'utf8');\r\n totalChanges++;\r\n}\r\nconsole.log(`Updated ${totalChanges} files.`);\r\n"
|
|
11
|
-
}
|