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.
Files changed (125) hide show
  1. package/.agent/.shared/ui-ux-pro-max/README.md +3 -3
  2. package/.agent/ARCHITECTURE.md +205 -10
  3. package/.agent/GEMINI.md +37 -7
  4. package/.agent/agents/accessibility-reviewer.md +134 -0
  5. package/.agent/agents/ai-code-reviewer.md +129 -0
  6. package/.agent/agents/frontend-specialist.md +3 -0
  7. package/.agent/agents/game-developer.md +21 -21
  8. package/.agent/agents/logic-reviewer.md +12 -0
  9. package/.agent/agents/mobile-reviewer.md +79 -0
  10. package/.agent/agents/orchestrator.md +56 -26
  11. package/.agent/agents/performance-reviewer.md +36 -0
  12. package/.agent/agents/supervisor-agent.md +156 -0
  13. package/.agent/agents/swarm-worker-contracts.md +166 -0
  14. package/.agent/agents/swarm-worker-registry.md +92 -0
  15. package/.agent/rules/GEMINI.md +134 -5
  16. package/.agent/scripts/bundle_analyzer.py +259 -0
  17. package/.agent/scripts/dependency_analyzer.py +247 -0
  18. package/.agent/scripts/lint_runner.py +188 -0
  19. package/.agent/scripts/patch_skills_meta.py +177 -0
  20. package/.agent/scripts/patch_skills_output.py +285 -0
  21. package/.agent/scripts/schema_validator.py +279 -0
  22. package/.agent/scripts/security_scan.py +224 -0
  23. package/.agent/scripts/session_manager.py +144 -3
  24. package/.agent/scripts/skill_integrator.py +234 -0
  25. package/.agent/scripts/strengthen_skills.py +220 -0
  26. package/.agent/scripts/swarm_dispatcher.py +317 -0
  27. package/.agent/scripts/test_runner.py +192 -0
  28. package/.agent/scripts/test_swarm_dispatcher.py +163 -0
  29. package/.agent/skills/agent-organizer/SKILL.md +132 -0
  30. package/.agent/skills/agentic-patterns/SKILL.md +335 -0
  31. package/.agent/skills/api-patterns/SKILL.md +226 -50
  32. package/.agent/skills/app-builder/SKILL.md +215 -52
  33. package/.agent/skills/architecture/SKILL.md +176 -31
  34. package/.agent/skills/bash-linux/SKILL.md +150 -134
  35. package/.agent/skills/behavioral-modes/SKILL.md +152 -160
  36. package/.agent/skills/brainstorming/SKILL.md +148 -101
  37. package/.agent/skills/brainstorming/dynamic-questioning.md +10 -0
  38. package/.agent/skills/clean-code/SKILL.md +139 -134
  39. package/.agent/skills/code-review-checklist/SKILL.md +177 -80
  40. package/.agent/skills/config-validator/SKILL.md +165 -0
  41. package/.agent/skills/csharp-developer/SKILL.md +107 -0
  42. package/.agent/skills/database-design/SKILL.md +252 -29
  43. package/.agent/skills/deployment-procedures/SKILL.md +122 -175
  44. package/.agent/skills/devops-engineer/SKILL.md +134 -0
  45. package/.agent/skills/devops-incident-responder/SKILL.md +98 -0
  46. package/.agent/skills/documentation-templates/SKILL.md +175 -121
  47. package/.agent/skills/dotnet-core-expert/SKILL.md +103 -0
  48. package/.agent/skills/edge-computing/SKILL.md +213 -0
  49. package/.agent/skills/frontend-design/SKILL.md +76 -0
  50. package/.agent/skills/frontend-design/color-system.md +18 -0
  51. package/.agent/skills/frontend-design/typography-system.md +18 -0
  52. package/.agent/skills/game-development/SKILL.md +69 -0
  53. package/.agent/skills/geo-fundamentals/SKILL.md +158 -99
  54. package/.agent/skills/i18n-localization/SKILL.md +158 -96
  55. package/.agent/skills/intelligent-routing/SKILL.md +89 -285
  56. package/.agent/skills/intelligent-routing/router-manifest.md +65 -0
  57. package/.agent/skills/lint-and-validate/SKILL.md +229 -27
  58. package/.agent/skills/llm-engineering/SKILL.md +258 -0
  59. package/.agent/skills/local-first/SKILL.md +203 -0
  60. package/.agent/skills/mcp-builder/SKILL.md +159 -111
  61. package/.agent/skills/mobile-design/SKILL.md +102 -282
  62. package/.agent/skills/nextjs-react-expert/SKILL.md +143 -227
  63. package/.agent/skills/nodejs-best-practices/SKILL.md +201 -254
  64. package/.agent/skills/observability/SKILL.md +285 -0
  65. package/.agent/skills/parallel-agents/SKILL.md +124 -118
  66. package/.agent/skills/performance-profiling/SKILL.md +143 -89
  67. package/.agent/skills/plan-writing/SKILL.md +133 -97
  68. package/.agent/skills/platform-engineer/SKILL.md +135 -0
  69. package/.agent/skills/powershell-windows/SKILL.md +167 -104
  70. package/.agent/skills/python-patterns/SKILL.md +149 -361
  71. package/.agent/skills/python-pro/SKILL.md +114 -0
  72. package/.agent/skills/react-specialist/SKILL.md +107 -0
  73. package/.agent/skills/realtime-patterns/SKILL.md +296 -0
  74. package/.agent/skills/red-team-tactics/SKILL.md +136 -134
  75. package/.agent/skills/rust-pro/SKILL.md +237 -173
  76. package/.agent/skills/seo-fundamentals/SKILL.md +134 -82
  77. package/.agent/skills/server-management/SKILL.md +155 -104
  78. package/.agent/skills/sql-pro/SKILL.md +104 -0
  79. package/.agent/skills/systematic-debugging/SKILL.md +156 -79
  80. package/.agent/skills/tailwind-patterns/SKILL.md +163 -205
  81. package/.agent/skills/tdd-workflow/SKILL.md +148 -88
  82. package/.agent/skills/test-result-analyzer/SKILL.md +299 -0
  83. package/.agent/skills/testing-patterns/SKILL.md +141 -114
  84. package/.agent/skills/trend-researcher/SKILL.md +228 -0
  85. package/.agent/skills/ui-ux-pro-max/SKILL.md +107 -0
  86. package/.agent/skills/ui-ux-researcher/SKILL.md +234 -0
  87. package/.agent/skills/vue-expert/SKILL.md +118 -0
  88. package/.agent/skills/vulnerability-scanner/SKILL.md +228 -188
  89. package/.agent/skills/web-design-guidelines/SKILL.md +148 -33
  90. package/.agent/skills/webapp-testing/SKILL.md +171 -122
  91. package/.agent/skills/whimsy-injector/SKILL.md +349 -0
  92. package/.agent/skills/workflow-optimizer/SKILL.md +219 -0
  93. package/.agent/workflows/api-tester.md +279 -0
  94. package/.agent/workflows/audit.md +168 -0
  95. package/.agent/workflows/brainstorm.md +65 -19
  96. package/.agent/workflows/changelog.md +144 -0
  97. package/.agent/workflows/create.md +67 -14
  98. package/.agent/workflows/debug.md +122 -30
  99. package/.agent/workflows/deploy.md +82 -31
  100. package/.agent/workflows/enhance.md +59 -27
  101. package/.agent/workflows/fix.md +143 -0
  102. package/.agent/workflows/generate.md +84 -20
  103. package/.agent/workflows/migrate.md +163 -0
  104. package/.agent/workflows/orchestrate.md +66 -17
  105. package/.agent/workflows/performance-benchmarker.md +305 -0
  106. package/.agent/workflows/plan.md +76 -33
  107. package/.agent/workflows/preview.md +73 -17
  108. package/.agent/workflows/refactor.md +153 -0
  109. package/.agent/workflows/review-ai.md +140 -0
  110. package/.agent/workflows/review.md +83 -16
  111. package/.agent/workflows/session.md +154 -0
  112. package/.agent/workflows/status.md +74 -18
  113. package/.agent/workflows/strengthen-skills.md +99 -0
  114. package/.agent/workflows/swarm.md +194 -0
  115. package/.agent/workflows/test.md +80 -31
  116. package/.agent/workflows/tribunal-backend.md +55 -13
  117. package/.agent/workflows/tribunal-database.md +62 -18
  118. package/.agent/workflows/tribunal-frontend.md +58 -12
  119. package/.agent/workflows/tribunal-full.md +70 -11
  120. package/.agent/workflows/tribunal-mobile.md +123 -0
  121. package/.agent/workflows/tribunal-performance.md +152 -0
  122. package/.agent/workflows/ui-ux-pro-max.md +100 -82
  123. package/README.md +117 -62
  124. package/bin/tribunal-kit.js +329 -75
  125. package/package.json +10 -6
