tribunal-kit 4.4.1 → 4.4.2

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 (44) hide show
  1. package/.agent/history/architecture-graph.yaml +140 -0
  2. package/.agent/history/graph-cache.json +262 -0
  3. package/.agent/history/snapshots/bin__tribunal-kit.js.json +19 -0
  4. package/.agent/history/snapshots/eslint.config.js.json +9 -0
  5. package/.agent/history/snapshots/migrate_refs.js.json +11 -0
  6. package/.agent/history/snapshots/scripts__changelog.js.json +13 -0
  7. package/.agent/history/snapshots/scripts__sync-version.js.json +12 -0
  8. package/.agent/history/snapshots/scripts__validate-payload.js.json +12 -0
  9. package/.agent/history/snapshots/test__integration__bridges.test.js.json +14 -0
  10. package/.agent/history/snapshots/test__integration__init.test.js.json +14 -0
  11. package/.agent/history/snapshots/test__integration__routing.test.js.json +12 -0
  12. package/.agent/history/snapshots/test__integration__swarm_dispatcher.test.js.json +14 -0
  13. package/.agent/history/snapshots/test__integration__wave2.test.js.json +14 -0
  14. package/.agent/history/snapshots/test__unit__args.test.js.json +20 -0
  15. package/.agent/history/snapshots/test__unit__case_law_manager.test.js.json +11 -0
  16. package/.agent/history/snapshots/test__unit__context_broker.test.js.json +11 -0
  17. package/.agent/history/snapshots/test__unit__copyDir.test.js.json +23 -0
  18. package/.agent/history/snapshots/test__unit__graph_tools.test.js.json +12 -0
  19. package/.agent/history/snapshots/test__unit__inner_loop_validator.test.js.json +11 -0
  20. package/.agent/history/snapshots/test__unit__selfInstall.test.js.json +23 -0
  21. package/.agent/history/snapshots/test__unit__semver.test.js.json +20 -0
  22. package/.agent/history/snapshots/test__unit__swarm_dispatcher.test.js.json +12 -0
  23. package/.agent/scripts/_colors.js +170 -18
  24. package/.agent/scripts/_utils.js +244 -42
  25. package/.agent/scripts/bundle_analyzer.js +261 -290
  26. package/.agent/scripts/case_law_manager.js +1 -7
  27. package/.agent/scripts/checklist.js +278 -266
  28. package/.agent/scripts/colors.js +11 -17
  29. package/.agent/scripts/context_broker.js +1 -7
  30. package/.agent/scripts/dependency_analyzer.js +234 -272
  31. package/.agent/scripts/graph_builder.js +46 -18
  32. package/.agent/scripts/graph_visualizer.js +10 -4
  33. package/.agent/scripts/graph_zoom.js +6 -4
  34. package/.agent/scripts/inner_loop_validator.js +2 -8
  35. package/.agent/scripts/lint_runner.js +186 -187
  36. package/.agent/scripts/schema_validator.js +8 -25
  37. package/.agent/scripts/security_scan.js +276 -303
  38. package/.agent/scripts/session_manager.js +1 -7
  39. package/.agent/scripts/skill_evolution.js +1 -8
  40. package/.agent/scripts/skill_integrator.js +1 -7
  41. package/.agent/scripts/test_runner.js +186 -193
  42. package/.agent/scripts/utils.js +17 -32
  43. package/.agent/scripts/verify_all.js +248 -257
  44. package/package.json +1 -1
