tribunal-kit 4.4.2 → 4.4.4
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/scripts/marathon_harness.js +896 -0
- package/.agent/scripts/prompt_compiler.js +87 -0
- package/.agent/skills/agent-organizer/SKILL.md +42 -0
- package/.agent/skills/agentic-patterns/SKILL.md +42 -0
- package/.agent/skills/ai-prompt-injection-defense/SKILL.md +42 -0
- package/.agent/skills/api-patterns/SKILL.md +42 -0
- package/.agent/skills/api-security-auditor/SKILL.md +42 -0
- package/.agent/skills/app-builder/SKILL.md +42 -0
- package/.agent/skills/appflow-wireframe/SKILL.md +42 -0
- package/.agent/skills/architecture/SKILL.md +42 -0
- package/.agent/skills/authentication-best-practices/SKILL.md +42 -0
- package/.agent/skills/backend-security-expert/SKILL.md +122 -0
- package/.agent/skills/bash-linux/SKILL.md +42 -0
- package/.agent/skills/behavioral-modes/SKILL.md +42 -0
- package/.agent/skills/brainstorming/SKILL.md +42 -0
- package/.agent/skills/building-native-ui/SKILL.md +42 -0
- package/.agent/skills/clean-code/SKILL.md +42 -0
- package/.agent/skills/code-review-checklist/SKILL.md +42 -0
- package/.agent/skills/config-validator/SKILL.md +42 -0
- package/.agent/skills/csharp-developer/SKILL.md +42 -0
- package/.agent/skills/data-validation-schemas/SKILL.md +42 -0
- package/.agent/skills/database-design/SKILL.md +42 -0
- package/.agent/skills/deployment-procedures/SKILL.md +42 -0
- package/.agent/skills/devops-engineer/SKILL.md +42 -0
- package/.agent/skills/devops-incident-responder/SKILL.md +42 -0
- package/.agent/skills/documentation-templates/SKILL.md +42 -0
- package/.agent/skills/edge-computing/SKILL.md +42 -0
- package/.agent/skills/error-resilience/SKILL.md +42 -0
- package/.agent/skills/extract-design-system/SKILL.md +42 -0
- package/.agent/skills/framer-motion-expert/SKILL.md +42 -0
- package/.agent/skills/frontend-design/SKILL.md +42 -0
- package/.agent/skills/frontend-security-expert/SKILL.md +123 -0
- package/.agent/skills/game-design-expert/SKILL.md +42 -0
- package/.agent/skills/game-engineering-expert/SKILL.md +42 -0
- package/.agent/skills/geo-fundamentals/SKILL.md +42 -0
- package/.agent/skills/github-operations/SKILL.md +42 -0
- package/.agent/skills/gsap-core/SKILL.md +42 -0
- package/.agent/skills/gsap-frameworks/SKILL.md +42 -0
- package/.agent/skills/gsap-performance/SKILL.md +42 -0
- package/.agent/skills/gsap-plugins/SKILL.md +42 -0
- package/.agent/skills/gsap-react/SKILL.md +42 -0
- package/.agent/skills/gsap-scrolltrigger/SKILL.md +42 -0
- package/.agent/skills/gsap-timeline/SKILL.md +42 -0
- package/.agent/skills/gsap-utils/SKILL.md +42 -0
- package/.agent/skills/i18n-localization/SKILL.md +42 -0
- package/.agent/skills/intelligent-routing/SKILL.md +42 -0
- package/.agent/skills/knowledge-graph/SKILL.md +42 -0
- package/.agent/skills/lint-and-validate/SKILL.md +42 -0
- package/.agent/skills/llm-engineering/SKILL.md +42 -0
- package/.agent/skills/local-first/SKILL.md +42 -0
- package/.agent/skills/mcp-builder/SKILL.md +42 -0
- package/.agent/skills/mobile-design/SKILL.md +42 -0
- package/.agent/skills/monorepo-management/SKILL.md +42 -0
- package/.agent/skills/motion-engineering/SKILL.md +42 -0
- package/.agent/skills/nextjs-react-expert/SKILL.md +42 -0
- package/.agent/skills/nodejs-best-practices/SKILL.md +42 -0
- package/.agent/skills/observability/SKILL.md +42 -0
- package/.agent/skills/parallel-agents/SKILL.md +42 -0
- package/.agent/skills/performance-profiling/SKILL.md +42 -0
- package/.agent/skills/plan-writing/SKILL.md +42 -0
- package/.agent/skills/platform-engineer/SKILL.md +42 -0
- package/.agent/skills/playwright-best-practices/SKILL.md +42 -0
- package/.agent/skills/powershell-windows/SKILL.md +42 -0
- package/.agent/skills/project-idioms/SKILL.md +42 -0
- package/.agent/skills/python-patterns/SKILL.md +42 -0
- package/.agent/skills/python-pro/SKILL.md +42 -0
- package/.agent/skills/react-specialist/SKILL.md +42 -0
- package/.agent/skills/readme-builder/SKILL.md +42 -0
- package/.agent/skills/realtime-patterns/SKILL.md +42 -0
- package/.agent/skills/red-team-tactics/SKILL.md +42 -0
- package/.agent/skills/rust-pro/SKILL.md +42 -0
- package/.agent/skills/seo-fundamentals/SKILL.md +42 -0
- package/.agent/skills/server-management/SKILL.md +42 -0
- package/.agent/skills/shadcn-ui-expert/SKILL.md +42 -0
- package/.agent/skills/skill-creator/SKILL.md +42 -0
- package/.agent/skills/sql-pro/SKILL.md +42 -0
- package/.agent/skills/supabase-postgres-best-practices/SKILL.md +42 -0
- package/.agent/skills/swiftui-expert/SKILL.md +42 -0
- package/.agent/skills/systematic-debugging/SKILL.md +42 -0
- package/.agent/skills/tailwind-patterns/SKILL.md +42 -0
- package/.agent/skills/tdd-workflow/SKILL.md +42 -0
- package/.agent/skills/test-result-analyzer/SKILL.md +42 -0
- package/.agent/skills/testing-patterns/SKILL.md +42 -0
- package/.agent/skills/trend-researcher/SKILL.md +42 -0
- package/.agent/skills/typescript-advanced/SKILL.md +42 -0
- package/.agent/skills/ui-ux-pro-max/SKILL.md +42 -0
- package/.agent/skills/ui-ux-researcher/SKILL.md +42 -0
- package/.agent/skills/vue-expert/SKILL.md +42 -0
- package/.agent/skills/vulnerability-scanner/SKILL.md +42 -0
- package/.agent/skills/web-accessibility-auditor/SKILL.md +42 -0
- package/.agent/skills/web-design-guidelines/SKILL.md +42 -0
- package/.agent/skills/webapp-testing/SKILL.md +42 -0
- package/.agent/skills/whimsy-injector/SKILL.md +42 -0
- package/.agent/skills/workflow-optimizer/SKILL.md +42 -0
- package/.agent/workflows/marathon.md +247 -0
- package/.agent/workflows/super-prompt.md +27 -0
- package/README.md +113 -242
- package/bin/tribunal-kit.js +49 -3
- package/package.json +3 -2
- package/.agent/scripts/append_flow.js +0 -72
- package/.agent/scripts/colors.js +0 -11
- package/.agent/scripts/compress_skills.js +0 -141
- package/.agent/scripts/consolidate_skills.js +0 -149
- package/.agent/scripts/deep_compress.js +0 -150
- package/.agent/scripts/patch_skills_meta.js +0 -156
- package/.agent/scripts/patch_skills_output.js +0 -244
- package/.agent/scripts/strip_tribunal.js +0 -47
- package/.agent/scripts/utils.js +0 -17
package/bin/tribunal-kit.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* tribunal-kit CLI (alias: tk)
|
|
4
4
|
*
|
|
@@ -743,6 +743,9 @@ async function runWithUpdateCheck(command, flags) {
|
|
|
743
743
|
case 'context':
|
|
744
744
|
cmdContext(flags);
|
|
745
745
|
break;
|
|
746
|
+
case 'marathon':
|
|
747
|
+
cmdMarathon(flags);
|
|
748
|
+
break;
|
|
746
749
|
case 'uninstall':
|
|
747
750
|
cmdUninstall(flags);
|
|
748
751
|
break;
|
|
@@ -956,6 +959,7 @@ function cmdHelp() {
|
|
|
956
959
|
log(cmd('graph', 'Build and visualize the architecture graph'));
|
|
957
960
|
log(cmd('mutate', 'Run the Mutation Engine to test test-suite reliability'));
|
|
958
961
|
log(cmd('context', 'Retrieve a highly-optimized Context Snapshot for a file'));
|
|
962
|
+
log(cmd('marathon', 'Long-running agent harness (init, status, next, mark)'));
|
|
959
963
|
log(cmd('hook', 'Install pre-push git hook for auto-learning'));
|
|
960
964
|
log(cmd('uninstall','Remove .agent/ folder from project'));
|
|
961
965
|
console.log();
|
|
@@ -994,12 +998,54 @@ function cmdHelp() {
|
|
|
994
998
|
log(ex('tk case overrule --id 1'));
|
|
995
999
|
log(ex('tk graph'));
|
|
996
1000
|
log(ex('tk mutate src/utils.js "npm test"'));
|
|
1001
|
+
log(ex('tk marathon init "Build a todo app"'));
|
|
1002
|
+
log(ex('tk marathon status'));
|
|
1003
|
+
log(ex('tk marathon next'));
|
|
1004
|
+
log(ex('tk marathon mark 5 pass'));
|
|
997
1005
|
log(ex('tk hook'));
|
|
998
1006
|
log(ex('tk uninstall'));
|
|
999
1007
|
console.log();
|
|
1000
1008
|
}
|
|
1001
1009
|
|
|
1002
1010
|
|
|
1011
|
+
function cmdMarathon(flags) {
|
|
1012
|
+
const targetDir = flags.path ? path.resolve(flags.path) : process.cwd();
|
|
1013
|
+
const agentDest = path.join(targetDir, '.agent');
|
|
1014
|
+
|
|
1015
|
+
if (!fs.existsSync(agentDest)) {
|
|
1016
|
+
err('.agent/ not found. Run: npx tribunal-kit init');
|
|
1017
|
+
process.exit(1);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
const args = process.argv.slice(3);
|
|
1021
|
+
const argsStr = args.join(' ');
|
|
1022
|
+
if (args.length === 0 || args[0] === 'help' || args[0] === '--help' || args[0] === '-h') {
|
|
1023
|
+
banner();
|
|
1024
|
+
log(` ${c('cyan', '╔' + '═'.repeat(60) + '╗')}`);
|
|
1025
|
+
log(` ${c('cyan', '║')}${c('bold', c('white', ' Marathon — Long-Running Agent Harness '))}${c('cyan', '║')}`);
|
|
1026
|
+
log(` ${c('cyan', '╚' + '═'.repeat(60) + '╝')}`);
|
|
1027
|
+
console.log();
|
|
1028
|
+
log(` ${c('cyan', 'init'.padEnd(16))} ${c('gray', 'Start a new marathon (init "spec")')}`);
|
|
1029
|
+
log(` ${c('cyan', 'status'.padEnd(16))} ${c('gray', 'Show progress dashboard')}`);
|
|
1030
|
+
log(` ${c('cyan', 'next'.padEnd(16))} ${c('gray', 'Show next unfinished feature')}`);
|
|
1031
|
+
log(` ${c('cyan', 'mark'.padEnd(16))} ${c('gray', 'Mark feature pass/fail (mark <id> pass)')}`);
|
|
1032
|
+
log(` ${c('cyan', 'log'.padEnd(16))} ${c('gray', 'Add a progress note')}`);
|
|
1033
|
+
log(` ${c('cyan', 'session-start'.padEnd(16))} ${c('gray', 'Begin a new work session')}`);
|
|
1034
|
+
log(` ${c('cyan', 'session-end'.padEnd(16))} ${c('gray', 'End session with summary')}`);
|
|
1035
|
+
log(` ${c('cyan', 'add-feature'.padEnd(16))} ${c('gray', 'Add feature: "category" "desc" "step1" ...')}`);
|
|
1036
|
+
log(` ${c('cyan', 'reset'.padEnd(16))} ${c('gray', 'Archive and start fresh')}`);
|
|
1037
|
+
console.log();
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
const marathonScript = path.join(agentDest, 'scripts', 'marathon_harness.js');
|
|
1042
|
+
try {
|
|
1043
|
+
execSync(`node "${marathonScript}" ${argsStr}`, { stdio: 'inherit', cwd: targetDir });
|
|
1044
|
+
} catch {
|
|
1045
|
+
process.exit(1);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1003
1049
|
function cmdContext(flags) {
|
|
1004
1050
|
const targetDir = flags.path ? path.resolve(flags.path) : process.cwd();
|
|
1005
1051
|
const agentDest = path.join(targetDir, '.agent');
|
|
@@ -1071,5 +1117,5 @@ runWithUpdateCheck(command, flags);
|
|
|
1071
1117
|
|
|
1072
1118
|
// -- Exports (for testing) -- do not remove
|
|
1073
1119
|
if (require.main !== module) {
|
|
1074
|
-
module.exports = { parseArgs, compareSemver, copyDir, countDir, isSelfInstall, CORE_AGENTS, CORE_SKILLS, generateIDEBridges };
|
|
1075
|
-
}
|
|
1120
|
+
module.exports = { parseArgs, compareSemver, copyDir, countDir, isSelfInstall, CORE_AGENTS, CORE_SKILLS, generateIDEBridges, cmdMarathon };
|
|
1121
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tribunal-kit",
|
|
3
|
-
"version": "4.4.
|
|
4
|
-
"description": "Anti-Hallucination AI Agent Kit — 40 specialist agents,
|
|
3
|
+
"version": "4.4.4",
|
|
4
|
+
"description": "Anti-Hallucination AI Agent Kit — 40 specialist agents, 32 slash commands, 16 parallel Tribunal reviewers, Performance Swarm engine, Supreme Court case law pipeline, and long-running agent harness.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
7
7
|
"ai-agent",
|
|
8
|
+
"long-running-agents",
|
|
8
9
|
"agent",
|
|
9
10
|
"agents",
|
|
10
11
|
"multi-agent",
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// append_flow.js — append Supreme Court section to AGENT_FLOW.md
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const f = 'AGENT_FLOW.md';
|
|
5
|
-
|
|
6
|
-
const appendix = [
|
|
7
|
-
'',
|
|
8
|
-
'---',
|
|
9
|
-
'',
|
|
10
|
-
'## Supreme Court Edition — Self-Learning Engine',
|
|
11
|
-
'',
|
|
12
|
-
'Tribunal Kit v4.0+ ships two industry-first features that transform the',
|
|
13
|
-
'agent kit from a reactive reviewer into a **persistent engineering authority**.',
|
|
14
|
-
'',
|
|
15
|
-
'### 1 — Case Law Engine',
|
|
16
|
-
'',
|
|
17
|
-
'Every rejected pattern becomes binding legal precedent.',
|
|
18
|
-
'',
|
|
19
|
-
'| Step | What Happens |',
|
|
20
|
-
'|:-----|:-------------|',
|
|
21
|
-
'| 1 | Developer rejects AI proposal |',
|
|
22
|
-
'| 2 | Runs `case_law_manager.py add-case` |',
|
|
23
|
-
'| 3 | diff + tags + reason stored in `.agent/history/case-law/` |',
|
|
24
|
-
'| 4 | `precedence-reviewer` queries index on every future `/generate` or `/review` |',
|
|
25
|
-
'| 5 | Jaccard tag match score >= 0.4 → PRECEDENCE HOLD |',
|
|
26
|
-
'',
|
|
27
|
-
'### 2 — Skill Evolution Forge',
|
|
28
|
-
'',
|
|
29
|
-
'The agent kit writes its own skills by learning from your commits.',
|
|
30
|
-
'',
|
|
31
|
-
'| Step | What Happens |',
|
|
32
|
-
'|:-----|:-------------|',
|
|
33
|
-
'| 1 | Developer commits code different from AI proposal |',
|
|
34
|
-
'| 2 | `tribunal-kit learn` (or `skill_evolution.py digest`) |',
|
|
35
|
-
'| 3 | Semantic Delta Filter strips trivial noise (70-90% token reduction) |',
|
|
36
|
-
'| 4 | Minimal LLM Reflection Prompt (< 500 tokens) |',
|
|
37
|
-
'| 5 | YAML idioms merged into `.agent/skills/project-idioms/SKILL.md` |',
|
|
38
|
-
'| 6 | All agents inherit these idioms on next activation |',
|
|
39
|
-
'',
|
|
40
|
-
'### CLI Commands (Supreme Court)',
|
|
41
|
-
'',
|
|
42
|
-
'| Command | Action |',
|
|
43
|
-
'|:--------|:-------|',
|
|
44
|
-
'| `tribunal-kit learn` | Run Skill Evolution + Case Law prompt |',
|
|
45
|
-
'| `tribunal-kit learn --dry-run` | Preview delta without writing |',
|
|
46
|
-
'| `tribunal-kit learn --head` | Diff last commit instead of staged |',
|
|
47
|
-
'| `python .agent/scripts/case_law_manager.py add-case` | Record a rejection |',
|
|
48
|
-
'| `python .agent/scripts/case_law_manager.py search-cases --query "..."` | Find precedents |',
|
|
49
|
-
'| `python .agent/scripts/skill_evolution.py digest` | Run evolution cycle |',
|
|
50
|
-
'| `python .agent/scripts/skill_evolution.py status` | Token savings report |',
|
|
51
|
-
'',
|
|
52
|
-
'### Review Order (Updated)',
|
|
53
|
-
'',
|
|
54
|
-
'```',
|
|
55
|
-
'1. precedence-reviewer <- FIRST (Case Law check, zero LLM tokens)',
|
|
56
|
-
'2. logic-reviewer',
|
|
57
|
-
'3. security-auditor',
|
|
58
|
-
'4. domain-specific reviewers',
|
|
59
|
-
'5. Human Gate',
|
|
60
|
-
'```',
|
|
61
|
-
'',
|
|
62
|
-
'### New Reviewer',
|
|
63
|
-
'',
|
|
64
|
-
'| Reviewer | Activates for | Catches |',
|
|
65
|
-
'|:---------|:-------------|:--------|',
|
|
66
|
-
'| `precedence-reviewer` | All domains | Violations of previously rejected patterns |',
|
|
67
|
-
'',
|
|
68
|
-
].join('\n');
|
|
69
|
-
|
|
70
|
-
let existing = fs.readFileSync(f, 'utf8').trimEnd();
|
|
71
|
-
fs.writeFileSync(f, existing + appendix + '\n', 'utf8');
|
|
72
|
-
console.log('AGENT_FLOW.md updated.');
|
package/.agent/scripts/colors.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* colors.js — Backward-compatible re-export of _colors.js
|
|
3
|
-
* ════════════════════════════════════════════════════════
|
|
4
|
-
* All color constants and helpers are defined in _colors.js.
|
|
5
|
-
* This file re-exports them for scripts that import from './colors.js'.
|
|
6
|
-
*
|
|
7
|
-
* New scripts should import from './_colors' directly.
|
|
8
|
-
*/
|
|
9
|
-
'use strict';
|
|
10
|
-
|
|
11
|
-
module.exports = require('./_colors');
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// compress_skills.js - Aggressive token reduction for .agent/skills/**/*.md files
|
|
3
|
-
|
|
4
|
-
'use strict';
|
|
5
|
-
|
|
6
|
-
const fs = require('fs');
|
|
7
|
-
const path = require('path');
|
|
8
|
-
|
|
9
|
-
const SECTION_PATTERNS = [
|
|
10
|
-
/^## 🏛️ Tribunal Integration[\s\S]*?(?=\n## |\n# |$)/gm,
|
|
11
|
-
/^## Tribunal Integration[\s\S]*?(?=\n## |\n# |$)/gm,
|
|
12
|
-
/^### ✅ Pre-Flight Self-Audit[\s\S]*?(?=\n## |\n### |\n# |$)/gm,
|
|
13
|
-
/^## Pre-Flight Self-Audit[\s\S]*?(?=\n## |\n# |$)/gm,
|
|
14
|
-
/^## Cross-Workflow Navigation[\s\S]*?(?=\n## |\n# |$)/gm,
|
|
15
|
-
/^## Output Format\s*\n```[\s\S]*?```\s*\n/gm,
|
|
16
|
-
/^## VBC Protocol[\s\S]*?(?=\n## |\n# |$)/gm,
|
|
17
|
-
/^## LLM Traps[\s\S]*?(?=\n## |\n# |$)/gm,
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
const CHATTY_INTRO = /(^# .+\n)\n[A-Z][^#\n]{60,}\n[A-Z][^#\n]{40,}\n\n---/gm;
|
|
21
|
-
|
|
22
|
-
function stripChattyIntro(content) {
|
|
23
|
-
return content.replace(CHATTY_INTRO, '$1\n---');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const OBVIOUS_COMMENT = /^(\s*)(\/\/ (default for most properties|shorthand|number of repeats|default: \d+|spring tension|resistance|weight|approximate duration|deceleration rate)[^\n]*)\n/gm;
|
|
27
|
-
|
|
28
|
-
function stripObviousComments(content) {
|
|
29
|
-
return content.replace(OBVIOUS_COMMENT, '');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const PERF_TEXT_BLOCK = /^```\n(✅ Use \w[^\n]*\n → [^\n]*\n\n?){3,}```\n/gm;
|
|
33
|
-
|
|
34
|
-
function compressPerfBlocks(content) {
|
|
35
|
-
return content.replace(PERF_TEXT_BLOCK, (match) => {
|
|
36
|
-
const lines = match.replace(/`|\n$/g, '').split('\n');
|
|
37
|
-
const bullets = [];
|
|
38
|
-
for (const line of lines) {
|
|
39
|
-
const stripped = line.trim();
|
|
40
|
-
if (stripped.startsWith('✅') || stripped.startsWith('❌')) {
|
|
41
|
-
bullets.push(`- ${stripped}`);
|
|
42
|
-
} else if (stripped.startsWith('→')) {
|
|
43
|
-
bullets[bullets.length - 1] += ` (${stripped.substring(1).trim()})`;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return bullets.join('\n') + '\n';
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function collapseBlanks(content) {
|
|
51
|
-
return content.replace(/\n{3,}/g, '\n\n');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const FILLER_BEFORE_SECTION = /(^# .+\n\n)([A-Z][^\n]+\n){1,4}(\n---\n)/gm;
|
|
55
|
-
|
|
56
|
-
function removeFillerBetweenTitleAndHr(content) {
|
|
57
|
-
return content.replace(FILLER_BEFORE_SECTION, '$1$3');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const REDUNDANT_NOTE = /^\/\/ (motion\.\w+|Any HTML|Note:|Variant names propagate|\/\/ )[^\n]*\n/gm;
|
|
61
|
-
|
|
62
|
-
function stripRedundantNotes(content) {
|
|
63
|
-
return content.replace(REDUNDANT_NOTE, '');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function compressFile(filePath) {
|
|
67
|
-
const original = fs.readFileSync(filePath, 'utf8');
|
|
68
|
-
let content = original;
|
|
69
|
-
|
|
70
|
-
for (const pattern of SECTION_PATTERNS) {
|
|
71
|
-
content = content.replace(pattern, '');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
content = stripChattyIntro(content);
|
|
75
|
-
content = removeFillerBetweenTitleAndHr(content);
|
|
76
|
-
content = stripObviousComments(content);
|
|
77
|
-
content = stripRedundantNotes(content);
|
|
78
|
-
content = compressPerfBlocks(content);
|
|
79
|
-
content = collapseBlanks(content);
|
|
80
|
-
|
|
81
|
-
const originalLen = Buffer.byteLength(original, 'utf8');
|
|
82
|
-
const newLen = Buffer.byteLength(content.trim() + '\n', 'utf8');
|
|
83
|
-
|
|
84
|
-
fs.writeFileSync(filePath, content.trim() + '\n', 'utf8');
|
|
85
|
-
return [originalLen, newLen, originalLen - newLen];
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function main() {
|
|
89
|
-
const base = '.agent/skills';
|
|
90
|
-
if (!fs.existsSync(base)) {
|
|
91
|
-
console.error(`ERROR: '${base}' not found. Run from tribunal-kit root.`);
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let totalOrig = 0;
|
|
96
|
-
let totalNew = 0;
|
|
97
|
-
const results = [];
|
|
98
|
-
|
|
99
|
-
function walkDir(dir) {
|
|
100
|
-
const items = fs.readdirSync(dir, { withFileTypes: true });
|
|
101
|
-
for (const item of items) {
|
|
102
|
-
const fpath = path.join(dir, item.name);
|
|
103
|
-
if (item.isDirectory()) {
|
|
104
|
-
walkDir(fpath);
|
|
105
|
-
} else if (item.name.endsWith('.md')) {
|
|
106
|
-
const [orig, newL, saved] = compressFile(fpath);
|
|
107
|
-
totalOrig += orig;
|
|
108
|
-
totalNew += newL;
|
|
109
|
-
if (saved > 0) {
|
|
110
|
-
results.push([saved, fpath]);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
walkDir(base);
|
|
117
|
-
results.sort((a, b) => b[0] - a[0]);
|
|
118
|
-
|
|
119
|
-
console.log(`\n${'='.repeat(55)}`);
|
|
120
|
-
console.log(` Skill Compression Complete`);
|
|
121
|
-
console.log(`${'='.repeat(55)}`);
|
|
122
|
-
console.log(` Original : ${totalOrig} bytes (${Math.floor(totalOrig / 1024)}KB)`);
|
|
123
|
-
console.log(` After : ${totalNew} bytes (${Math.floor(totalNew / 1024)}KB)`);
|
|
124
|
-
|
|
125
|
-
const savedTotal = totalOrig - totalNew;
|
|
126
|
-
const pct = totalOrig ? (savedTotal / totalOrig * 100) : 0;
|
|
127
|
-
console.log(` Saved : ${savedTotal} bytes (${Math.floor(savedTotal / 1024)}KB) — ${pct.toFixed(1)}%`);
|
|
128
|
-
console.log(`\n Top savings:`);
|
|
129
|
-
|
|
130
|
-
for (const [saved, filePath] of results.slice(0, 15)) {
|
|
131
|
-
const parts = filePath.split(path.sep);
|
|
132
|
-
const skill = parts[parts.length - 2];
|
|
133
|
-
const fname = parts[parts.length - 1];
|
|
134
|
-
console.log(` -${Math.floor(saved / 1024).toString().padStart(2, ' ')}KB ${skill}/${fname}`);
|
|
135
|
-
}
|
|
136
|
-
console.log();
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (require.main === module) {
|
|
140
|
-
main();
|
|
141
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* consolidate_skills.js
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
|
|
11
|
-
const BASE = '.agent/skills';
|
|
12
|
-
|
|
13
|
-
const STRIP_PATTERNS = [
|
|
14
|
-
/^## 🏛️ Tribunal Integration.*?(?=\n## |$)/gms,
|
|
15
|
-
/^## Tribunal Integration.*?(?=\n## |$)/gms,
|
|
16
|
-
/^### ✅ Pre-Flight Self-Audit.*?(?=\n###|\n## |$)/gms,
|
|
17
|
-
/^## Pre-Flight Self-Audit.*?(?=\n## |$)/gms,
|
|
18
|
-
/^## Output Format\b.*?(?=\n## |$)/gms,
|
|
19
|
-
/^## 🔧 Runtime Scripts.*?(?=\n## |$)/gms,
|
|
20
|
-
/^## 🔴 MANDATORY.*?(?=\n## |$)/gms,
|
|
21
|
-
/^## ⚠️ CRITICAL: ASK BEFORE ASSUMING.*?(?=\n## |$)/gms,
|
|
22
|
-
/^## 📝 CHECKPOINT \(MANDATORY.*?(?=\n## |$)/gms,
|
|
23
|
-
/^## Output Format.*?```\n[^`]*```\n?(?=\n## |$)/gms,
|
|
24
|
-
/^\*\*Execute these for validation.*?---\n/gms,
|
|
25
|
-
/^\*\*VBC \(Verification-Before-Completion\).*?\n/gms,
|
|
26
|
-
/^\*\*⛔ DO NOT start.*?---\n?/gms,
|
|
27
|
-
/^> 🧠 \*\*mobile-design.*?\n/gms,
|
|
28
|
-
/^> \*\*STOP.*?\n/gms,
|
|
29
|
-
];
|
|
30
|
-
|
|
31
|
-
function adjustHeadings(content, offset = 1) {
|
|
32
|
-
const lines = content.split('\n');
|
|
33
|
-
const out = [];
|
|
34
|
-
for (let line of lines) {
|
|
35
|
-
const m = line.match(/^(#{1,5}) /);
|
|
36
|
-
if (m) {
|
|
37
|
-
const level = m[1].length;
|
|
38
|
-
const newLevel = Math.min(level + offset, 6);
|
|
39
|
-
line = '#'.repeat(newLevel) + line.substring(level);
|
|
40
|
-
}
|
|
41
|
-
out.push(line);
|
|
42
|
-
}
|
|
43
|
-
return out.join('\n');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function cleanContent(content) {
|
|
47
|
-
for (const p of STRIP_PATTERNS) {
|
|
48
|
-
content = content.replace(p, '');
|
|
49
|
-
}
|
|
50
|
-
content = content.replace(/\n{3,}/g, '\n\n');
|
|
51
|
-
return content.trim();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function extractFrontmatter(content) {
|
|
55
|
-
const m = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);
|
|
56
|
-
if (m) {
|
|
57
|
-
return [m[1], content.substring(m[0].length)];
|
|
58
|
-
}
|
|
59
|
-
return ['', content];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function consolidate(skillDir) {
|
|
63
|
-
const skillName = path.basename(skillDir);
|
|
64
|
-
const mainPath = path.join(skillDir, 'SKILL.md');
|
|
65
|
-
if (!fs.existsSync(mainPath)) return false;
|
|
66
|
-
|
|
67
|
-
const files = fs.readdirSync(skillDir);
|
|
68
|
-
const subFiles = files.filter(f => f.endsWith('.md') && f !== 'SKILL.md').sort();
|
|
69
|
-
|
|
70
|
-
if (subFiles.length === 0) return false;
|
|
71
|
-
|
|
72
|
-
console.log(`\n → Consolidating: ${skillName} (${subFiles.length} sub-files)`);
|
|
73
|
-
|
|
74
|
-
const mainContent = fs.readFileSync(mainPath, 'utf8');
|
|
75
|
-
let [frontmatter, mainBody] = extractFrontmatter(mainContent);
|
|
76
|
-
|
|
77
|
-
const fmLines = frontmatter.split('\n');
|
|
78
|
-
const newFm = [];
|
|
79
|
-
for (const line of fmLines) {
|
|
80
|
-
if (line.startsWith('version:')) newFm.push('version: 3.1.0');
|
|
81
|
-
else if (line.startsWith('last-updated:')) newFm.push('last-updated: 2026-04-06');
|
|
82
|
-
else newFm.push(line);
|
|
83
|
-
}
|
|
84
|
-
frontmatter = newFm.join('\n');
|
|
85
|
-
|
|
86
|
-
mainBody = cleanContent(mainBody);
|
|
87
|
-
mainBody = mainBody.replace(/\|.*?\.md.*?\|.*?\|.*?\|\n/g, '');
|
|
88
|
-
mainBody = mainBody.replace(/^\|[-| ]+\|\n/gm, '');
|
|
89
|
-
mainBody = mainBody.replace(/\n{3,}/g, '\n\n');
|
|
90
|
-
|
|
91
|
-
const mergedSections = [];
|
|
92
|
-
for (const fname of subFiles) {
|
|
93
|
-
const fpath = path.join(skillDir, fname);
|
|
94
|
-
const raw = fs.readFileSync(fpath, 'utf8');
|
|
95
|
-
let [, body] = extractFrontmatter(raw);
|
|
96
|
-
body = cleanContent(body);
|
|
97
|
-
body = adjustHeadings(body, 1);
|
|
98
|
-
if (body.trim()) {
|
|
99
|
-
mergedSections.push(body.trim());
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
let combined = `---\n${frontmatter}\n---\n\n${mainBody}`;
|
|
104
|
-
if (mergedSections.length > 0) {
|
|
105
|
-
combined += '\n\n---\n\n' + mergedSections.join('\n\n---\n\n');
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
combined = combined.replace(/\n{3,}/g, '\n\n');
|
|
109
|
-
combined = combined.trim() + '\n';
|
|
110
|
-
|
|
111
|
-
let totalSubBytes = 0;
|
|
112
|
-
for (const f of subFiles) totalSubBytes += fs.statSync(path.join(skillDir, f)).size;
|
|
113
|
-
console.log(` Sub-files total: ${Math.floor(totalSubBytes / 1024)}KB`);
|
|
114
|
-
|
|
115
|
-
fs.writeFileSync(mainPath, combined, 'utf8');
|
|
116
|
-
const newSize = fs.statSync(mainPath).size;
|
|
117
|
-
console.log(` New SKILL.md: ${Math.floor(newSize / 1024)}KB (from ${Math.floor(Buffer.byteLength(mainContent, 'utf8') / 1024)}KB main + ${Math.floor(totalSubBytes / 1024)}KB subs → ${Math.floor(newSize / 1024)}KB)`);
|
|
118
|
-
|
|
119
|
-
for (const fname of subFiles) {
|
|
120
|
-
fs.unlinkSync(path.join(skillDir, fname));
|
|
121
|
-
console.log(` Deleted: ${fname}`);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return true;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function main() {
|
|
128
|
-
const target = process.argv.length > 2 ? process.argv[2] : null;
|
|
129
|
-
|
|
130
|
-
let processed = 0;
|
|
131
|
-
if (!fs.existsSync(BASE)) return;
|
|
132
|
-
|
|
133
|
-
for (const skillName of fs.readdirSync(BASE)) {
|
|
134
|
-
const skillDir = path.join(BASE, skillName);
|
|
135
|
-
if (!fs.statSync(skillDir).isDirectory()) continue;
|
|
136
|
-
if (target && skillName !== target) continue;
|
|
137
|
-
if (consolidate(skillDir)) processed++;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (processed === 0) {
|
|
141
|
-
console.log('No skills with sub-files found (or target not matched).');
|
|
142
|
-
} else {
|
|
143
|
-
console.log(`\n✅ Consolidated ${processed} skills.`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (require.main === module) {
|
|
148
|
-
main();
|
|
149
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* deep_compress.js - Deep surgical compression for .agent/ markdown files (skills, agents, workflows).
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
|
|
11
|
-
const BASE_DIRS = ['.agent/skills', '.agent/agents', '.agent/workflows'];
|
|
12
|
-
|
|
13
|
-
const REMOVE_SECTIONS = [
|
|
14
|
-
/^## 🏛️ Tribunal Integration[\s\S]*?(?=\n## |$)/gm,
|
|
15
|
-
/^## Tribunal Integration[\s\S]*?(?=\n## |$)/gm,
|
|
16
|
-
/^### ✅ Pre-Flight Self-Audit[\s\S]*?(?=\n### |\n## |$)/gm,
|
|
17
|
-
/^## Pre-Flight Self-Audit[\s\S]*?(?=\n## |$)/gm,
|
|
18
|
-
/^## Cross-Workflow Navigation[\s\S]*?(?=\n## |$)/gm,
|
|
19
|
-
/^## LLM Traps[\s\S]*?(?=\n## |$)/gm,
|
|
20
|
-
/^## VBC Protocol[\s\S]*?(?=\n## |$)/gm,
|
|
21
|
-
/^## Output Format\n```[\s\S]*?```\n/gm,
|
|
22
|
-
/^## 🤖 LLM-Specific Traps[\s\S]*?(?=\n## |$)/gm,
|
|
23
|
-
];
|
|
24
|
-
|
|
25
|
-
const VERBOSE_COMMENT_PATTERNS = [
|
|
26
|
-
/^(\s*)\/\/\s*(?:Any HTML or SVG element|motion\.div, motion\.span|The MAGIC of|This is the key performance|The pattern that|Compound components share|Note that children|The action receives|Children inherit the|Import first|Parent controls when|It's always motion)\b[^\n]*\n/gm,
|
|
27
|
-
/^(\s*)#\s*(?:TypedDict gives you|Usage:|Note:|Return user|Return None|Automatically)\b[^\n]*\n/gm,
|
|
28
|
-
/^\s*\/\/\s*Usage:\s*\n(?=\s*[<{])/gm,
|
|
29
|
-
/^\s*#\s*Usage:\s*\n(?=\s*[{])/gm,
|
|
30
|
-
/^\s*\/\/\s*When (?:server responds|a component|React can interrupt|the React Compiler)[^\n]*\n/gm,
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
function stripChattyOpeners(content) {
|
|
34
|
-
return content.replace(/(^# .+\n)\n.{60,}\n.{30,}\n(?:\n---)/gm, '$1\n---');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function compressLegacyModernBlocks(content) {
|
|
38
|
-
const pattern = /```(\w+)\n((?:.*\n)*?.*(?:\/\/|#) ❌ LEGACY[^\n]*\n(?:.*\n)*?)```\n\n```\w+\n((?:.*\n)*?.*(?:\/\/|#) ✅ MODERN[^\n]*\n(?:.*\n)*?)```/gm;
|
|
39
|
-
return content.replace(pattern, (match, lang, legacy, modern) => {
|
|
40
|
-
const totalLines = (legacy.match(/\n/g) || []).length + (modern.match(/\n/g) || []).length;
|
|
41
|
-
if (totalLines > 28) return match;
|
|
42
|
-
return `\`\`\`${lang}\n// ❌ LEGACY\n${legacy.trim()}\n\n// ✅ MODERN\n${modern.trim()}\n\`\`\``;
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function stripEmptyComments(content) {
|
|
47
|
-
content = content.replace(/^\s*\/\/\s*$\n/gm, '');
|
|
48
|
-
content = content.replace(/^\s*#\s*$\n/gm, '');
|
|
49
|
-
return content;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function dedupBulletPoints(content) {
|
|
53
|
-
const lines = content.split('\n');
|
|
54
|
-
const seenBullets = {};
|
|
55
|
-
const output = [];
|
|
56
|
-
for (let i = 0; i < lines.length; i++) {
|
|
57
|
-
const line = lines[i];
|
|
58
|
-
const stripped = line.trim();
|
|
59
|
-
if (/^(✅|❌|- ✅|- ❌)/.test(stripped)) {
|
|
60
|
-
if (seenBullets[stripped] !== undefined && (i - seenBullets[stripped]) < 80) {
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
seenBullets[stripped] = i;
|
|
64
|
-
}
|
|
65
|
-
output.push(line);
|
|
66
|
-
}
|
|
67
|
-
return output.join('\n');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function collapseBlanks(content) {
|
|
71
|
-
return content.replace(/\n{3,}/g, '\n\n');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function compressFile(filePath) {
|
|
75
|
-
const original = fs.readFileSync(filePath, 'utf8');
|
|
76
|
-
let content = original;
|
|
77
|
-
|
|
78
|
-
for (const pattern of REMOVE_SECTIONS) {
|
|
79
|
-
content = content.replace(pattern, '');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
content = stripChattyOpeners(content);
|
|
83
|
-
content = compressLegacyModernBlocks(content);
|
|
84
|
-
|
|
85
|
-
for (const pattern of VERBOSE_COMMENT_PATTERNS) {
|
|
86
|
-
content = content.replace(pattern, '');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
content = stripEmptyComments(content);
|
|
90
|
-
content = dedupBulletPoints(content);
|
|
91
|
-
content = collapseBlanks(content);
|
|
92
|
-
|
|
93
|
-
if (content.trim() !== original.trim()) {
|
|
94
|
-
fs.writeFileSync(filePath, content.trim() + '\n', 'utf8');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return [Buffer.byteLength(original, 'utf8'), Buffer.byteLength(content, 'utf8')];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function main() {
|
|
101
|
-
let totalOrig = 0;
|
|
102
|
-
let totalNew = 0;
|
|
103
|
-
const fileResults = [];
|
|
104
|
-
|
|
105
|
-
function walkDir(dir) {
|
|
106
|
-
let items;
|
|
107
|
-
try { items = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
|
108
|
-
for (const item of items) {
|
|
109
|
-
const fpath = path.join(dir, item.name);
|
|
110
|
-
if (item.isDirectory()) walkDir(fpath);
|
|
111
|
-
else if (item.name.endsWith('.md')) {
|
|
112
|
-
const [orig, newL] = compressFile(fpath);
|
|
113
|
-
totalOrig += orig;
|
|
114
|
-
totalNew += newL;
|
|
115
|
-
const saved = orig - newL;
|
|
116
|
-
if (saved > 200) {
|
|
117
|
-
fileResults.push([saved, fpath]);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
for (const base of BASE_DIRS) {
|
|
124
|
-
if (fs.existsSync(base)) walkDir(base);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
fileResults.sort((a, b) => b[0] - a[0]);
|
|
128
|
-
|
|
129
|
-
const savedTotal = totalOrig - totalNew;
|
|
130
|
-
const pct = totalOrig ? (savedTotal / totalOrig * 100) : 0;
|
|
131
|
-
|
|
132
|
-
console.log(`\n${'='.repeat(58)}`);
|
|
133
|
-
console.log(` Deep Compression Complete`);
|
|
134
|
-
console.log(`${'='.repeat(58)}`);
|
|
135
|
-
console.log(` Original : ${totalOrig} bytes (${Math.floor(totalOrig / 1024)}KB)`);
|
|
136
|
-
console.log(` After : ${totalNew} bytes (${Math.floor(totalNew / 1024)}KB)`);
|
|
137
|
-
console.log(` Saved : ${savedTotal} bytes (${Math.floor(savedTotal / 1024)}KB) — ${pct.toFixed(1)}%`);
|
|
138
|
-
console.log(`\n Top savings:`);
|
|
139
|
-
|
|
140
|
-
for (const [saved, filePath] of fileResults.slice(0, 20)) {
|
|
141
|
-
const parts = filePath.split(path.sep);
|
|
142
|
-
const skill = parts.length >= 2 ? `${parts[parts.length - 2]}/${parts[parts.length - 1]}` : filePath;
|
|
143
|
-
console.log(` -${Math.floor(saved / 1024).toString().padStart(2, ' ')}KB ${skill}`);
|
|
144
|
-
}
|
|
145
|
-
console.log();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (require.main === module) {
|
|
149
|
-
main();
|
|
150
|
-
}
|