tribunal-kit 1.0.0 → 2.4.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/.shared/ui-ux-pro-max/README.md +3 -3
- package/.agent/ARCHITECTURE.md +205 -10
- package/.agent/GEMINI.md +37 -7
- package/.agent/agents/accessibility-reviewer.md +134 -0
- package/.agent/agents/ai-code-reviewer.md +129 -0
- package/.agent/agents/frontend-specialist.md +3 -0
- package/.agent/agents/game-developer.md +21 -21
- package/.agent/agents/logic-reviewer.md +12 -0
- package/.agent/agents/mobile-reviewer.md +79 -0
- package/.agent/agents/orchestrator.md +56 -26
- package/.agent/agents/performance-reviewer.md +36 -0
- package/.agent/agents/supervisor-agent.md +156 -0
- package/.agent/agents/swarm-worker-contracts.md +166 -0
- package/.agent/agents/swarm-worker-registry.md +92 -0
- package/.agent/rules/GEMINI.md +134 -5
- package/.agent/scripts/bundle_analyzer.py +259 -0
- package/.agent/scripts/dependency_analyzer.py +247 -0
- package/.agent/scripts/lint_runner.py +188 -0
- package/.agent/scripts/patch_skills_meta.py +177 -0
- package/.agent/scripts/patch_skills_output.py +285 -0
- package/.agent/scripts/schema_validator.py +279 -0
- package/.agent/scripts/security_scan.py +224 -0
- package/.agent/scripts/session_manager.py +144 -3
- package/.agent/scripts/skill_integrator.py +234 -0
- package/.agent/scripts/strengthen_skills.py +220 -0
- package/.agent/scripts/swarm_dispatcher.py +317 -0
- package/.agent/scripts/test_runner.py +192 -0
- package/.agent/scripts/test_swarm_dispatcher.py +163 -0
- package/.agent/skills/agent-organizer/SKILL.md +132 -0
- package/.agent/skills/agentic-patterns/SKILL.md +335 -0
- package/.agent/skills/api-patterns/SKILL.md +226 -50
- package/.agent/skills/app-builder/SKILL.md +215 -52
- package/.agent/skills/architecture/SKILL.md +176 -31
- package/.agent/skills/bash-linux/SKILL.md +150 -134
- package/.agent/skills/behavioral-modes/SKILL.md +152 -160
- package/.agent/skills/brainstorming/SKILL.md +148 -101
- package/.agent/skills/brainstorming/dynamic-questioning.md +10 -0
- package/.agent/skills/clean-code/SKILL.md +139 -134
- package/.agent/skills/code-review-checklist/SKILL.md +177 -80
- package/.agent/skills/config-validator/SKILL.md +165 -0
- package/.agent/skills/csharp-developer/SKILL.md +107 -0
- package/.agent/skills/database-design/SKILL.md +252 -29
- package/.agent/skills/deployment-procedures/SKILL.md +122 -175
- package/.agent/skills/devops-engineer/SKILL.md +134 -0
- package/.agent/skills/devops-incident-responder/SKILL.md +98 -0
- package/.agent/skills/documentation-templates/SKILL.md +175 -121
- package/.agent/skills/dotnet-core-expert/SKILL.md +103 -0
- package/.agent/skills/edge-computing/SKILL.md +213 -0
- package/.agent/skills/frontend-design/SKILL.md +76 -0
- package/.agent/skills/frontend-design/color-system.md +18 -0
- package/.agent/skills/frontend-design/typography-system.md +18 -0
- package/.agent/skills/game-development/SKILL.md +69 -0
- package/.agent/skills/geo-fundamentals/SKILL.md +158 -99
- package/.agent/skills/i18n-localization/SKILL.md +158 -96
- package/.agent/skills/intelligent-routing/SKILL.md +89 -285
- package/.agent/skills/intelligent-routing/router-manifest.md +65 -0
- package/.agent/skills/lint-and-validate/SKILL.md +229 -27
- package/.agent/skills/llm-engineering/SKILL.md +258 -0
- package/.agent/skills/local-first/SKILL.md +203 -0
- package/.agent/skills/mcp-builder/SKILL.md +159 -111
- package/.agent/skills/mobile-design/SKILL.md +102 -282
- package/.agent/skills/nextjs-react-expert/SKILL.md +143 -227
- package/.agent/skills/nodejs-best-practices/SKILL.md +201 -254
- package/.agent/skills/observability/SKILL.md +285 -0
- package/.agent/skills/parallel-agents/SKILL.md +124 -118
- package/.agent/skills/performance-profiling/SKILL.md +143 -89
- package/.agent/skills/plan-writing/SKILL.md +133 -97
- package/.agent/skills/platform-engineer/SKILL.md +135 -0
- package/.agent/skills/powershell-windows/SKILL.md +167 -104
- package/.agent/skills/python-patterns/SKILL.md +149 -361
- package/.agent/skills/python-pro/SKILL.md +114 -0
- package/.agent/skills/react-specialist/SKILL.md +107 -0
- package/.agent/skills/realtime-patterns/SKILL.md +296 -0
- package/.agent/skills/red-team-tactics/SKILL.md +136 -134
- package/.agent/skills/rust-pro/SKILL.md +237 -173
- package/.agent/skills/seo-fundamentals/SKILL.md +134 -82
- package/.agent/skills/server-management/SKILL.md +155 -104
- package/.agent/skills/sql-pro/SKILL.md +104 -0
- package/.agent/skills/systematic-debugging/SKILL.md +156 -79
- package/.agent/skills/tailwind-patterns/SKILL.md +163 -205
- package/.agent/skills/tdd-workflow/SKILL.md +148 -88
- package/.agent/skills/test-result-analyzer/SKILL.md +299 -0
- package/.agent/skills/testing-patterns/SKILL.md +141 -114
- package/.agent/skills/trend-researcher/SKILL.md +228 -0
- package/.agent/skills/ui-ux-pro-max/SKILL.md +107 -0
- package/.agent/skills/ui-ux-researcher/SKILL.md +234 -0
- package/.agent/skills/vue-expert/SKILL.md +118 -0
- package/.agent/skills/vulnerability-scanner/SKILL.md +228 -188
- package/.agent/skills/web-design-guidelines/SKILL.md +148 -33
- package/.agent/skills/webapp-testing/SKILL.md +171 -122
- package/.agent/skills/whimsy-injector/SKILL.md +349 -0
- package/.agent/skills/workflow-optimizer/SKILL.md +219 -0
- package/.agent/workflows/api-tester.md +279 -0
- package/.agent/workflows/audit.md +168 -0
- package/.agent/workflows/brainstorm.md +65 -19
- package/.agent/workflows/changelog.md +144 -0
- package/.agent/workflows/create.md +67 -14
- package/.agent/workflows/debug.md +122 -30
- package/.agent/workflows/deploy.md +82 -31
- package/.agent/workflows/enhance.md +59 -27
- package/.agent/workflows/fix.md +143 -0
- package/.agent/workflows/generate.md +84 -20
- package/.agent/workflows/migrate.md +163 -0
- package/.agent/workflows/orchestrate.md +66 -17
- package/.agent/workflows/performance-benchmarker.md +305 -0
- package/.agent/workflows/plan.md +76 -33
- package/.agent/workflows/preview.md +73 -17
- package/.agent/workflows/refactor.md +153 -0
- package/.agent/workflows/review-ai.md +140 -0
- package/.agent/workflows/review.md +83 -16
- package/.agent/workflows/session.md +154 -0
- package/.agent/workflows/status.md +74 -18
- package/.agent/workflows/strengthen-skills.md +99 -0
- package/.agent/workflows/swarm.md +194 -0
- package/.agent/workflows/test.md +80 -31
- package/.agent/workflows/tribunal-backend.md +55 -13
- package/.agent/workflows/tribunal-database.md +62 -18
- package/.agent/workflows/tribunal-frontend.md +58 -12
- package/.agent/workflows/tribunal-full.md +70 -11
- package/.agent/workflows/tribunal-mobile.md +123 -0
- package/.agent/workflows/tribunal-performance.md +152 -0
- package/.agent/workflows/ui-ux-pro-max.md +100 -82
- package/README.md +117 -62
- package/bin/tribunal-kit.js +329 -75
- package/package.json +10 -6
package/bin/tribunal-kit.js
CHANGED
|
@@ -19,30 +19,43 @@
|
|
|
19
19
|
|
|
20
20
|
const fs = require('fs');
|
|
21
21
|
const path = require('path');
|
|
22
|
+
const https = require('https');
|
|
23
|
+
const { execSync } = require('child_process');
|
|
24
|
+
|
|
25
|
+
const PKG = require(path.resolve(__dirname, '..', 'package.json'));
|
|
26
|
+
const CURRENT_VERSION = PKG.version;
|
|
22
27
|
|
|
23
28
|
// ── Colors ───────────────────────────────────────────────
|
|
24
29
|
const C = {
|
|
25
|
-
reset:
|
|
26
|
-
bold:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
reset: '\x1b[0m',
|
|
31
|
+
bold: '\x1b[1m',
|
|
32
|
+
dim: '\x1b[2m',
|
|
33
|
+
red: '\x1b[91m',
|
|
34
|
+
green: '\x1b[92m',
|
|
35
|
+
yellow: '\x1b[93m',
|
|
36
|
+
blue: '\x1b[94m',
|
|
37
|
+
magenta: '\x1b[95m',
|
|
38
|
+
cyan: '\x1b[96m',
|
|
39
|
+
white: '\x1b[97m',
|
|
40
|
+
gray: '\x1b[90m',
|
|
41
|
+
bgCyan: '\x1b[46m',
|
|
32
42
|
};
|
|
33
43
|
|
|
34
44
|
function colorize(color, text) {
|
|
35
45
|
return `${C[color]}${text}${C.reset}`;
|
|
36
46
|
}
|
|
37
47
|
|
|
48
|
+
function c(color, text) { return `${C[color]}${text}${C.reset}`; }
|
|
49
|
+
function bold(text) { return `${C.bold}${text}${C.reset}`; }
|
|
50
|
+
|
|
38
51
|
// ── Logging ──────────────────────────────────────────────
|
|
39
52
|
let quiet = false;
|
|
40
53
|
|
|
41
|
-
function log(msg)
|
|
42
|
-
function ok(msg)
|
|
43
|
-
function warn(msg) { if (!quiet) console.log(` ${
|
|
44
|
-
function err(msg)
|
|
45
|
-
function dim(msg)
|
|
54
|
+
function log(msg) { if (!quiet) console.log(msg); }
|
|
55
|
+
function ok(msg) { if (!quiet) console.log(` ${c('green', '✔')} ${msg}`); }
|
|
56
|
+
function warn(msg) { if (!quiet) console.log(` ${c('yellow', '⚠')} ${msg}`); }
|
|
57
|
+
function err(msg) { console.error(` ${c('red', '✖')} ${msg}`); }
|
|
58
|
+
function dim(msg) { if (!quiet) console.log(` ${c('gray', msg)}`); }
|
|
46
59
|
|
|
47
60
|
// ── Arg Parser ───────────────────────────────────────────
|
|
48
61
|
function parseArgs(argv) {
|
|
@@ -58,6 +71,7 @@ function parseArgs(argv) {
|
|
|
58
71
|
if (arg === '--force') { args.flags.force = true; continue; }
|
|
59
72
|
if (arg === '--quiet') { args.flags.quiet = true; continue; }
|
|
60
73
|
if (arg === '--dry-run') { args.flags.dryRun = true; continue; }
|
|
74
|
+
if (arg === '--skip-update-check') { args.flags.skipUpdateCheck = true; continue; }
|
|
61
75
|
if (arg.startsWith('--path=')) {
|
|
62
76
|
args.flags.path = arg.split('=').slice(1).join('=');
|
|
63
77
|
}
|
|
@@ -109,6 +123,107 @@ function countDir(dir) {
|
|
|
109
123
|
return count;
|
|
110
124
|
}
|
|
111
125
|
|
|
126
|
+
// ── Version Check & Auto-Update ──────────────────────────
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Compare two semver strings. Returns:
|
|
130
|
+
* 1 if a > b, -1 if a < b, 0 if equal.
|
|
131
|
+
*/
|
|
132
|
+
function compareSemver(a, b) {
|
|
133
|
+
const pa = a.replace(/^v/, '').split('.').map(Number);
|
|
134
|
+
const pb = b.replace(/^v/, '').split('.').map(Number);
|
|
135
|
+
for (let i = 0; i < 3; i++) {
|
|
136
|
+
const na = pa[i] || 0;
|
|
137
|
+
const nb = pb[i] || 0;
|
|
138
|
+
if (na > nb) return 1;
|
|
139
|
+
if (na < nb) return -1;
|
|
140
|
+
}
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Fetch the latest version from GitHub Releases.
|
|
146
|
+
* Returns the version string (e.g. '2.4.0') or null on failure.
|
|
147
|
+
*/
|
|
148
|
+
function fetchLatestVersion() {
|
|
149
|
+
return new Promise((resolve) => {
|
|
150
|
+
const req = https.get(
|
|
151
|
+
'https://api.github.com/repos/Harmitx7/tribunal-kit/releases/latest',
|
|
152
|
+
{
|
|
153
|
+
headers: {
|
|
154
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
155
|
+
'User-Agent': `tribunal-kit/${CURRENT_VERSION}`
|
|
156
|
+
},
|
|
157
|
+
timeout: 5000
|
|
158
|
+
},
|
|
159
|
+
(res) => {
|
|
160
|
+
let data = '';
|
|
161
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
162
|
+
res.on('end', () => {
|
|
163
|
+
try {
|
|
164
|
+
const json = JSON.parse(data);
|
|
165
|
+
// GitHub tags usually have a 'v' prefix (e.g., 'v2.4.0')
|
|
166
|
+
const version = json.tag_name ? json.tag_name.replace(/^v/, '') : null;
|
|
167
|
+
resolve(version);
|
|
168
|
+
} catch {
|
|
169
|
+
resolve(null);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
req.on('error', () => resolve(null));
|
|
175
|
+
req.on('timeout', () => { req.destroy(); resolve(null); });
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Check for a newer version and re-invoke with @latest if found.
|
|
181
|
+
* Uses TK_SKIP_UPDATE_CHECK env var as recursion guard.
|
|
182
|
+
* Returns true if a re-invoke happened (caller should exit), false otherwise.
|
|
183
|
+
*/
|
|
184
|
+
async function autoUpdateCheck(originalArgs) {
|
|
185
|
+
// Recursion guard: if we're already a re-invoked process, skip
|
|
186
|
+
if (process.env.TK_SKIP_UPDATE_CHECK === '1') {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const latestVersion = await fetchLatestVersion();
|
|
191
|
+
|
|
192
|
+
if (!latestVersion) {
|
|
193
|
+
// Network fail — proceed silently with current version
|
|
194
|
+
dim('Could not check for updates (offline?). Using local version.');
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (compareSemver(latestVersion, CURRENT_VERSION) <= 0) {
|
|
199
|
+
// Already up to date
|
|
200
|
+
dim(`Version ${CURRENT_VERSION} is up to date.`);
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Newer version available — re-invoke
|
|
205
|
+
log('');
|
|
206
|
+
log(colorize('cyan', ` ⬆ New version available: ${colorize('bold', CURRENT_VERSION)} → ${colorize('bold', latestVersion)}`));
|
|
207
|
+
log(colorize('gray', ' Re-invoking with latest version...'));
|
|
208
|
+
log('');
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
// Build the command pulling directly from GitHub
|
|
212
|
+
const args = originalArgs.join(' ');
|
|
213
|
+
const cmd = `npx -y github:Harmitx7/tribunal-kit#v${latestVersion} ${args}`;
|
|
214
|
+
|
|
215
|
+
execSync(cmd, {
|
|
216
|
+
stdio: 'inherit',
|
|
217
|
+
env: { ...process.env, TK_SKIP_UPDATE_CHECK: '1' },
|
|
218
|
+
});
|
|
219
|
+
return true; // Re-invoke succeeded, caller should exit
|
|
220
|
+
} catch (e) {
|
|
221
|
+
warn(`Auto-update failed: ${e.message}`);
|
|
222
|
+
warn('Continuing with current version...');
|
|
223
|
+
return false; // Fall through to current version
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
112
227
|
// ── Kit Source Location ───────────────────────────────────
|
|
113
228
|
function getKitAgent() {
|
|
114
229
|
// When installed via npm, the .agent/ folder is next to this script's package
|
|
@@ -124,12 +239,55 @@ function getKitAgent() {
|
|
|
124
239
|
return agentDir;
|
|
125
240
|
}
|
|
126
241
|
|
|
242
|
+
// ── Self-Install Guard ────────────────────────────────────
|
|
243
|
+
/**
|
|
244
|
+
* Returns true if the target directory IS the tribunal-kit package itself.
|
|
245
|
+
* This prevents `init --force` / `update` from deleting the package's own files
|
|
246
|
+
* when run from inside the project directory.
|
|
247
|
+
*/
|
|
248
|
+
function isSelfInstall(targetDir) {
|
|
249
|
+
const kitRoot = path.resolve(__dirname, '..');
|
|
250
|
+
const resolvedTarget = path.resolve(targetDir);
|
|
251
|
+
|
|
252
|
+
// Direct path match
|
|
253
|
+
if (resolvedTarget === kitRoot) return true;
|
|
254
|
+
|
|
255
|
+
// Check if the target's package.json is this package
|
|
256
|
+
const targetPkg = path.join(resolvedTarget, 'package.json');
|
|
257
|
+
if (fs.existsSync(targetPkg)) {
|
|
258
|
+
try {
|
|
259
|
+
const targetName = JSON.parse(fs.readFileSync(targetPkg, 'utf8')).name;
|
|
260
|
+
if (targetName === PKG.name) return true;
|
|
261
|
+
} catch {
|
|
262
|
+
// Unreadable package.json — not a match
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
|
|
127
269
|
// ── Banner ────────────────────────────────────────────────
|
|
128
270
|
function banner() {
|
|
129
271
|
if (quiet) return;
|
|
272
|
+
// Big ASCII art (TRIBUNAL-KIT)
|
|
273
|
+
const art = String.raw`
|
|
274
|
+
___________ ._____. .__ ____ __.__ __
|
|
275
|
+
\__ ___/______|__\_ |__ __ __ ____ _____ | | | |/ _|__|/ |_
|
|
276
|
+
| | \_ __ \ || __ \| | \/ \\__ \ | | ______ | < | \ __\
|
|
277
|
+
| | | | \/ || \_\ \ | / | \/ __ \| |__ /_____/ | | \| || |
|
|
278
|
+
|____| |__| |__||___ /____/|___| (____ /____/ |____|__ \__||__|
|
|
279
|
+
\/ \/ \/ \/ `.split('\n').filter(Boolean);
|
|
280
|
+
console.log();
|
|
281
|
+
for (const line of art) log(` ${c('cyan', bold(line))}`);
|
|
130
282
|
console.log();
|
|
131
|
-
|
|
132
|
-
|
|
283
|
+
// Subtitle strip
|
|
284
|
+
const W = 80;
|
|
285
|
+
const sub = 'Anti-Hallucination Agent System';
|
|
286
|
+
const sp = Math.max(0, W - sub.length);
|
|
287
|
+
const centred = ' '.repeat(Math.floor(sp / 2)) + sub + ' '.repeat(Math.ceil(sp / 2));
|
|
288
|
+
console.log(` ${c('cyan', '╔' + '═'.repeat(W) + '╗')}`);
|
|
289
|
+
console.log(` ${c('cyan', '║')}${c('gray', centred)}${c('cyan', '║')}`);
|
|
290
|
+
console.log(` ${c('cyan', '╚' + '═'.repeat(W) + '╝')}`);
|
|
133
291
|
console.log();
|
|
134
292
|
}
|
|
135
293
|
|
|
@@ -140,6 +298,21 @@ function cmdInit(flags) {
|
|
|
140
298
|
const agentDest = path.join(targetDir, '.agent');
|
|
141
299
|
const dryRun = flags.dryRun || false;
|
|
142
300
|
|
|
301
|
+
// ── Self-install guard ──────────────────────────────────
|
|
302
|
+
if (isSelfInstall(targetDir)) {
|
|
303
|
+
err('Cannot run init/update inside the tribunal-kit package itself.');
|
|
304
|
+
err(`Target: ${targetDir}`);
|
|
305
|
+
err(`Package: ${path.resolve(__dirname, '..')}`);
|
|
306
|
+
console.log();
|
|
307
|
+
dim('This command is designed to install .agent/ into OTHER projects.');
|
|
308
|
+
dim('Run it from the root of the project you want to set up:');
|
|
309
|
+
dim(' cd /path/to/your-project');
|
|
310
|
+
dim(' npx tribunal-kit init');
|
|
311
|
+
console.log();
|
|
312
|
+
process.exit(1);
|
|
313
|
+
}
|
|
314
|
+
// ────────────────────────────────────────────────────────
|
|
315
|
+
|
|
143
316
|
banner();
|
|
144
317
|
|
|
145
318
|
if (dryRun) {
|
|
@@ -161,32 +334,74 @@ function cmdInit(flags) {
|
|
|
161
334
|
process.exit(0);
|
|
162
335
|
}
|
|
163
336
|
|
|
337
|
+
if (!dryRun && fs.existsSync(agentDest) && flags.force) {
|
|
338
|
+
const subdirs = ['agents', 'workflows', 'skills', 'scripts', '.shared'];
|
|
339
|
+
for (const sub of subdirs) {
|
|
340
|
+
const subPath = path.join(agentDest, sub);
|
|
341
|
+
if (fs.existsSync(subPath)) {
|
|
342
|
+
fs.rmSync(subPath, { recursive: true, force: true });
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
164
347
|
// Count what we're installing
|
|
165
348
|
const totalFiles = countDir(agentSrc);
|
|
166
|
-
|
|
349
|
+
log(` ${c('gray','▸')} Scanning ${c('white', String(totalFiles))} files ${c('gray','→')} ${c('gray', agentDest)}`);
|
|
167
350
|
|
|
168
351
|
try {
|
|
169
352
|
const copied = copyDir(agentSrc, agentDest, dryRun);
|
|
170
353
|
|
|
171
354
|
console.log();
|
|
172
355
|
if (dryRun) {
|
|
173
|
-
ok(
|
|
356
|
+
ok(`${bold('DRY RUN')} complete — would install ${c('cyan', String(copied))} files`);
|
|
174
357
|
dim(`Target: ${agentDest}`);
|
|
175
358
|
} else {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
359
|
+
// ── Success card — W=52, rows padded by plain-text length ──
|
|
360
|
+
const W = 52;
|
|
361
|
+
const agentsCount = fs.readdirSync(path.join(agentDest, 'agents')).length;
|
|
362
|
+
const workflowsCount = fs.readdirSync(path.join(agentDest, 'workflows')).length;
|
|
363
|
+
const skillsCount = fs.readdirSync(path.join(agentDest, 'skills')).length;
|
|
364
|
+
const scriptsCount = fs.readdirSync(path.join(agentDest, 'scripts')).length;
|
|
365
|
+
|
|
366
|
+
// Stat rows: compute trailing spaces from plain text so right ║ aligns
|
|
367
|
+
const statRow = (icon, label, val, col) => {
|
|
368
|
+
// emoji JS .length===2 == terminal display width 2 ✓
|
|
369
|
+
const plain = ` ${icon} ${label.padEnd(10)}${String(val).padStart(3)} installed`;
|
|
370
|
+
const trail = ' '.repeat(Math.max(0, W - plain.length));
|
|
371
|
+
return ` ${c('cyan','║')} ${icon} ${c('white',label.padEnd(10))}${c(col,String(val).padStart(3))} ${c('gray','installed')}${trail}${c('cyan','║')}`;
|
|
372
|
+
};
|
|
373
|
+
// Plain-text rows (header / blank)
|
|
374
|
+
const plainRow = (text, wrapFn) => {
|
|
375
|
+
const trail = ' '.repeat(Math.max(0, W - text.length));
|
|
376
|
+
return ` ${c('cyan','║')}${wrapFn(text)}${trail}${c('cyan','║')}`;
|
|
377
|
+
};
|
|
378
|
+
// Next-step rows: fixed cmd column + description
|
|
379
|
+
const stepRow = (cmd, desc) => {
|
|
380
|
+
const plain = ` ${cmd.padEnd(16)}${desc}`;
|
|
381
|
+
const trail = ' '.repeat(Math.max(0, W - plain.length));
|
|
382
|
+
return ` ${c('cyan','║')} ${c('white',cmd.padEnd(16))}${c('gray',desc)}${trail}${c('cyan','║')}`;
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
console.log(` ${c('green','✔')} ${bold(c('green','Installation complete'))} ${c('gray','—')} ${c('white',String(copied))} files`);
|
|
386
|
+
console.log(` ${c('gray',' ╰─')} ${c('gray', agentDest)}`);
|
|
187
387
|
console.log();
|
|
188
|
-
log(
|
|
189
|
-
log(
|
|
388
|
+
console.log(` ${c('cyan', '╔' + '═'.repeat(W) + '╗')}`);
|
|
389
|
+
console.log(plainRow(` What's inside:`, s => c('bold', c('white', s))));
|
|
390
|
+
console.log(` ${c('cyan', '╠' + '═'.repeat(W) + '╣')}`);
|
|
391
|
+
console.log(statRow('🤖', 'Agents', agentsCount, 'magenta'));
|
|
392
|
+
console.log(statRow('⚡', 'Workflows', workflowsCount, 'yellow'));
|
|
393
|
+
console.log(statRow('🧠', 'Skills', skillsCount, 'blue'));
|
|
394
|
+
console.log(statRow('🔧', 'Scripts', scriptsCount, 'green'));
|
|
395
|
+
console.log(` ${c('cyan', '╠' + '═'.repeat(W) + '╣')}`);
|
|
396
|
+
console.log(plainRow('', () => ''));
|
|
397
|
+
console.log(plainRow(` Next steps:`, s => c('gray', s)));
|
|
398
|
+
console.log(stepRow('/generate', 'Generate code with anti-hallucination'));
|
|
399
|
+
console.log(stepRow('/review', 'Audit existing code for issues'));
|
|
400
|
+
console.log(stepRow('/tribunal-full', 'Run all 11 reviewers in parallel'));
|
|
401
|
+
console.log(plainRow('', () => ''));
|
|
402
|
+
console.log(` ${c('cyan', '╚' + '═'.repeat(W) + '╝')}`);
|
|
403
|
+
console.log();
|
|
404
|
+
log(` ${c('gray', '✦ Your AI IDE will pick up changes automatically.')}`);
|
|
190
405
|
}
|
|
191
406
|
|
|
192
407
|
console.log();
|
|
@@ -197,15 +412,68 @@ function cmdInit(flags) {
|
|
|
197
412
|
}
|
|
198
413
|
|
|
199
414
|
function cmdUpdate(flags) {
|
|
415
|
+
// ── Self-install guard (early, before banner) ───────────
|
|
416
|
+
const targetDir = flags.path ? path.resolve(flags.path) : process.cwd();
|
|
417
|
+
if (isSelfInstall(targetDir)) {
|
|
418
|
+
err('Cannot run update inside the tribunal-kit package itself.');
|
|
419
|
+
err(`Target: ${targetDir}`);
|
|
420
|
+
console.log();
|
|
421
|
+
dim('This command is designed to update .agent/ in OTHER projects.');
|
|
422
|
+
dim('Run it from the root of the project you want to update:');
|
|
423
|
+
dim(' cd /path/to/your-project');
|
|
424
|
+
dim(' npx tribunal-kit update');
|
|
425
|
+
console.log();
|
|
426
|
+
process.exit(1);
|
|
427
|
+
}
|
|
428
|
+
// ────────────────────────────────────────────────────────
|
|
429
|
+
|
|
200
430
|
// Update = init with --force
|
|
201
431
|
flags.force = true;
|
|
202
432
|
if (!quiet) {
|
|
203
|
-
log(
|
|
433
|
+
log(` ${c('cyan','↻')} ${bold('Updating')} ${c('white','.agent/')} to latest version...`);
|
|
204
434
|
console.log();
|
|
205
435
|
}
|
|
206
436
|
cmdInit(flags);
|
|
207
437
|
}
|
|
208
438
|
|
|
439
|
+
// ── Async Main Wrapper ───────────────────────────────────
|
|
440
|
+
async function runWithUpdateCheck(command, flags) {
|
|
441
|
+
const shouldSkip = flags.skipUpdateCheck || process.env.TK_SKIP_UPDATE_CHECK === '1';
|
|
442
|
+
|
|
443
|
+
if (!shouldSkip && (command === 'init' || command === 'update')) {
|
|
444
|
+
// Pass through the original args (minus the node/script path)
|
|
445
|
+
const originalArgs = process.argv.slice(2);
|
|
446
|
+
const didReInvoke = await autoUpdateCheck(originalArgs);
|
|
447
|
+
if (didReInvoke) {
|
|
448
|
+
process.exit(0); // Latest version handled it
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Proceed with current version
|
|
453
|
+
switch (command) {
|
|
454
|
+
case 'init':
|
|
455
|
+
cmdInit(flags);
|
|
456
|
+
break;
|
|
457
|
+
case 'update':
|
|
458
|
+
cmdUpdate(flags);
|
|
459
|
+
break;
|
|
460
|
+
case 'status':
|
|
461
|
+
cmdStatus(flags);
|
|
462
|
+
break;
|
|
463
|
+
case 'help':
|
|
464
|
+
case '--help':
|
|
465
|
+
case '-h':
|
|
466
|
+
case null:
|
|
467
|
+
cmdHelp();
|
|
468
|
+
break;
|
|
469
|
+
default:
|
|
470
|
+
err(`Unknown command: "${command}"`);
|
|
471
|
+
console.log();
|
|
472
|
+
dim('Run tribunal-kit --help for usage');
|
|
473
|
+
process.exit(1);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
209
477
|
function cmdStatus(flags) {
|
|
210
478
|
const targetDir = flags.path ? path.resolve(flags.path) : process.cwd();
|
|
211
479
|
const agentDest = path.join(targetDir, '.agent');
|
|
@@ -213,22 +481,24 @@ function cmdStatus(flags) {
|
|
|
213
481
|
banner();
|
|
214
482
|
|
|
215
483
|
if (!fs.existsSync(agentDest)) {
|
|
216
|
-
log(` ${
|
|
484
|
+
log(` ${c('red','✖')} ${bold('Not installed')} in this project`);
|
|
217
485
|
console.log();
|
|
218
|
-
|
|
486
|
+
log(` ${c('gray','Run:')} ${c('cyan','npx tribunal-kit init')}`);
|
|
219
487
|
console.log();
|
|
220
488
|
return;
|
|
221
489
|
}
|
|
222
490
|
|
|
223
|
-
log(` ${
|
|
491
|
+
log(` ${c('green','✔')} ${bold(c('green','Installed'))} ${c('gray','→')} ${c('gray', agentDest)}`);
|
|
224
492
|
console.log();
|
|
225
493
|
|
|
494
|
+
const icons = { agents: '🤖', workflows: '⚡', skills: '🧠', scripts: '🔧' };
|
|
495
|
+
const colors = { agents: 'magenta', workflows: 'yellow', skills: 'blue', scripts: 'green' };
|
|
226
496
|
const subdirs = ['agents', 'workflows', 'skills', 'scripts'];
|
|
227
497
|
for (const sub of subdirs) {
|
|
228
498
|
const subPath = path.join(agentDest, sub);
|
|
229
499
|
if (fs.existsSync(subPath)) {
|
|
230
500
|
const count = fs.readdirSync(subPath).filter(f => !fs.statSync(path.join(subPath, f)).isDirectory()).length;
|
|
231
|
-
|
|
501
|
+
log(` ${icons[sub]} ${c(colors[sub], sub.padEnd(12))}${c('white', String(count).padStart(3))} files`);
|
|
232
502
|
}
|
|
233
503
|
}
|
|
234
504
|
console.log();
|
|
@@ -236,27 +506,32 @@ function cmdStatus(flags) {
|
|
|
236
506
|
|
|
237
507
|
function cmdHelp() {
|
|
238
508
|
banner();
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
509
|
+
const cmd = (name, desc) => ` ${c('cyan', name.padEnd(10))} ${c('gray', desc)}`;
|
|
510
|
+
const opt = (flag, desc) => ` ${c('yellow', flag.padEnd(22))} ${c('gray', desc)}`;
|
|
511
|
+
const ex = (s) => ` ${c('gray', '▸')} ${c('white', s)}`;
|
|
512
|
+
|
|
513
|
+
log(bold(' Commands'));
|
|
514
|
+
log(` ${c('gray','─'.repeat(40))}`);
|
|
515
|
+
log(cmd('init', 'Install .agent/ into current project'));
|
|
516
|
+
log(cmd('update', 'Re-install to get latest version'));
|
|
517
|
+
log(cmd('status', 'Check if .agent/ is installed'));
|
|
246
518
|
console.log();
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
519
|
+
log(bold(' Options'));
|
|
520
|
+
log(` ${c('gray','─'.repeat(40))}`);
|
|
521
|
+
log(opt('--force', 'Overwrite existing .agent/ folder'));
|
|
522
|
+
log(opt('--path <dir>', 'Install in specific directory'));
|
|
523
|
+
log(opt('--quiet', 'Suppress all output'));
|
|
524
|
+
log(opt('--dry-run', 'Preview actions without executing'));
|
|
525
|
+
log(opt('--skip-update-check', 'Skip auto-update version check'));
|
|
251
526
|
console.log();
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
527
|
+
log(bold(' Examples'));
|
|
528
|
+
log(` ${c('gray','─'.repeat(40))}`);
|
|
529
|
+
log(ex('npx tribunal-kit init'));
|
|
530
|
+
log(ex('npx tribunal-kit init --force'));
|
|
531
|
+
log(ex('npx tribunal-kit init --path ./my-app'));
|
|
532
|
+
log(ex('npx tribunal-kit init --dry-run'));
|
|
533
|
+
log(ex('npx tribunal-kit update'));
|
|
534
|
+
log(ex('npx tribunal-kit status'));
|
|
260
535
|
console.log();
|
|
261
536
|
}
|
|
262
537
|
|
|
@@ -265,25 +540,4 @@ const { command, flags } = parseArgs(process.argv);
|
|
|
265
540
|
|
|
266
541
|
if (flags.quiet) quiet = true;
|
|
267
542
|
|
|
268
|
-
|
|
269
|
-
case 'init':
|
|
270
|
-
cmdInit(flags);
|
|
271
|
-
break;
|
|
272
|
-
case 'update':
|
|
273
|
-
cmdUpdate(flags);
|
|
274
|
-
break;
|
|
275
|
-
case 'status':
|
|
276
|
-
cmdStatus(flags);
|
|
277
|
-
break;
|
|
278
|
-
case 'help':
|
|
279
|
-
case '--help':
|
|
280
|
-
case '-h':
|
|
281
|
-
case null:
|
|
282
|
-
cmdHelp();
|
|
283
|
-
break;
|
|
284
|
-
default:
|
|
285
|
-
err(`Unknown command: "${command}"`);
|
|
286
|
-
console.log();
|
|
287
|
-
dim('Run tribunal-kit --help for usage');
|
|
288
|
-
process.exit(1);
|
|
289
|
-
}
|
|
543
|
+
runWithUpdateCheck(command, flags);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tribunal-kit",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Anti-Hallucination AI Agent Kit —
|
|
3
|
+
"version": "2.4.0",
|
|
4
|
+
"description": "Anti-Hallucination AI Agent Kit — 33 specialist agents, 25 slash commands, Swarm/Supervisor engine, and Tribunal review pipeline for Cursor, Windsurf, and Antigravity.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
7
7
|
"agent",
|
|
@@ -13,11 +13,15 @@
|
|
|
13
13
|
"code-review",
|
|
14
14
|
"llm"
|
|
15
15
|
],
|
|
16
|
-
"homepage": "https://github.com/
|
|
16
|
+
"homepage": "https://github.com/Harmitx7/tribunal-kit",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/Harmitx7/tribunal-kit.git"
|
|
20
|
+
},
|
|
17
21
|
"license": "MIT",
|
|
18
22
|
"bin": {
|
|
19
|
-
"tribunal-kit": "
|
|
20
|
-
"tk": "
|
|
23
|
+
"tribunal-kit": "bin/tribunal-kit.js",
|
|
24
|
+
"tk": "bin/tribunal-kit.js"
|
|
21
25
|
},
|
|
22
26
|
"files": [
|
|
23
27
|
"bin/",
|
|
@@ -31,4 +35,4 @@
|
|
|
31
35
|
"scripts": {
|
|
32
36
|
"test": "echo \"No tests for CLI\" && exit 0"
|
|
33
37
|
}
|
|
34
|
-
}
|
|
38
|
+
}
|