@@ -1,42 +1,244 @@
1
- /**
2
- * Shared utilities for Tribunal Kit scripts.
3
- * Import this module instead of duplicating helper functions.
4
- */
5
-
6
- 'use strict';
7
-
8
- const fs = require('fs');
9
- const path = require('path');
10
- const { RED, RESET } = require('./_colors');
11
-
12
- /**
13
- * Walk up the directory tree to find the nearest .agent/ folder.
14
- * @param {string} [startDir] - Directory to start searching from (defaults to cwd).
15
- * @returns {string} Absolute path to the .agent directory.
16
- */
17
- function findAgentDir(startDir) {
18
- let current = path.resolve(startDir || process.cwd());
19
- const root = path.parse(current).root;
20
-
21
- while (current !== root) {
22
- const candidate = path.join(current, '.agent');
23
- if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
24
- return candidate;
25
- }
26
- current = path.dirname(current);
27
- }
28
-
29
- console.error(`${RED}✖ Error: '.agent' directory not found. Please run 'npx tribunal-kit init' first.${RESET}`);
30
- process.exit(1);
31
- }
32
-
33
- /**
34
- * Check if a package.json exists in the given directory.
35
- * @param {string} dir - Directory to check.
36
- * @returns {boolean}
37
- */
38
- function hasNpm(dir) {
39
- return fs.existsSync(path.join(dir, 'package.json'));
40
- }
41
-
42
- module.exports = { findAgentDir, hasNpm };
1
+ /**
2
+ * _utils.js Tribunal Kit Shared Utilities
3
+ * ════════════════════════════════════════════════════════════════
4
+ * Single source of truth for all shared utility functions.
5
+ * Import this module instead of duplicating helpers.
6
+ *
7
+ * Usage:
8
+ * const { findAgentDir, walkDir, loadJson } = require('./_utils');
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const { RED, RESET } = require('./_colors');
16
+
17
+ // ── Default Skip Directories ────────────────────────────────────────────────
18
+ const DEFAULT_SKIP_DIRS = new Set([
19
+ 'node_modules', '.git', 'dist', 'build', '.next', '.agent',
20
+ '__pycache__', '.venv', 'venv', 'coverage', '.turbo',
21
+ '.svelte-kit', '.nuxt', '.output',
22
+ ]);
23
+
24
+ // ── Default Source Extensions ───────────────────────────────────────────────
25
+ const SOURCE_EXTENSIONS = new Set([
26
+ '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
27
+ '.py', '.rs', '.go', '.java', '.cs', '.rb',
28
+ '.vue', '.svelte',
29
+ ]);
30
+
31
+ // ── Agent Directory Discovery ───────────────────────────────────────────────
32
+
33
+ /**
34
+ * Walk up the directory tree to find the nearest .agent/ folder.
35
+ * @param {string} [startDir] - Directory to start searching from (defaults to cwd).
36
+ * @returns {string} Absolute path to the .agent directory.
37
+ */
38
+ function findAgentDir(startDir) {
39
+ let current = path.resolve(startDir || process.cwd());
40
+ const root = path.parse(current).root;
41
+
42
+ while (current !== root) {
43
+ const candidate = path.join(current, '.agent');
44
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
45
+ return candidate;
46
+ }
47
+ current = path.dirname(current);
48
+ }
49
+
50
+ console.error(`${RED}✖ Error: '.agent' directory not found. Please run 'npx tribunal-kit init' first.${RESET}`);
51
+ process.exit(1);
52
+ }
53
+
54
+ // ── Package.json Helpers ────────────────────────────────────────────────────
55
+
56
+ /**
57
+ * Check if a package.json exists in the given directory.
58
+ * @param {string} dir - Directory to check.
59
+ * @returns {boolean}
60
+ */
61
+ function hasNpm(dir) {
62
+ return fs.existsSync(path.join(dir, 'package.json'));
63
+ }
64
+
65
+ /**
66
+ * Load and parse a JSON file safely. Returns null on failure.
67
+ * @param {string} filePath - Absolute path to the JSON file.
68
+ * @returns {object|null}
69
+ */
70
+ function loadJson(filePath) {
71
+ try {
72
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
77
+
78
+ // ── Filesystem Walking ──────────────────────────────────────────────────────
79
+
80
+ /**
81
+ * Recursively walk a directory tree, yielding file paths.
82
+ * This is the consolidated walker used by all scanning scripts.
83
+ *
84
+ * @param {string} dir - Root directory to walk.
85
+ * @param {object} [opts] - Options.
86
+ * @param {Set<string>} [opts.skipDirs] - Directory names to skip (default: DEFAULT_SKIP_DIRS).
87
+ * @param {Set<string>} [opts.extensions] - Only yield files with these extensions. Null = all files.
88
+ * @param {function(string): boolean} [opts.filter] - Custom filter predicate for file paths.
89
+ * @returns {string[]} Array of absolute file paths.
90
+ */
91
+ function walkDir(dir, opts = {}) {
92
+ const skipDirs = opts.skipDirs || DEFAULT_SKIP_DIRS;
93
+ const extensions = opts.extensions || null;
94
+ const filter = opts.filter || null;
95
+ const results = [];
96
+
97
+ function _walk(currentDir) {
98
+ let entries;
99
+ try {
100
+ entries = fs.readdirSync(currentDir, { withFileTypes: true });
101
+ } catch {
102
+ return;
103
+ }
104
+
105
+ for (const entry of entries) {
106
+ const fullPath = path.join(currentDir, entry.name);
107
+
108
+ if (entry.isDirectory()) {
109
+ if (!skipDirs.has(entry.name)) {
110
+ _walk(fullPath);
111
+ }
112
+ } else if (entry.isFile()) {
113
+ if (extensions) {
114
+ const ext = path.extname(entry.name);
115
+ if (!extensions.has(ext)) continue;
116
+ }
117
+ if (filter && !filter(fullPath)) continue;
118
+ results.push(fullPath);
119
+ }
120
+ }
121
+ }
122
+
123
+ _walk(dir);
124
+ return results;
125
+ }
126
+
127
+ /**
128
+ * Count files in a directory recursively (fast — no file content reads).
129
+ * @param {string} dir
130
+ * @param {Set<string>} [skipDirs]
131
+ * @returns {number}
132
+ */
133
+ function countFiles(dir, skipDirs = DEFAULT_SKIP_DIRS) {
134
+ let count = 0;
135
+ function _count(d) {
136
+ let entries;
137
+ try { entries = fs.readdirSync(d, { withFileTypes: true }); } catch { return; }
138
+ for (const e of entries) {
139
+ if (e.isDirectory() && !skipDirs.has(e.name)) _count(path.join(d, e.name));
140
+ else if (e.isFile()) count++;
141
+ }
142
+ }
143
+ _count(dir);
144
+ return count;
145
+ }
146
+
147
+ // ── CLI Argument Parsing ────────────────────────────────────────────────────
148
+
149
+ /**
150
+ * Parse command-line arguments into a structured object.
151
+ * Supports --flag, --key value, and positional arguments.
152
+ *
153
+ * @param {string[]} argv - process.argv.slice(2)
154
+ * @param {object} [schema] - Flag definitions: { flag: { type: 'boolean'|'string'|'number', default: any } }
155
+ * @returns {{ flags: object, positional: string[] }}
156
+ */
157
+ function parseArgs(argv, schema = {}) {
158
+ const flags = {};
159
+ const positional = [];
160
+
161
+ // Set defaults
162
+ for (const [key, def] of Object.entries(schema)) {
163
+ flags[key] = def.default ?? (def.type === 'boolean' ? false : null);
164
+ }
165
+
166
+ for (let i = 0; i < argv.length; i++) {
167
+ const arg = argv[i];
168
+
169
+ if (arg === '-h' || arg === '--help') {
170
+ flags.help = true;
171
+ continue;
172
+ }
173
+
174
+ if (arg.startsWith('--')) {
175
+ const flagName = arg.slice(2);
176
+ const schemaDef = schema[flagName];
177
+
178
+ if (schemaDef && schemaDef.type === 'boolean') {
179
+ flags[flagName] = true;
180
+ } else if (schemaDef && i + 1 < argv.length) {
181
+ const val = argv[++i];
182
+ flags[flagName] = schemaDef.type === 'number' ? Number(val) : val;
183
+ } else {
184
+ // Unknown flag, store as boolean
185
+ flags[flagName] = true;
186
+ }
187
+ } else if (arg.startsWith('-') && arg.length === 2) {
188
+ // Short flag — treat as boolean
189
+ flags[arg.slice(1)] = true;
190
+ } else {
191
+ positional.push(arg);
192
+ }
193
+ }
194
+
195
+ return { flags, positional };
196
+ }
197
+
198
+ // ── Command Runner ──────────────────────────────────────────────────────────
199
+
200
+ /**
201
+ * Run a command synchronously and return a structured result.
202
+ * Handles Windows .cmd shims automatically.
203
+ *
204
+ * @param {string} cmd - Command to run
205
+ * @param {string[]} args - Arguments
206
+ * @param {object} [opts] - spawnSync options (cwd, timeout, etc.)
207
+ * @returns {{ status: number, stdout: string, stderr: string, ok: boolean }}
208
+ */
209
+ function runCommand(cmd, args = [], opts = {}) {
210
+ const { spawnSync } = require('child_process');
211
+ const executable = process.platform === 'win32' && !cmd.endsWith('.cmd') && !cmd.includes(path.sep)
212
+ ? `${cmd}.cmd`
213
+ : cmd;
214
+
215
+ const result = spawnSync(executable, args, {
216
+ encoding: 'utf8',
217
+ timeout: opts.timeout || 120000,
218
+ cwd: opts.cwd || process.cwd(),
219
+ shell: process.platform === 'win32',
220
+ stdio: opts.stdio || 'pipe',
221
+ ...opts,
222
+ });
223
+
224
+ return {
225
+ status: result.status ?? 1,
226
+ stdout: (result.stdout || '').toString(),
227
+ stderr: (result.stderr || '').toString(),
228
+ ok: result.status === 0,
229
+ };
230
+ }
231
+
232
+ module.exports = {
233
+ // Agent discovery
234
+ findAgentDir,
235
+ // Package.json
236
+ hasNpm, loadJson,
237
+ // Filesystem
238
+ walkDir, countFiles,
239
+ DEFAULT_SKIP_DIRS, SOURCE_EXTENSIONS,
240
+ // CLI
241
+ parseArgs,
242
+ // Commands
243
+ runCommand,
244
+ };