@@ -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: '\x1b[0m',
26
- bold: '\x1b[1m',
27
- red: '\x1b[91m',
28
- green: '\x1b[92m',
29
- yellow: '\x1b[93m',
30
- cyan: '\x1b[96m',
31
- gray: '\x1b[90m',
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) { if (!quiet) console.log(msg); }
42
- function ok(msg) { if (!quiet) console.log(` ${colorize('green', '')} ${msg}`); }
43
- function warn(msg) { if (!quiet) console.log(` ${colorize('yellow', '⚠️ ')} ${msg}`); }
44
- function err(msg) { console.error(` ${colorize('red', '')} ${msg}`); }
45
- function dim(msg) { if (!quiet) console.log(` ${colorize('gray', 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
- console.log(colorize('cyan', colorize('bold', ' Tribunal Anti-Hallucination Agent Kit')));
132
- console.log(colorize('gray', ' ──────────────────────────────────────'));
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
- dim(`Installing ${totalFiles} files ${agentDest}`);
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(`DRY RUN complete — would install ${copied} files`);
356
+ ok(`${bold('DRY RUN')} complete — would install ${c('cyan', String(copied))} files`);
174
357
  dim(`Target: ${agentDest}`);
175
358
  } else {
176
- ok(`Installation complete${copied} files installed`);
177
- dim(`Location: ${agentDest}`);
178
- }
179
- console.log();
180
-
181
- if (!dryRun) {
182
- log(colorize('bold', ' What was installed:'));
183
- dim(` Agents: ${fs.readdirSync(path.join(agentDest, 'agents')).length} specialist agents`);
184
- dim(` Workflows: ${fs.readdirSync(path.join(agentDest, 'workflows')).length} slash commands`);
185
- dim(` Skills: ${fs.readdirSync(path.join(agentDest, 'skills')).length} skill modules`);
186
- dim(` Scripts: ${fs.readdirSync(path.join(agentDest, 'scripts')).length} utility scripts`);
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(colorize('gray', ' Your AI IDE will pick this up automatically.'));
189
- log(colorize('gray', ' Type /generate, /review, /tribunal-full in the chat.'));
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(colorize('cyan', ' Updating .agent/ to latest version...'));
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(` ${colorize('red', '🔴')} Not installed in: ${targetDir}`);
484
+ log(` ${c('red','')} ${bold('Not installed')} in this project`);
217
485
  console.log();
218
- dim('Run: tribunal-kit init');
486
+ log(` ${c('gray','Run:')} ${c('cyan','npx tribunal-kit init')}`);
219
487
  console.log();
220
488
  return;
221
489
  }
222
490
 
223
- log(` ${colorize('green', '🟢')} Installed at: ${agentDest}`);
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
- dim(` ${sub.padEnd(12)} ${count} files`);
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
- console.log(colorize('bold', ' Commands:'));
240
- console.log();
241
- console.log(` ${colorize('cyan', 'init')} Install .agent/ into current project`);
242
- console.log(` ${colorize('cyan', 'update')} Re-install to get latest version`);
243
- console.log(` ${colorize('cyan', 'status')} Check if .agent/ is installed`);
244
- console.log();
245
- console.log(colorize('bold', ' Options:'));
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
- console.log(` ${colorize('gray', '--force')} Overwrite existing .agent/ folder`);
248
- console.log(` ${colorize('gray', '--path <dir>')} Install in specific directory`);
249
- console.log(` ${colorize('gray', '--quiet')} Suppress all output`);
250
- console.log(` ${colorize('gray', '--dry-run')} Preview actions without executing`);
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
- console.log(colorize('bold', ' Examples:'));
253
- console.log();
254
- console.log(` ${colorize('gray', 'npx tribunal-kit init')}`);
255
- console.log(` ${colorize('gray', 'npx tribunal-kit init --force')}`);
256
- console.log(` ${colorize('gray', 'npx tribunal-kit init --path ./my-app')}`);
257
- console.log(` ${colorize('gray', 'npx tribunal-kit init --dry-run')}`);
258
- console.log(` ${colorize('gray', 'npx tribunal-kit update')}`);
259
- console.log(` ${colorize('gray', 'npx tribunal-kit status')}`);
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
- switch (command) {
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": "1.0.0",
4
- "description": "Anti-Hallucination AI Agent Kit — 27 specialist agents, 17 slash commands, and Tribunal review pipeline for Cursor, Windsurf, and Antigravity.",
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/your-username/tribunal-kit",
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": "./bin/tribunal-kit.js",
20
- "tk": "./bin/tribunal-kit.js"
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
+ }