tribunal-kit 4.4.0 → 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.
- package/.agent/agents/api-architect.md +66 -66
- package/.agent/agents/db-latency-auditor.md +216 -216
- package/.agent/agents/precedence-reviewer.md +250 -250
- package/.agent/agents/resilience-reviewer.md +88 -88
- package/.agent/agents/schema-reviewer.md +67 -67
- package/.agent/agents/throughput-optimizer.md +299 -299
- package/.agent/agents/ui-ux-auditor.md +292 -292
- package/.agent/agents/vitals-reviewer.md +223 -223
- package/.agent/scripts/_colors.js +18 -18
- package/.agent/scripts/_utils.js +42 -42
- package/.agent/scripts/append_flow.js +72 -72
- package/.agent/scripts/auto_preview.js +197 -197
- package/.agent/scripts/bundle_analyzer.js +290 -290
- package/.agent/scripts/case_law_manager.js +17 -6
- package/.agent/scripts/checklist.js +266 -266
- package/.agent/scripts/colors.js +17 -17
- package/.agent/scripts/compress_skills.js +141 -141
- package/.agent/scripts/consolidate_skills.js +149 -149
- package/.agent/scripts/context_broker.js +611 -609
- package/.agent/scripts/deep_compress.js +150 -150
- package/.agent/scripts/dependency_analyzer.js +272 -272
- package/.agent/scripts/graph_builder.js +313 -311
- package/.agent/scripts/graph_visualizer.js +384 -384
- package/.agent/scripts/inner_loop_validator.js +451 -465
- package/.agent/scripts/lint_runner.js +187 -187
- package/.agent/scripts/minify_context.js +100 -100
- package/.agent/scripts/mutation_runner.js +280 -280
- package/.agent/scripts/patch_skills_meta.js +156 -156
- package/.agent/scripts/patch_skills_output.js +244 -244
- package/.agent/scripts/schema_validator.js +297 -297
- package/.agent/scripts/security_scan.js +303 -303
- package/.agent/scripts/session_manager.js +276 -276
- package/.agent/scripts/skill_evolution.js +644 -644
- package/.agent/scripts/skill_integrator.js +313 -313
- package/.agent/scripts/strengthen_skills.js +193 -193
- package/.agent/scripts/strip_tribunal.js +47 -47
- package/.agent/scripts/swarm_dispatcher.js +360 -360
- package/.agent/scripts/test_runner.js +193 -193
- package/.agent/scripts/utils.js +32 -32
- package/.agent/scripts/verify_all.js +257 -256
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +1 -1
- package/.agent/skills/doc.md +1 -1
- package/.agent/skills/knowledge-graph/SKILL.md +52 -52
- package/.agent/skills/ui-ux-pro-max/SKILL.md +562 -562
- package/.agent/workflows/generate.md +183 -183
- package/.agent/workflows/tribunal-speed.md +183 -183
- package/README.md +1 -1
- package/bin/tribunal-kit.js +76 -87
- package/package.json +6 -3
- package/scripts/changelog.js +167 -167
- package/scripts/sync-version.js +81 -81
- package/.agent/history/architecture-explorer.html +0 -352
- package/.agent/history/architecture-graph.yaml +0 -109
- package/.agent/history/graph-cache.json +0 -215
- package/.agent/history/snapshots/migrate_refs.js.json +0 -11
- package/.agent/history/snapshots/scripts__changelog.js.json +0 -12
- package/.agent/history/snapshots/scripts__sync-version.js.json +0 -11
- package/.agent/history/snapshots/scripts__validate-payload.js.json +0 -11
- package/.agent/history/snapshots/test__integration__bridges.test.js.json +0 -13
- package/.agent/history/snapshots/test__integration__init.test.js.json +0 -13
- package/.agent/history/snapshots/test__integration__routing.test.js.json +0 -11
- package/.agent/history/snapshots/test__integration__swarm_dispatcher.test.js.json +0 -13
- package/.agent/history/snapshots/test__integration__wave2.test.js.json +0 -13
- package/.agent/history/snapshots/test__unit__args.test.js.json +0 -10
- package/.agent/history/snapshots/test__unit__case_law_manager.test.js.json +0 -10
- package/.agent/history/snapshots/test__unit__copyDir.test.js.json +0 -13
- package/.agent/history/snapshots/test__unit__graph_tools.test.js.json +0 -11
- package/.agent/history/snapshots/test__unit__selfInstall.test.js.json +0 -13
- package/.agent/history/snapshots/test__unit__semver.test.js.json +0 -10
- package/.agent/history/snapshots/test__unit__swarm_dispatcher.test.js.json +0 -11
- package/.agent/scripts/__pycache__/_colors.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/_utils.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/case_law_manager.cpython-311.pyc +0 -0
|
@@ -1,256 +1,257 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* verify_all.js — Full pre-deploy validation suite for the Tribunal Agent Kit.
|
|
4
|
-
*
|
|
5
|
-
* Runs comprehensive checks before any production deployment.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* node .agent/scripts/verify_all.js
|
|
9
|
-
* node .agent/scripts/verify_all.js --skip build,deps
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
'use strict';
|
|
13
|
-
|
|
14
|
-
const fs = require('fs');
|
|
15
|
-
const path = require('path');
|
|
16
|
-
const { execFileSync } = require('child_process');
|
|
17
|
-
|
|
18
|
-
// ━━━ ANSI colors ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
19
|
-
const RED = '\x1b[91m';
|
|
20
|
-
const GREEN = '\x1b[92m';
|
|
21
|
-
const YELLOW = '\x1b[93m';
|
|
22
|
-
const BLUE = '\x1b[94m';
|
|
23
|
-
const BOLD = '\x1b[1m';
|
|
24
|
-
const RESET = '\x1b[0m';
|
|
25
|
-
|
|
26
|
-
const RESULTS = [];
|
|
27
|
-
|
|
28
|
-
function section(title) {
|
|
29
|
-
console.log(`\n${BOLD}${BLUE}━━━ ${title} ━━━${RESET}`);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function ok(label, note) {
|
|
33
|
-
const msg = `${GREEN}✅ ${label}${RESET}` + (note ? ` ${YELLOW}(${note})${RESET}` : '');
|
|
34
|
-
console.log(` ${msg}`);
|
|
35
|
-
RESULTS.push({ label, passed: true, note: note || '' });
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function fail(label, note) {
|
|
39
|
-
const noteStr = note ? `\n ${note}` : '';
|
|
40
|
-
console.log(` ${RED}❌ ${label}${RESET}${noteStr}`);
|
|
41
|
-
RESULTS.push({ label, passed: false, note: note || '' });
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function skip(label, reason) {
|
|
45
|
-
console.log(` ${YELLOW}⏭️ ${label} — ${reason}${RESET}`);
|
|
46
|
-
RESULTS.push({ label, passed: true, note: `skipped: ${reason}` });
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Run a shell command and return true if it exits with code 0.
|
|
51
|
-
*/
|
|
52
|
-
function run(label, cmd, cwd) {
|
|
53
|
-
try {
|
|
54
|
-
const isWindows = process.platform === 'win32';
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
});
|
|
64
|
-
ok(label);
|
|
65
|
-
return true;
|
|
66
|
-
} catch (err) {
|
|
67
|
-
if (err.code === 'ENOENT') {
|
|
68
|
-
skip(label, 'tool not installed — skipping');
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
if (err.killed) {
|
|
72
|
-
fail(label, 'timed out after 120s');
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
const output = ((err.stdout || '') + (err.stderr || '')).trim();
|
|
76
|
-
fail(label, output ? output.slice(0, 500) : 'non-zero exit code');
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Scan source files for obviously hardcoded credentials.
|
|
84
|
-
*/
|
|
85
|
-
function scanSecrets(cwd) {
|
|
86
|
-
const patterns = ['password=', 'secret=', 'api_key=', 'private_key=', 'auth_token='];
|
|
87
|
-
const found = [];
|
|
88
|
-
const skipDirs = new Set(['node_modules', '.git', 'dist', '__pycache__', '.agent']);
|
|
89
|
-
|
|
90
|
-
function walk(dir) {
|
|
91
|
-
let entries;
|
|
92
|
-
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
|
93
|
-
|
|
94
|
-
for (const entry of entries) {
|
|
95
|
-
const fullPath = path.join(dir, entry.name);
|
|
96
|
-
if (entry.isDirectory()) {
|
|
97
|
-
if (!skipDirs.has(entry.name)) walk(fullPath);
|
|
98
|
-
} else if (entry.isFile()) {
|
|
99
|
-
if (!/\.(ts|js|tsx|jsx|py)$/.test(entry.name)) continue;
|
|
100
|
-
|
|
101
|
-
let content;
|
|
102
|
-
try { content = fs.readFileSync(fullPath, 'utf8'); } catch { continue; }
|
|
103
|
-
|
|
104
|
-
const lines = content.split('\n');
|
|
105
|
-
for (let i = 0; i < lines.length; i++) {
|
|
106
|
-
const low = lines[i].toLowerCase().trim();
|
|
107
|
-
const hasPattern = patterns.some(p => low.includes(p));
|
|
108
|
-
if (hasPattern && !low.startsWith('#') && low.includes('=')) {
|
|
109
|
-
const rel = path.relative(cwd, fullPath);
|
|
110
|
-
found.push(`${rel}:${i + 1}`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
walk(cwd);
|
|
118
|
-
|
|
119
|
-
if (found.length > 0) {
|
|
120
|
-
fail('Secret scan', found.slice(0, 5).join('\n '));
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
ok('Secret scan — no hardcoded credentials found');
|
|
124
|
-
return true;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Check if there's a package.json to run npm commands against.
|
|
130
|
-
*/
|
|
131
|
-
function hasNpm(cwd) {
|
|
132
|
-
return fs.existsSync(path.join(cwd, 'package.json'));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Run all verification checks. Returns number of failures.
|
|
138
|
-
*/
|
|
139
|
-
function verifyAll(cwd, skipped) {
|
|
140
|
-
let failures = 0;
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
console.log(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* verify_all.js — Full pre-deploy validation suite for the Tribunal Agent Kit.
|
|
4
|
+
*
|
|
5
|
+
* Runs comprehensive checks before any production deployment.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node .agent/scripts/verify_all.js
|
|
9
|
+
* node .agent/scripts/verify_all.js --skip build,deps
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const { execFileSync } = require('child_process');
|
|
17
|
+
|
|
18
|
+
// ━━━ ANSI colors ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
19
|
+
const RED = '\x1b[91m';
|
|
20
|
+
const GREEN = '\x1b[92m';
|
|
21
|
+
const YELLOW = '\x1b[93m';
|
|
22
|
+
const BLUE = '\x1b[94m';
|
|
23
|
+
const BOLD = '\x1b[1m';
|
|
24
|
+
const RESET = '\x1b[0m';
|
|
25
|
+
|
|
26
|
+
const RESULTS = [];
|
|
27
|
+
|
|
28
|
+
function section(title) {
|
|
29
|
+
console.log(`\n${BOLD}${BLUE}━━━ ${title} ━━━${RESET}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function ok(label, note) {
|
|
33
|
+
const msg = `${GREEN}✅ ${label}${RESET}` + (note ? ` ${YELLOW}(${note})${RESET}` : '');
|
|
34
|
+
console.log(` ${msg}`);
|
|
35
|
+
RESULTS.push({ label, passed: true, note: note || '' });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function fail(label, note) {
|
|
39
|
+
const noteStr = note ? `\n ${note}` : '';
|
|
40
|
+
console.log(` ${RED}❌ ${label}${RESET}${noteStr}`);
|
|
41
|
+
RESULTS.push({ label, passed: false, note: note || '' });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function skip(label, reason) {
|
|
45
|
+
console.log(` ${YELLOW}⏭️ ${label} — ${reason}${RESET}`);
|
|
46
|
+
RESULTS.push({ label, passed: true, note: `skipped: ${reason}` });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Run a shell command and return true if it exits with code 0.
|
|
51
|
+
*/
|
|
52
|
+
function run(label, cmd, cwd) {
|
|
53
|
+
try {
|
|
54
|
+
const isWindows = process.platform === 'win32';
|
|
55
|
+
const bin = cmd[0];
|
|
56
|
+
|
|
57
|
+
execFileSync(bin, cmd.slice(1), {
|
|
58
|
+
cwd,
|
|
59
|
+
stdio: 'pipe',
|
|
60
|
+
timeout: 120000,
|
|
61
|
+
encoding: 'utf8',
|
|
62
|
+
shell: isWindows
|
|
63
|
+
});
|
|
64
|
+
ok(label);
|
|
65
|
+
return true;
|
|
66
|
+
} catch (err) {
|
|
67
|
+
if (err.code === 'ENOENT') {
|
|
68
|
+
skip(label, 'tool not installed — skipping');
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
if (err.killed) {
|
|
72
|
+
fail(label, 'timed out after 120s');
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
const output = ((err.stdout || '') + (err.stderr || '')).trim();
|
|
76
|
+
fail(label, output ? output.slice(0, 500) : 'non-zero exit code');
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Scan source files for obviously hardcoded credentials.
|
|
84
|
+
*/
|
|
85
|
+
function scanSecrets(cwd) {
|
|
86
|
+
const patterns = ['password=', 'secret=', 'api_key=', 'private_key=', 'auth_token='];
|
|
87
|
+
const found = [];
|
|
88
|
+
const skipDirs = new Set(['node_modules', '.git', 'dist', '__pycache__', '.agent']);
|
|
89
|
+
|
|
90
|
+
function walk(dir) {
|
|
91
|
+
let entries;
|
|
92
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
|
93
|
+
|
|
94
|
+
for (const entry of entries) {
|
|
95
|
+
const fullPath = path.join(dir, entry.name);
|
|
96
|
+
if (entry.isDirectory()) {
|
|
97
|
+
if (!skipDirs.has(entry.name)) walk(fullPath);
|
|
98
|
+
} else if (entry.isFile()) {
|
|
99
|
+
if (!/\.(ts|js|tsx|jsx|py)$/.test(entry.name)) continue;
|
|
100
|
+
|
|
101
|
+
let content;
|
|
102
|
+
try { content = fs.readFileSync(fullPath, 'utf8'); } catch { continue; }
|
|
103
|
+
|
|
104
|
+
const lines = content.split('\n');
|
|
105
|
+
for (let i = 0; i < lines.length; i++) {
|
|
106
|
+
const low = lines[i].toLowerCase().trim();
|
|
107
|
+
const hasPattern = patterns.some(p => low.includes(p));
|
|
108
|
+
if (hasPattern && !low.startsWith('#') && low.includes('=')) {
|
|
109
|
+
const rel = path.relative(cwd, fullPath);
|
|
110
|
+
found.push(`${rel}:${i + 1}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
walk(cwd);
|
|
118
|
+
|
|
119
|
+
if (found.length > 0) {
|
|
120
|
+
fail('Secret scan', found.slice(0, 5).join('\n '));
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
ok('Secret scan — no hardcoded credentials found');
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Check if there's a package.json to run npm commands against.
|
|
130
|
+
*/
|
|
131
|
+
function hasNpm(cwd) {
|
|
132
|
+
return fs.existsSync(path.join(cwd, 'package.json'));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Run all verification checks. Returns number of failures.
|
|
138
|
+
*/
|
|
139
|
+
function verifyAll(cwd, skipped) {
|
|
140
|
+
let failures = 0;
|
|
141
|
+
RESULTS.length = 0; // Reset for clean runs (prevents accumulation in tests)
|
|
142
|
+
|
|
143
|
+
section('1 — Secret Scan');
|
|
144
|
+
if (!skipped.includes('secrets')) {
|
|
145
|
+
if (!scanSecrets(cwd)) failures++;
|
|
146
|
+
} else {
|
|
147
|
+
skip('Secret scan', 'skipped by flag');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
section('2 — TypeScript');
|
|
151
|
+
if (!skipped.includes('typescript')) {
|
|
152
|
+
if (hasNpm(cwd)) {
|
|
153
|
+
if (!run('tsc --noEmit', ['npx', 'tsc', '--noEmit'], cwd)) failures++;
|
|
154
|
+
} else {
|
|
155
|
+
skip('TypeScript', 'no package.json found in project');
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
skip('TypeScript', 'skipped by flag');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
section('3 — ESLint');
|
|
162
|
+
if (!skipped.includes('lint')) {
|
|
163
|
+
if (hasNpm(cwd)) {
|
|
164
|
+
if (!run('ESLint', ['npx', 'eslint', '.', '--max-warnings=0'], cwd)) failures++;
|
|
165
|
+
} else {
|
|
166
|
+
skip('ESLint', 'no package.json found in project');
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
skip('ESLint', 'skipped by flag');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
section('4 — Unit Tests');
|
|
173
|
+
if (!skipped.includes('tests')) {
|
|
174
|
+
if (hasNpm(cwd)) {
|
|
175
|
+
if (!run('Test suite', ['npm', 'test', '--', '--passWithNoTests'], cwd)) failures++;
|
|
176
|
+
} else {
|
|
177
|
+
skip('Tests', 'no package.json found in project');
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
skip('Tests', 'skipped by flag');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
section('5 — Build');
|
|
184
|
+
if (!skipped.includes('build')) {
|
|
185
|
+
if (hasNpm(cwd)) {
|
|
186
|
+
if (!run('npm run build', ['npm', 'run', 'build'], cwd)) failures++;
|
|
187
|
+
} else {
|
|
188
|
+
skip('Build', 'no package.json found in project');
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
skip('Build', 'skipped by flag');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
section('6 — Dependency Audit');
|
|
195
|
+
if (!skipped.includes('deps')) {
|
|
196
|
+
if (hasNpm(cwd)) {
|
|
197
|
+
if (!run('npm audit', ['npm', 'audit', '--audit-level=high'], cwd)) failures++;
|
|
198
|
+
} else {
|
|
199
|
+
skip('Dependency audit', 'no package.json found in project');
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
skip('Dependency audit', 'skipped by flag');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// ━━━ Summary ━━━
|
|
206
|
+
console.log(`\n${BOLD}━━━ Summary ━━━${RESET}`);
|
|
207
|
+
for (const { label, passed, note } of RESULTS) {
|
|
208
|
+
const status = passed ? `${GREEN}✅${RESET}` : `${RED}❌${RESET}`;
|
|
209
|
+
const noteStr = (!passed && note) ? ` ${YELLOW}(${note})${RESET}` : '';
|
|
210
|
+
console.log(` ${status} ${label}${noteStr}`);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
console.log();
|
|
214
|
+
if (failures === 0) {
|
|
215
|
+
console.log(`${GREEN}${BOLD}All checks passed — safe to deploy.${RESET}`);
|
|
216
|
+
} else {
|
|
217
|
+
console.log(`${RED}${BOLD}${failures} check(s) failed — fix before deploying.${RESET}`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return failures;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Parse CLI arguments manually (no external dependencies).
|
|
226
|
+
*/
|
|
227
|
+
function parseArgs(argv) {
|
|
228
|
+
const args = { skip: [] };
|
|
229
|
+
const raw = argv.slice(2);
|
|
230
|
+
|
|
231
|
+
for (let i = 0; i < raw.length; i++) {
|
|
232
|
+
if (raw[i] === '--skip' && raw[i + 1]) {
|
|
233
|
+
args.skip = raw[++i].split(',').map(s => s.trim().toLowerCase()).filter(Boolean);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return args;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
function main() {
|
|
241
|
+
const args = parseArgs(process.argv);
|
|
242
|
+
const cwd = process.cwd();
|
|
243
|
+
|
|
244
|
+
console.log(`${BOLD}Tribunal — verify_all.js${RESET}`);
|
|
245
|
+
console.log(`Project: ${cwd}\n`);
|
|
246
|
+
|
|
247
|
+
const failures = verifyAll(cwd, args.skip);
|
|
248
|
+
process.exit(failures > 0 ? 1 : 0);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
// ━━━ Exports for testing & programmatic use ━━━
|
|
253
|
+
module.exports = { verifyAll, scanSecrets, hasNpm };
|
|
254
|
+
|
|
255
|
+
if (require.main === module) {
|
|
256
|
+
main();
|
|
257
|
+
}
|
|
@@ -119,4 +119,4 @@ project-name/
|
|
|
119
119
|
- **Mutations**: Use Server Actions combined with React 19's `useActionState` to handle loading and error states instead of manual useState.
|
|
120
120
|
- **Type Safety**: Share Zod schemas between Server Actions (input validation) and Client Forms.
|
|
121
121
|
- **Security**: Always validate input data with Zod before passing it to Prisma.
|
|
122
|
-
- **Styling**: Use native CSS variables in Tailwind v4 for easier dynamic theming.
|
|
122
|
+
- **Styling**: Use native CSS variables in Tailwind v4 for easier dynamic theming.
|
|
@@ -166,4 +166,4 @@ export const metadata: Metadata = {
|
|
|
166
166
|
- **React Server Components (RSC)**: Default all components to Server Components. Only add `'use client'` when you need state (`useState`) or event listeners (`onClick`).
|
|
167
167
|
- **Image Optimization**: Use the `<Image />` component but remember `unoptimized: true` for static export or use an external image CDN (Cloudinary/Imgix).
|
|
168
168
|
- **Font Optimization**: Use `next/font` (Google Fonts) to automatically host fonts and prevent layout shift.
|
|
169
|
-
- **Responsive**: Mobile-first design using Tailwind prefixes like `sm:`, `md:`, `lg:`.
|
|
169
|
+
- **Responsive**: Mobile-first design using Tailwind prefixes like `sm:`, `md:`, `lg:`.
|
|
@@ -131,4 +131,4 @@ project-name/
|
|
|
131
131
|
```
|
|
132
132
|
- **Data Fetching**: Sử dụng `useFetch` với `server: false` cho các tác vụ client-only, hoặc dùng Server Functions để type-safety tốt hơn.
|
|
133
133
|
- **State**: Dùng `defineStore` (Pinia) cho global state, `useState` của Nuxt cho state đơn giản chia sẻ giữa Server/Client.
|
|
134
|
-
- **Type Safety**: Tự động tạo type cho API routes (`$fetch` typed automatically).
|
|
134
|
+
- **Type Safety**: Tự động tạo type cho API routes (`$fetch` typed automatically).
|
|
@@ -116,4 +116,4 @@ project-name/
|
|
|
116
116
|
- **React 19**: Reduce usage of `useMemo` or `useCallback` thanks to React Compiler (if enabled).
|
|
117
117
|
- **Components**: Build UI primitives (Box, Text) with NativeWind className for reusability.
|
|
118
118
|
- **Assets**: Use `expo-image` instead of default `<Image />` for better caching and performance.
|
|
119
|
-
- **API**: Always wrap API calls with TanStack Query, avoid direct calls in `useEffect`.
|
|
119
|
+
- **API**: Always wrap API calls with TanStack Query, avoid direct calls in `useEffect`.
|
package/.agent/skills/doc.md
CHANGED
|
@@ -174,4 +174,4 @@ By creating Skills, you transform a general AI model into an expert for your pro
|
|
|
174
174
|
- ✅ Automatically add license headers
|
|
175
175
|
- ✅ The Agent automatically knows how to work with your team
|
|
176
176
|
|
|
177
|
-
Instead of constantly reminding the AI to "remember to add the license" or "fix the commit format," now the Agent will do it automatically!
|
|
177
|
+
Instead of constantly reminding the AI to "remember to add the license" or "fix the commit format," now the Agent will do it automatically!
|