tribunal-kit 4.3.1 → 4.4.1

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 (67) hide show
  1. package/.agent/agents/api-architect.md +66 -66
  2. package/.agent/agents/db-latency-auditor.md +216 -216
  3. package/.agent/agents/precedence-reviewer.md +250 -250
  4. package/.agent/agents/resilience-reviewer.md +88 -88
  5. package/.agent/agents/schema-reviewer.md +67 -67
  6. package/.agent/agents/throughput-optimizer.md +299 -299
  7. package/.agent/agents/ui-ux-auditor.md +292 -292
  8. package/.agent/agents/vitals-reviewer.md +223 -223
  9. package/.agent/scripts/_colors.js +18 -18
  10. package/.agent/scripts/_utils.js +42 -42
  11. package/.agent/scripts/append_flow.js +72 -72
  12. package/.agent/scripts/auto_preview.js +197 -197
  13. package/.agent/scripts/bundle_analyzer.js +290 -290
  14. package/.agent/scripts/case_law_manager.js +17 -6
  15. package/.agent/scripts/checklist.js +266 -266
  16. package/.agent/scripts/colors.js +17 -17
  17. package/.agent/scripts/compress_skills.js +141 -141
  18. package/.agent/scripts/consolidate_skills.js +149 -149
  19. package/.agent/scripts/context_broker.js +611 -609
  20. package/.agent/scripts/deep_compress.js +150 -150
  21. package/.agent/scripts/dependency_analyzer.js +272 -272
  22. package/.agent/scripts/graph_builder.js +151 -37
  23. package/.agent/scripts/graph_visualizer.js +384 -0
  24. package/.agent/scripts/inner_loop_validator.js +451 -465
  25. package/.agent/scripts/lint_runner.js +187 -187
  26. package/.agent/scripts/minify_context.js +100 -100
  27. package/.agent/scripts/mutation_runner.js +280 -0
  28. package/.agent/scripts/patch_skills_meta.js +156 -156
  29. package/.agent/scripts/patch_skills_output.js +244 -244
  30. package/.agent/scripts/schema_validator.js +297 -297
  31. package/.agent/scripts/security_scan.js +303 -303
  32. package/.agent/scripts/session_manager.js +276 -276
  33. package/.agent/scripts/skill_evolution.js +644 -644
  34. package/.agent/scripts/skill_integrator.js +313 -313
  35. package/.agent/scripts/strengthen_skills.js +193 -193
  36. package/.agent/scripts/strip_tribunal.js +47 -47
  37. package/.agent/scripts/swarm_dispatcher.js +360 -360
  38. package/.agent/scripts/test_runner.js +193 -193
  39. package/.agent/scripts/utils.js +32 -32
  40. package/.agent/scripts/verify_all.js +257 -256
  41. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +1 -1
  42. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +1 -1
  43. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +1 -1
  44. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +1 -1
  45. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +1 -1
  46. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +1 -1
  47. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +1 -1
  48. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +1 -1
  49. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
  50. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +1 -1
  51. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +1 -1
  52. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +1 -1
  53. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +1 -1
  54. package/.agent/skills/doc.md +1 -1
  55. package/.agent/skills/knowledge-graph/SKILL.md +32 -16
  56. package/.agent/skills/testing-patterns/SKILL.md +19 -2
  57. package/.agent/skills/ui-ux-pro-max/SKILL.md +480 -43
  58. package/.agent/workflows/generate.md +183 -183
  59. package/.agent/workflows/tribunal-speed.md +183 -183
  60. package/README.md +1 -1
  61. package/bin/tribunal-kit.js +134 -17
  62. package/package.json +6 -3
  63. package/scripts/changelog.js +167 -167
  64. package/scripts/sync-version.js +81 -81
  65. package/.agent/scripts/__pycache__/_colors.cpython-311.pyc +0 -0
  66. package/.agent/scripts/__pycache__/_utils.cpython-311.pyc +0 -0
  67. package/.agent/scripts/__pycache__/case_law_manager.cpython-311.pyc +0 -0
@@ -1,187 +1,187 @@
1
- #!/usr/bin/env node
2
- /**
3
- * lint_runner.js — Standalone lint runner for the Tribunal Agent Kit.
4
- *
5
- * Usage:
6
- * node .agent/scripts/lint_runner.js .
7
- * node .agent/scripts/lint_runner.js . --fix
8
- * node .agent/scripts/lint_runner.js . --files src/index.ts src/utils.ts
9
- */
10
-
11
- 'use strict';
12
-
13
- const fs = require('fs');
14
- const path = require('path');
15
- const { spawnSync } = require('child_process');
16
-
17
- const { RED, GREEN, YELLOW, BLUE, BOLD, RESET } = require('./colors.js');
18
-
19
- function header(title) {
20
- console.log(`\n${BOLD}${BLUE}━━━ ${title} ━━━${RESET}`);
21
- }
22
-
23
- function ok(msg) {
24
- console.log(` ${GREEN}✅ ${msg}${RESET}`);
25
- }
26
-
27
- function fail(msg) {
28
- console.log(` ${RED}❌ ${msg}${RESET}`);
29
- }
30
-
31
- function skip(msg) {
32
- console.log(` ${YELLOW}⏭️ ${msg}${RESET}`);
33
- }
34
-
35
- function runLinter(label, cmd, cwd) {
36
- try {
37
- const executable = process.platform === 'win32' && cmd[0] === 'npx' ? 'npx.cmd' : cmd[0];
38
- const result = spawnSync(executable, cmd.slice(1), {
39
- cwd,
40
- encoding: 'utf8',
41
- timeout: 120000,
42
- shell: process.platform === 'win32'
43
- });
44
-
45
- if (result.status === 0) {
46
- ok(`${label} — clean`);
47
- return true;
48
- }
49
-
50
- fail(`${label} — issues found`);
51
- if (result.error) {
52
- console.log(` Error: ${result.error.message}`);
53
- }
54
- const out = result.stdout ? result.stdout.toString() : '';
55
- const err = result.stderr ? result.stderr.toString() : '';
56
- const output = (out + "\n" + err).trim();
57
- if (output) {
58
- const lines = output.split('\n');
59
- for (const line of lines.slice(0, 15)) {
60
- console.log(` ${line}`);
61
- }
62
- if (lines.length > 15) {
63
- console.log(` ... and ${lines.length - 15} more lines`);
64
- }
65
- }
66
- return false;
67
- } catch {
68
- skip(`${label} — tool not installed`);
69
- return true;
70
- }
71
- }
72
-
73
- function detectLinters(projectRoot) {
74
- const available = {};
75
- const pkgJson = path.join(projectRoot, "package.json");
76
-
77
- if (fs.existsSync(pkgJson)) {
78
- const eslintFiles = [".eslintrc", ".eslintrc.js", ".eslintrc.json", ".eslintrc.yml", "eslint.config.js", "eslint.config.mjs"];
79
- available.eslint = eslintFiles.some(f => fs.existsSync(path.join(projectRoot, f)));
80
-
81
- const prettierFiles = [".prettierrc", ".prettierrc.js", ".prettierrc.json", "prettier.config.js"];
82
- available.prettier = prettierFiles.some(f => fs.existsSync(path.join(projectRoot, f)));
83
- }
84
-
85
- available.ruff = fs.existsSync(path.join(projectRoot, "pyproject.toml")) || fs.existsSync(path.join(projectRoot, "ruff.toml"));
86
- available.flake8 = fs.existsSync(path.join(projectRoot, ".flake8")) || fs.existsSync(path.join(projectRoot, "setup.cfg"));
87
-
88
- return available;
89
- }
90
-
91
- function main() {
92
- const args = process.argv.slice(2);
93
- let targetPath = null;
94
- let fixFlag = false;
95
- let fileArgs = [];
96
-
97
- let i = 0;
98
- while (i < args.length) {
99
- if (args[i] === '--fix') fixFlag = true;
100
- else if (args[i] === '--files') {
101
- i++;
102
- while (i < args.length && !args[i].startsWith('--')) {
103
- fileArgs.push(args[i++]);
104
- }
105
- continue;
106
- } else if (!targetPath && !args[i].startsWith('-')) {
107
- targetPath = args[i];
108
- }
109
- i++;
110
- }
111
-
112
- if (!targetPath) {
113
- console.log("Usage: node lint_runner.js <path> [--fix] [--files <file1> <file2> ...]");
114
- process.exit(1);
115
- }
116
-
117
- const projectRoot = path.resolve(targetPath);
118
- if (!fs.existsSync(projectRoot) || !fs.statSync(projectRoot).isDirectory()) {
119
- fail(`Directory not found: ${projectRoot}`);
120
- process.exit(1);
121
- }
122
-
123
- console.log(`${BOLD}Tribunal — lint_runner.js${RESET}`);
124
- console.log(`Project: ${projectRoot}`);
125
-
126
- const available = detectLinters(projectRoot);
127
- if (!Object.values(available).some(Boolean)) {
128
- skip("No linter configuration detected in this project");
129
- process.exit(0);
130
- }
131
-
132
- let failures = 0;
133
-
134
- if (available.eslint) {
135
- header("ESLint");
136
- const cmd = ["npx", "eslint"];
137
- if (fixFlag) cmd.push("--fix");
138
- if (fileArgs.length) cmd.push(...fileArgs);
139
- else cmd.push(".", "--max-warnings=0");
140
- if (!runLinter("ESLint", cmd, projectRoot)) failures++;
141
- }
142
-
143
- if (available.prettier) {
144
- header("Prettier");
145
- const cmd = ["npx", "prettier"];
146
- if (fixFlag) cmd.push("--write");
147
- else cmd.push("--check");
148
- if (fileArgs.length) cmd.push(...fileArgs);
149
- else cmd.push(".");
150
- if (!runLinter("Prettier", cmd, projectRoot)) failures++;
151
- }
152
-
153
- if (available.ruff) {
154
- header("Ruff (Python)");
155
- const cmd = ["ruff", "check"];
156
- if (fixFlag) cmd.push("--fix");
157
- if (fileArgs.length) cmd.push(...fileArgs);
158
- else cmd.push(".");
159
- if (!runLinter("Ruff", cmd, projectRoot)) failures++;
160
- }
161
-
162
- if (available.flake8 && !available.ruff) {
163
- header("Flake8 (Python)");
164
- const cmd = ["flake8"];
165
- if (fileArgs.length) cmd.push(...fileArgs);
166
- else cmd.push(".");
167
- if (!runLinter("Flake8", cmd, projectRoot)) failures++;
168
- }
169
-
170
- if (fs.existsSync(path.join(projectRoot, "tsconfig.json"))) {
171
- header("TypeScript");
172
- if (!runLinter("TypeScript", ["npx", "tsc", "--noEmit"], projectRoot)) failures++;
173
- }
174
-
175
- console.log(`\n${BOLD}━━━ Lint Summary ━━━${RESET}`);
176
- if (failures === 0) {
177
- ok("All linters passed");
178
- } else {
179
- fail(`${failures} linter(s) reported issues`);
180
- }
181
-
182
- process.exit(failures > 0 ? 1 : 0);
183
- }
184
-
185
- if (require.main === module) {
186
- main();
187
- }
1
+ #!/usr/bin/env node
2
+ /**
3
+ * lint_runner.js — Standalone lint runner for the Tribunal Agent Kit.
4
+ *
5
+ * Usage:
6
+ * node .agent/scripts/lint_runner.js .
7
+ * node .agent/scripts/lint_runner.js . --fix
8
+ * node .agent/scripts/lint_runner.js . --files src/index.ts src/utils.ts
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const { spawnSync } = require('child_process');
16
+
17
+ const { RED, GREEN, YELLOW, BLUE, BOLD, RESET } = require('./colors.js');
18
+
19
+ function header(title) {
20
+ console.log(`\n${BOLD}${BLUE}━━━ ${title} ━━━${RESET}`);
21
+ }
22
+
23
+ function ok(msg) {
24
+ console.log(` ${GREEN}✅ ${msg}${RESET}`);
25
+ }
26
+
27
+ function fail(msg) {
28
+ console.log(` ${RED}❌ ${msg}${RESET}`);
29
+ }
30
+
31
+ function skip(msg) {
32
+ console.log(` ${YELLOW}⏭️ ${msg}${RESET}`);
33
+ }
34
+
35
+ function runLinter(label, cmd, cwd) {
36
+ try {
37
+ const executable = process.platform === 'win32' && cmd[0] === 'npx' ? 'npx.cmd' : cmd[0];
38
+ const result = spawnSync(executable, cmd.slice(1), {
39
+ cwd,
40
+ encoding: 'utf8',
41
+ timeout: 120000,
42
+ shell: process.platform === 'win32'
43
+ });
44
+
45
+ if (result.status === 0) {
46
+ ok(`${label} — clean`);
47
+ return true;
48
+ }
49
+
50
+ fail(`${label} — issues found`);
51
+ if (result.error) {
52
+ console.log(` Error: ${result.error.message}`);
53
+ }
54
+ const out = result.stdout ? result.stdout.toString() : '';
55
+ const err = result.stderr ? result.stderr.toString() : '';
56
+ const output = (out + "\n" + err).trim();
57
+ if (output) {
58
+ const lines = output.split('\n');
59
+ for (const line of lines.slice(0, 15)) {
60
+ console.log(` ${line}`);
61
+ }
62
+ if (lines.length > 15) {
63
+ console.log(` ... and ${lines.length - 15} more lines`);
64
+ }
65
+ }
66
+ return false;
67
+ } catch {
68
+ skip(`${label} — tool not installed`);
69
+ return true;
70
+ }
71
+ }
72
+
73
+ function detectLinters(projectRoot) {
74
+ const available = {};
75
+ const pkgJson = path.join(projectRoot, "package.json");
76
+
77
+ if (fs.existsSync(pkgJson)) {
78
+ const eslintFiles = [".eslintrc", ".eslintrc.js", ".eslintrc.json", ".eslintrc.yml", "eslint.config.js", "eslint.config.mjs"];
79
+ available.eslint = eslintFiles.some(f => fs.existsSync(path.join(projectRoot, f)));
80
+
81
+ const prettierFiles = [".prettierrc", ".prettierrc.js", ".prettierrc.json", "prettier.config.js"];
82
+ available.prettier = prettierFiles.some(f => fs.existsSync(path.join(projectRoot, f)));
83
+ }
84
+
85
+ available.ruff = fs.existsSync(path.join(projectRoot, "pyproject.toml")) || fs.existsSync(path.join(projectRoot, "ruff.toml"));
86
+ available.flake8 = fs.existsSync(path.join(projectRoot, ".flake8")) || fs.existsSync(path.join(projectRoot, "setup.cfg"));
87
+
88
+ return available;
89
+ }
90
+
91
+ function main() {
92
+ const args = process.argv.slice(2);
93
+ let targetPath = null;
94
+ let fixFlag = false;
95
+ let fileArgs = [];
96
+
97
+ let i = 0;
98
+ while (i < args.length) {
99
+ if (args[i] === '--fix') fixFlag = true;
100
+ else if (args[i] === '--files') {
101
+ i++;
102
+ while (i < args.length && !args[i].startsWith('--')) {
103
+ fileArgs.push(args[i++]);
104
+ }
105
+ continue;
106
+ } else if (!targetPath && !args[i].startsWith('-')) {
107
+ targetPath = args[i];
108
+ }
109
+ i++;
110
+ }
111
+
112
+ if (!targetPath) {
113
+ console.log("Usage: node lint_runner.js <path> [--fix] [--files <file1> <file2> ...]");
114
+ process.exit(1);
115
+ }
116
+
117
+ const projectRoot = path.resolve(targetPath);
118
+ if (!fs.existsSync(projectRoot) || !fs.statSync(projectRoot).isDirectory()) {
119
+ fail(`Directory not found: ${projectRoot}`);
120
+ process.exit(1);
121
+ }
122
+
123
+ console.log(`${BOLD}Tribunal — lint_runner.js${RESET}`);
124
+ console.log(`Project: ${projectRoot}`);
125
+
126
+ const available = detectLinters(projectRoot);
127
+ if (!Object.values(available).some(Boolean)) {
128
+ skip("No linter configuration detected in this project");
129
+ process.exit(0);
130
+ }
131
+
132
+ let failures = 0;
133
+
134
+ if (available.eslint) {
135
+ header("ESLint");
136
+ const cmd = ["npx", "eslint"];
137
+ if (fixFlag) cmd.push("--fix");
138
+ if (fileArgs.length) cmd.push(...fileArgs);
139
+ else cmd.push(".", "--max-warnings=0");
140
+ if (!runLinter("ESLint", cmd, projectRoot)) failures++;
141
+ }
142
+
143
+ if (available.prettier) {
144
+ header("Prettier");
145
+ const cmd = ["npx", "prettier"];
146
+ if (fixFlag) cmd.push("--write");
147
+ else cmd.push("--check");
148
+ if (fileArgs.length) cmd.push(...fileArgs);
149
+ else cmd.push(".");
150
+ if (!runLinter("Prettier", cmd, projectRoot)) failures++;
151
+ }
152
+
153
+ if (available.ruff) {
154
+ header("Ruff (Python)");
155
+ const cmd = ["ruff", "check"];
156
+ if (fixFlag) cmd.push("--fix");
157
+ if (fileArgs.length) cmd.push(...fileArgs);
158
+ else cmd.push(".");
159
+ if (!runLinter("Ruff", cmd, projectRoot)) failures++;
160
+ }
161
+
162
+ if (available.flake8 && !available.ruff) {
163
+ header("Flake8 (Python)");
164
+ const cmd = ["flake8"];
165
+ if (fileArgs.length) cmd.push(...fileArgs);
166
+ else cmd.push(".");
167
+ if (!runLinter("Flake8", cmd, projectRoot)) failures++;
168
+ }
169
+
170
+ if (fs.existsSync(path.join(projectRoot, "tsconfig.json"))) {
171
+ header("TypeScript");
172
+ if (!runLinter("TypeScript", ["npx", "tsc", "--noEmit"], projectRoot)) failures++;
173
+ }
174
+
175
+ console.log(`\n${BOLD}━━━ Lint Summary ━━━${RESET}`);
176
+ if (failures === 0) {
177
+ ok("All linters passed");
178
+ } else {
179
+ fail(`${failures} linter(s) reported issues`);
180
+ }
181
+
182
+ process.exit(failures > 0 ? 1 : 0);
183
+ }
184
+
185
+ if (require.main === module) {
186
+ main();
187
+ }
@@ -1,100 +1,100 @@
1
- #!/usr/bin/env node
2
- /**
3
- * minify_context.js
4
- * Minifies markdown documentation in the .agent directory to save tokens.
5
- */
6
-
7
- 'use strict';
8
-
9
- const fs = require('fs');
10
- const path = require('path');
11
-
12
- function minifyMarkdown(filePath) {
13
- let content = fs.readFileSync(filePath, 'utf8');
14
- const originalLen = content.length;
15
-
16
- // 1. Strip repetitive Output Format templates
17
- content = content.replace(/## Output Format\n\n```[\s\S]*?```\n/g, '');
18
-
19
- // 2. Convert bloated Cross-Workflow Navigation tables to dense YAML lists
20
- content = content.replace(/## Cross-Workflow Navigation\n\n\|.*?\|[\s\S]*?(?=\n## |\Z)/g, match => {
21
- const lines = match.trim().split('\n');
22
- const out = [];
23
- for (const line of lines) {
24
- if (line.startsWith('|') && !line.startsWith('|:') && !line.startsWith('| After')) {
25
- const parts = line.split('|').map(p => p.trim()).filter(Boolean);
26
- if (parts.length >= 2) {
27
- out.push(`- ${parts[0]} -> ${parts[1]}`);
28
- }
29
- }
30
- }
31
- return '## Cross-Workflow Navigation\n' + out.join('\n') + '\n';
32
- });
33
-
34
- // 3. Collapse multiple empty lines into a single one
35
- content = content.replace(/\n{3,}/g, '\n\n');
36
-
37
- // 4. Remove padding from remaining tables to save space tokens
38
- content = content.replace(/^\|.+|$/gm, match => {
39
- let line = match;
40
- // remove spaces around |
41
- line = line.replace(/\s+\|\s+/g, '|');
42
- line = line.replace(/\|\s+/g, '|');
43
- line = line.replace(/\s+\|/g, '|');
44
- return line;
45
- });
46
-
47
- // 5. Remove conversational blockquotes > if they don't contain WARNING/NOTE/IMPORTANT
48
- content = content.replace(/^>.*$/gm, match => {
49
- if (match.includes('⚠️') || match.includes('WARNING') || match.includes('CRITICAL') || match.includes('!')) {
50
- return match;
51
- }
52
- return match.replace(/> /g, '').replace(/>/g, '');
53
- });
54
-
55
- // 6. Dense Examples (convert ❌ Bad: and ✅ Good: blocks to single lines)
56
- content = content.replace(/\n❌ Bad:/g, ' ❌');
57
- content = content.replace(/\n✅ Good:/g, ' ✅');
58
-
59
- fs.writeFileSync(filePath, content, 'utf8');
60
- return [originalLen, content.length];
61
- }
62
-
63
- function walkDir(dir, callback) {
64
- if (!fs.existsSync(dir)) return;
65
- const items = fs.readdirSync(dir, { withFileTypes: true });
66
- for (const item of items) {
67
- const fullPath = path.join(dir, item.name);
68
- if (item.isDirectory()) {
69
- walkDir(fullPath, callback);
70
- } else {
71
- callback(fullPath);
72
- }
73
- }
74
- }
75
-
76
- function main() {
77
- const agentDir = path.join('.agent');
78
- let totalOriginal = 0;
79
- let totalNew = 0;
80
-
81
- walkDir(agentDir, file => {
82
- if (file.endsWith('.md')) {
83
- const [orig, newLen] = minifyMarkdown(file);
84
- totalOriginal += orig;
85
- totalNew += newLen;
86
- }
87
- });
88
-
89
- const saved = totalOriginal - totalNew;
90
- const percent = totalOriginal > 0 ? (saved / totalOriginal * 100) : 0;
91
-
92
- console.log("Minification Complete.");
93
- console.log(`Original size: ${totalOriginal} bytes`);
94
- console.log(`New size: ${totalNew} bytes`);
95
- console.log(`Saved: ${saved} bytes (${percent.toFixed(1)}%)`);
96
- }
97
-
98
- if (require.main === module) {
99
- main();
100
- }
1
+ #!/usr/bin/env node
2
+ /**
3
+ * minify_context.js
4
+ * Minifies markdown documentation in the .agent directory to save tokens.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ function minifyMarkdown(filePath) {
13
+ let content = fs.readFileSync(filePath, 'utf8');
14
+ const originalLen = content.length;
15
+
16
+ // 1. Strip repetitive Output Format templates
17
+ content = content.replace(/## Output Format\n\n```[\s\S]*?```\n/g, '');
18
+
19
+ // 2. Convert bloated Cross-Workflow Navigation tables to dense YAML lists
20
+ content = content.replace(/## Cross-Workflow Navigation\n\n\|.*?\|[\s\S]*?(?=\n## |\Z)/g, match => {
21
+ const lines = match.trim().split('\n');
22
+ const out = [];
23
+ for (const line of lines) {
24
+ if (line.startsWith('|') && !line.startsWith('|:') && !line.startsWith('| After')) {
25
+ const parts = line.split('|').map(p => p.trim()).filter(Boolean);
26
+ if (parts.length >= 2) {
27
+ out.push(`- ${parts[0]} -> ${parts[1]}`);
28
+ }
29
+ }
30
+ }
31
+ return '## Cross-Workflow Navigation\n' + out.join('\n') + '\n';
32
+ });
33
+
34
+ // 3. Collapse multiple empty lines into a single one
35
+ content = content.replace(/\n{3,}/g, '\n\n');
36
+
37
+ // 4. Remove padding from remaining tables to save space tokens
38
+ content = content.replace(/^\|.+|$/gm, match => {
39
+ let line = match;
40
+ // remove spaces around |
41
+ line = line.replace(/\s+\|\s+/g, '|');
42
+ line = line.replace(/\|\s+/g, '|');
43
+ line = line.replace(/\s+\|/g, '|');
44
+ return line;
45
+ });
46
+
47
+ // 5. Remove conversational blockquotes > if they don't contain WARNING/NOTE/IMPORTANT
48
+ content = content.replace(/^>.*$/gm, match => {
49
+ if (match.includes('⚠️') || match.includes('WARNING') || match.includes('CRITICAL') || match.includes('!')) {
50
+ return match;
51
+ }
52
+ return match.replace(/> /g, '').replace(/>/g, '');
53
+ });
54
+
55
+ // 6. Dense Examples (convert ❌ Bad: and ✅ Good: blocks to single lines)
56
+ content = content.replace(/\n❌ Bad:/g, ' ❌');
57
+ content = content.replace(/\n✅ Good:/g, ' ✅');
58
+
59
+ fs.writeFileSync(filePath, content, 'utf8');
60
+ return [originalLen, content.length];
61
+ }
62
+
63
+ function walkDir(dir, callback) {
64
+ if (!fs.existsSync(dir)) return;
65
+ const items = fs.readdirSync(dir, { withFileTypes: true });
66
+ for (const item of items) {
67
+ const fullPath = path.join(dir, item.name);
68
+ if (item.isDirectory()) {
69
+ walkDir(fullPath, callback);
70
+ } else {
71
+ callback(fullPath);
72
+ }
73
+ }
74
+ }
75
+
76
+ function main() {
77
+ const agentDir = path.join('.agent');
78
+ let totalOriginal = 0;
79
+ let totalNew = 0;
80
+
81
+ walkDir(agentDir, file => {
82
+ if (file.endsWith('.md')) {
83
+ const [orig, newLen] = minifyMarkdown(file);
84
+ totalOriginal += orig;
85
+ totalNew += newLen;
86
+ }
87
+ });
88
+
89
+ const saved = totalOriginal - totalNew;
90
+ const percent = totalOriginal > 0 ? (saved / totalOriginal * 100) : 0;
91
+
92
+ console.log("Minification Complete.");
93
+ console.log(`Original size: ${totalOriginal} bytes`);
94
+ console.log(`New size: ${totalNew} bytes`);
95
+ console.log(`Saved: ${saved} bytes (${percent.toFixed(1)}%)`);
96
+ }
97
+
98
+ if (require.main === module) {
99
+ main();
100
+ }