tribunal-kit 6.0.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/.manifest.json +78 -0
- package/.agent/ARCHITECTURE.md +19 -241
- package/.agent/agents/accessibility-reviewer.md +23 -16
- package/.agent/agents/ai-code-reviewer.md +25 -21
- package/.agent/agents/anti-pattern-reviewer.md +12 -7
- package/.agent/agents/api-architect.md +1 -0
- package/.agent/agents/backend-specialist.md +23 -22
- package/.agent/agents/cloud-engineer.md +1 -0
- package/.agent/agents/code-archaeologist.md +1 -0
- package/.agent/agents/complexity-reviewer.md +10 -7
- package/.agent/agents/database-architect.md +3 -2
- package/.agent/agents/db-latency-auditor.md +6 -2
- package/.agent/agents/debugger.md +3 -2
- package/.agent/agents/dependency-reviewer.md +1 -0
- package/.agent/agents/devops-engineer.md +9 -8
- package/.agent/agents/documentation-writer.md +6 -5
- package/.agent/agents/explorer-agent.md +1 -0
- package/.agent/agents/frontend-reviewer.md +21 -17
- package/.agent/agents/frontend-specialist.md +23 -20
- package/.agent/agents/game-developer.md +1 -0
- package/.agent/agents/interaction-reviewer.md +10 -5
- package/.agent/agents/logic-reviewer.md +3 -0
- package/.agent/agents/minimalist-reviewer.md +6 -0
- package/.agent/agents/mobile-developer.md +7 -6
- package/.agent/agents/mobile-reviewer.md +14 -13
- package/.agent/agents/orchestrator.md +3 -0
- package/.agent/agents/penetration-tester.md +1 -0
- package/.agent/agents/performance-optimizer.md +6 -5
- package/.agent/agents/performance-reviewer.md +6 -6
- package/.agent/agents/pipeline-reviewer.md +144 -0
- package/.agent/agents/precedence-reviewer.md +1 -0
- package/.agent/agents/product-manager.md +1 -0
- package/.agent/agents/product-owner.md +1 -0
- package/.agent/agents/product-reviewer.md +12 -7
- package/.agent/agents/project-planner.md +3 -0
- package/.agent/agents/qa-automation-engineer.md +50 -43
- package/.agent/agents/resilience-reviewer.md +1 -0
- package/.agent/agents/schema-reviewer.md +1 -0
- package/.agent/agents/security-auditor.md +24 -24
- package/.agent/agents/seo-specialist.md +33 -23
- package/.agent/agents/sql-reviewer.md +5 -4
- package/.agent/agents/supervisor-agent.md +12 -2
- package/.agent/agents/swarm-worker-contracts.md +13 -13
- package/.agent/agents/swarm-worker-registry.md +51 -51
- package/.agent/agents/system-architect.md +1 -0
- package/.agent/agents/test-coverage-reviewer.md +25 -22
- package/.agent/agents/test-engineer.md +12 -11
- package/.agent/agents/throughput-optimizer.md +45 -40
- package/.agent/agents/type-safety-reviewer.md +5 -4
- package/.agent/agents/ui-ux-auditor.md +6 -4
- package/.agent/agents/ui-visual-auditor.md +3 -0
- package/.agent/agents/ux-reviewer.md +11 -6
- package/.agent/agents/visual-reviewer.md +11 -6
- package/.agent/agents/vitals-reviewer.md +5 -4
- package/.agent/history/memory/.memory.idx +3716 -1
- package/.agent/history/memory/MEMORY.md +246 -1
- package/.agent/mcp_config.json +1 -6
- package/.agent/routing_index.json +2034 -263
- package/.agent/rules/GEMINI.md +12 -10
- package/.agent/rules/GEMINI_PLANNER.md +19 -21
- package/.agent/scripts/_colors.js +52 -54
- package/.agent/scripts/_utils.js +52 -53
- package/.agent/scripts/auto_preview.js +39 -43
- package/.agent/scripts/bundle_analyzer.js +47 -60
- package/.agent/scripts/case_law_manager.js +200 -294
- package/.agent/scripts/checklist.js +73 -94
- package/.agent/scripts/cicd_validator.js +305 -0
- package/.agent/scripts/compile_router.py +4 -111
- package/.agent/scripts/context_broker.js +317 -412
- package/.agent/scripts/contract_engine.js +402 -0
- package/.agent/scripts/dependency_analyzer.js +112 -124
- package/.agent/scripts/graph_builder.js +75 -103
- package/.agent/scripts/graph_visualizer.js +10 -12
- package/.agent/scripts/graph_zoom.js +38 -55
- package/.agent/scripts/guardrail_engine.js +195 -145
- package/.agent/scripts/impact_classifier.js +55 -30
- package/.agent/scripts/inner_loop_validator.js +108 -159
- package/.agent/scripts/integrity_manifest.js +59 -67
- package/.agent/scripts/lint_runner.js +65 -75
- package/.agent/scripts/marathon_harness.js +131 -208
- package/.agent/scripts/migrate_skills_frontmatter.py +4 -63
- package/.agent/scripts/minify_context.js +29 -33
- package/.agent/scripts/minimal_change_engine.js +95 -87
- package/.agent/scripts/mutation_runner.js +46 -62
- package/.agent/scripts/pipeline_engine.js +320 -209
- package/.agent/scripts/prompt_compiler.js +118 -93
- package/.agent/scripts/schema_validator.js +73 -121
- package/.agent/scripts/security_scan.js +88 -117
- package/.agent/scripts/session_manager.js +52 -69
- package/.agent/scripts/signal_detector.js +24 -22
- package/.agent/scripts/skill_evolution.js +184 -245
- package/.agent/scripts/skill_integrator.js +35 -48
- package/.agent/scripts/socratic_gate_policy.js +15 -12
- package/.agent/scripts/strengthen_skills.js +29 -33
- package/.agent/scripts/swarm_dispatcher.js +120 -151
- package/.agent/scripts/test_runner.js +54 -56
- package/.agent/scripts/token_budget_broker.js +9 -7
- package/.agent/scripts/trace_engine.js +126 -0
- package/.agent/scripts/verify_all.js +76 -93
- package/.agent/scripts/visual_audit.js +16 -21
- package/.agent/skill_topic_map.json +237 -0
- package/.agent/skills/12-principles-of-animation/SKILL.md +7 -0
- package/.agent/skills/60fps-animation/SKILL.md +7 -0
- package/.agent/skills/accessible-animation/SKILL.md +5 -1
- package/.agent/skills/adapt/SKILL.md +7 -1
- package/.agent/skills/advanced-rag-pipelines/SKILL.md +1 -0
- package/.agent/skills/agent-organizer/SKILL.md +1 -0
- package/.agent/skills/agentic-patterns/SKILL.md +33 -25
- package/.agent/skills/agentic-workflows-2026/SKILL.md +80 -0
- package/.agent/skills/ai-app-hardening/SKILL.md +59 -0
- package/.agent/skills/ai-prompt-injection-defense/SKILL.md +7 -6
- package/.agent/skills/animation-on-scroll/SKILL.md +24 -15
- package/.agent/skills/animation-systems/SKILL.md +11 -10
- package/.agent/skills/antfu-conventions/SKILL.md +7 -2
- package/.agent/skills/api-patterns/SKILL.md +14 -10
- package/.agent/skills/api-security-auditor/SKILL.md +15 -14
- package/.agent/skills/app-builder/SKILL.md +1 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +2 -2
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +12 -12
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +3 -3
- package/.agent/skills/apple-design/SKILL.md +8 -7
- package/.agent/skills/architecture/SKILL.md +3 -2
- package/.agent/skills/audit-and-fix/SKILL.md +8 -5
- package/.agent/skills/authentication-best-practices/SKILL.md +9 -8
- package/.agent/skills/backend-security-expert/SKILL.md +1 -0
- package/.agent/skills/baseline-ui/SKILL.md +8 -7
- package/.agent/skills/bash-linux/SKILL.md +1 -0
- package/.agent/skills/behavioral-modes/SKILL.md +1 -0
- package/.agent/skills/better-colors/SKILL.md +11 -7
- package/.agent/skills/better-typography/SKILL.md +30 -16
- package/.agent/skills/better-ui/SKILL.md +17 -10
- package/.agent/skills/bolder/SKILL.md +6 -0
- package/.agent/skills/brainstorming/SKILL.md +6 -4
- package/.agent/skills/browser-native-ai/SKILL.md +5 -4
- package/.agent/skills/build-primitive/SKILL.md +5 -0
- package/.agent/skills/building-native-ui/SKILL.md +1 -0
- package/.agent/skills/cicd-pro/SKILL.md +2 -1
- package/.agent/skills/clarify/SKILL.md +19 -14
- package/.agent/skills/clean-code/SKILL.md +16 -15
- package/.agent/skills/cloud-architect/SKILL.md +1 -0
- package/.agent/skills/cobejs/SKILL.md +7 -9
- package/.agent/skills/code-review-checklist/SKILL.md +1 -0
- package/.agent/skills/codebase-design/SKILL.md +7 -2
- package/.agent/skills/colorize/SKILL.md +8 -3
- package/.agent/skills/compact-landing/SKILL.md +8 -3
- package/.agent/skills/company-logos/SKILL.md +6 -0
- package/.agent/skills/config-validator/SKILL.md +10 -9
- package/.agent/skills/containerization-pro/SKILL.md +6 -5
- package/.agent/skills/context-engineering-pro/SKILL.md +70 -0
- package/.agent/skills/create-design-md/SKILL.md +13 -5
- package/.agent/skills/critique/SKILL.md +10 -8
- package/.agent/skills/csharp-developer/SKILL.md +1 -0
- package/.agent/skills/data-validation-schemas/SKILL.md +28 -23
- package/.agent/skills/database-design/SKILL.md +2 -1
- package/.agent/skills/delight/SKILL.md +6 -0
- package/.agent/skills/deployment-procedures/SKILL.md +2 -1
- package/.agent/skills/design-lab/SKILL.md +5 -0
- package/.agent/skills/devops-engineer/SKILL.md +3 -2
- package/.agent/skills/devops-incident-responder/SKILL.md +2 -1
- package/.agent/skills/diagnosing-bugs/SKILL.md +12 -2
- package/.agent/skills/distill/SKILL.md +7 -2
- package/.agent/skills/documentation-templates/SKILL.md +3 -2
- package/.agent/skills/domain-modeling/SKILL.md +12 -4
- package/.agent/skills/duckdb-analytical-sql/SKILL.md +59 -0
- package/.agent/skills/edge-ai-mobile/SKILL.md +50 -0
- package/.agent/skills/edge-computing/SKILL.md +9 -8
- package/.agent/skills/emil-design-eng/SKILL.md +43 -27
- package/.agent/skills/error-resilience/SKILL.md +34 -16
- package/.agent/skills/expo-router-v4/SKILL.md +81 -0
- package/.agent/skills/extract-design-system/SKILL.md +12 -11
- package/.agent/skills/fabel-protocol/SKILL.md +24 -17
- package/.agent/skills/fixing-accessibility/SKILL.md +23 -16
- package/.agent/skills/fixing-metadata/SKILL.md +24 -13
- package/.agent/skills/fixing-motion-performance/SKILL.md +7 -5
- package/.agent/skills/framer-motion-expert/SKILL.md +29 -15
- package/.agent/skills/frontend-design/SKILL.md +21 -13
- package/.agent/skills/frontend-security-expert/SKILL.md +1 -0
- package/.agent/skills/game-design-expert/SKILL.md +1 -0
- package/.agent/skills/game-engineering-expert/SKILL.md +1 -0
- package/.agent/skills/generative-ui-expert/SKILL.md +3 -2
- package/.agent/skills/geo-fundamentals/SKILL.md +2 -1
- package/.agent/skills/git-pro/SKILL.md +10 -9
- package/.agent/skills/github-operations/SKILL.md +2 -1
- package/.agent/skills/gpt-taste/SKILL.md +7 -0
- package/.agent/skills/gsap-core/SKILL.md +26 -22
- package/.agent/skills/gsap-frameworks/SKILL.md +6 -5
- package/.agent/skills/gsap-performance/SKILL.md +4 -3
- package/.agent/skills/gsap-plugins/SKILL.md +34 -33
- package/.agent/skills/gsap-react/SKILL.md +9 -8
- package/.agent/skills/gsap-scrolltrigger/SKILL.md +34 -33
- package/.agent/skills/gsap-timeline/SKILL.md +18 -15
- package/.agent/skills/gsap-utils/SKILL.md +25 -24
- package/.agent/skills/harden/SKILL.md +9 -3
- package/.agent/skills/harness-protocol/SKILL.md +1 -0
- package/.agent/skills/i18n-localization/SKILL.md +10 -9
- package/.agent/skills/impeccable/SKILL.md +5 -0
- package/.agent/skills/improve-codebase-architecture/SKILL.md +10 -5
- package/.agent/skills/improve-ui/SKILL.md +12 -5
- package/.agent/skills/intelligent-routing/SKILL.md +7 -6
- package/.agent/skills/knowledge-graph/SKILL.md +1 -0
- package/.agent/skills/landing-page/SKILL.md +1 -0
- package/.agent/skills/lint-and-validate/SKILL.md +9 -4
- package/.agent/skills/llm-engineering/SKILL.md +55 -54
- package/.agent/skills/local-first/SKILL.md +20 -19
- package/.agent/skills/local-first-architecture/SKILL.md +6 -1
- package/.agent/skills/lottie-animation/SKILL.md +7 -3
- package/.agent/skills/marquee-loop/SKILL.md +1 -0
- package/.agent/skills/masked-reveal/SKILL.md +17 -4
- package/.agent/skills/mcp-builder/SKILL.md +13 -10
- package/.agent/skills/micro-interaction/SKILL.md +20 -5
- package/.agent/skills/mobile-design/SKILL.md +26 -15
- package/.agent/skills/monorepo-management/SKILL.md +3 -2
- package/.agent/skills/morphing-icons/SKILL.md +16 -6
- package/.agent/skills/motion-engineering/SKILL.md +19 -15
- package/.agent/skills/nextjs-react-expert/SKILL.md +26 -21
- package/.agent/skills/nodejs-best-practices/SKILL.md +89 -76
- package/.agent/skills/observability/SKILL.md +45 -44
- package/.agent/skills/opentelemetry-observability/SKILL.md +59 -0
- package/.agent/skills/page-transition-animation/SKILL.md +6 -3
- package/.agent/skills/parallel-agents/SKILL.md +7 -2
- package/.agent/skills/performance-profiling/SKILL.md +24 -13
- package/.agent/skills/plan-writing/SKILL.md +1 -0
- package/.agent/skills/platform-engineer/SKILL.md +3 -2
- package/.agent/skills/platform-engineering-opentofu/SKILL.md +68 -0
- package/.agent/skills/playwright-ai-e2e/SKILL.md +60 -0
- package/.agent/skills/playwright-best-practices/SKILL.md +29 -28
- package/.agent/skills/polish/SKILL.md +13 -12
- package/.agent/skills/powershell-windows/SKILL.md +1 -0
- package/.agent/skills/pricing-page/SKILL.md +8 -3
- package/.agent/skills/product-aware-heuristics/SKILL.md +122 -72
- package/.agent/skills/progressive-blur/SKILL.md +9 -4
- package/.agent/skills/project-idioms/SKILL.md +1 -0
- package/.agent/skills/property-based-testing/SKILL.md +58 -0
- package/.agent/skills/python-patterns/SKILL.md +1 -0
- package/.agent/skills/python-pro/SKILL.md +1 -0
- package/.agent/skills/quieter/SKILL.md +6 -0
- package/.agent/skills/react-doctor/SKILL.md +6 -0
- package/.agent/skills/react-specialist/SKILL.md +32 -28
- package/.agent/skills/readme-builder/SKILL.md +1 -0
- package/.agent/skills/realtime-patterns/SKILL.md +34 -33
- package/.agent/skills/red-team-tactics/SKILL.md +1 -0
- package/.agent/skills/redesign-skill/SKILL.md +6 -0
- package/.agent/skills/review-animations/SKILL.md +5 -2
- package/.agent/skills/review-animations/STANDARDS.md +37 -23
- package/.agent/skills/rust-pro/SKILL.md +1 -0
- package/.agent/skills/seo-fundamentals/SKILL.md +4 -3
- package/.agent/skills/server-management/SKILL.md +1 -0
- package/.agent/skills/shadcn-ui-expert/SKILL.md +28 -22
- package/.agent/skills/shape/SKILL.md +9 -2
- package/.agent/skills/skill-creator/SKILL.md +1 -0
- package/.agent/skills/soft-skill/SKILL.md +6 -0
- package/.agent/skills/sounds-on-the-web/SKILL.md +1 -0
- package/.agent/skills/sql-pro/SKILL.md +1 -0
- package/.agent/skills/supabase-postgres-best-practices/SKILL.md +1 -0
- package/.agent/skills/svg-animation/SKILL.md +16 -7
- package/.agent/skills/swiftui-expert/SKILL.md +1 -0
- package/.agent/skills/swiss-design/SKILL.md +5 -0
- package/.agent/skills/system-design-pro/SKILL.md +1 -0
- package/.agent/skills/systematic-debugging/SKILL.md +1 -0
- package/.agent/skills/tailwind-patterns/SKILL.md +25 -11
- package/.agent/skills/taste-skill/SKILL.md +6 -0
- package/.agent/skills/tdd-workflow/SKILL.md +5 -0
- package/.agent/skills/test-result-analyzer/SKILL.md +1 -0
- package/.agent/skills/testing-patterns/SKILL.md +123 -115
- package/.agent/skills/thermo-nuclear-code-quality-review/SKILL.md +5 -0
- package/.agent/skills/thinking-protocol/SKILL.md +3 -0
- package/.agent/skills/to-spring-or-not-to-spring/SKILL.md +9 -8
- package/.agent/skills/transitions-dev/SKILL.md +19 -6
- package/.agent/skills/trend-researcher/SKILL.md +1 -0
- package/.agent/skills/typescript-advanced/SKILL.md +23 -18
- package/.agent/skills/typeset/SKILL.md +10 -1
- package/.agent/skills/ui-reasoning-engine/SKILL.md +67 -48
- package/.agent/skills/ui-skill-packs/SKILL.md +6 -1
- package/.agent/skills/ui-skills-root/SKILL.md +39 -38
- package/.agent/skills/ui-ux-pro-max/SKILL.md +34 -26
- package/.agent/skills/ui-ux-researcher/SKILL.md +1 -0
- package/.agent/skills/vector-search-pgvector/SKILL.md +78 -0
- package/.agent/skills/vue-expert/SKILL.md +22 -19
- package/.agent/skills/vulnerability-scanner/SKILL.md +22 -21
- package/.agent/skills/web-accessibility-auditor/SKILL.md +2 -1
- package/.agent/skills/web-design-guidelines/SKILL.md +16 -10
- package/.agent/skills/web-quality-audit/SKILL.md +5 -0
- package/.agent/skills/webapp-testing/SKILL.md +14 -13
- package/.agent/skills/webgpu-performance/SKILL.md +1 -0
- package/.agent/skills/whimsy-injector/SKILL.md +9 -5
- package/.agent/skills/workflow-optimizer/SKILL.md +1 -0
- package/.agent/skills/zero-trust-passkeys/SKILL.md +90 -0
- package/.agent/templates/DESIGN.md +119 -110
- package/.agent/templates/design-tokens.json +9 -6
- package/.agent/workflows/acf.md +1 -0
- package/.agent/workflows/api-tester.md +1 -0
- package/.agent/workflows/audit.md +1 -0
- package/.agent/workflows/brainstorm.md +1 -0
- package/.agent/workflows/changelog.md +1 -0
- package/.agent/workflows/contract.md +60 -0
- package/.agent/workflows/create.md +1 -0
- package/.agent/workflows/debug.md +1 -0
- package/.agent/workflows/deploy.md +1 -0
- package/.agent/workflows/enhance.md +1 -0
- package/.agent/workflows/fix-ci.md +89 -0
- package/.agent/workflows/fix.md +1 -0
- package/.agent/workflows/generate.md +1 -0
- package/.agent/workflows/marathon.md +1 -0
- package/.agent/workflows/migrate.md +1 -0
- package/.agent/workflows/minimal.md +9 -7
- package/.agent/workflows/orchestrate.md +1 -0
- package/.agent/workflows/performance-benchmarker.md +1 -0
- package/.agent/workflows/pipeline.md +26 -21
- package/.agent/workflows/plan.md +1 -0
- package/.agent/workflows/preview.md +1 -0
- package/.agent/workflows/refactor.md +3 -2
- package/.agent/workflows/review-ai.md +4 -3
- package/.agent/workflows/review.md +1 -0
- package/.agent/workflows/session.md +1 -0
- package/.agent/workflows/status.md +1 -0
- package/.agent/workflows/strengthen-skills.md +1 -0
- package/.agent/workflows/super-prompt.md +1 -0
- package/.agent/workflows/swarm.md +15 -3
- package/.agent/workflows/test.md +8 -7
- package/.agent/workflows/tribunal-backend.md +3 -2
- package/.agent/workflows/tribunal-cicd.md +104 -0
- package/.agent/workflows/tribunal-database.md +1 -0
- package/.agent/workflows/tribunal-frontend.md +8 -6
- package/.agent/workflows/tribunal-full.md +15 -14
- package/.agent/workflows/tribunal-mobile.md +6 -5
- package/.agent/workflows/tribunal-performance.md +1 -0
- package/.agent/workflows/tribunal-speed.md +1 -0
- package/.agent/workflows/tribunal-ui.md +29 -21
- package/.agent/workflows/ui-ux-pro-max.md +19 -15
- package/CONTRIBUTING.md +3 -3
- package/README.md +160 -88
- package/SECURITY.md +11 -11
- package/bin/mcp-server.js +512 -233
- package/bin/tribunal-kit.js +29 -30
- package/bin/wrapper.js +45 -48
- package/dist/cli.js +26 -0
- package/dist/commands/case.js +2 -0
- package/dist/commands/contract.js +440 -0
- package/dist/commands/memory.js +3 -2
- package/dist/commands/native.js +36 -0
- package/dist/commands/status.js +6 -0
- package/dist/esm/index.mjs +32 -0
- package/dist/index.d.ts +58 -3
- package/package.json +20 -16
- package/scripts/benchmark.js +62 -86
- package/scripts/changelog.js +67 -73
- package/scripts/fix-vbc.js +13 -15
- package/scripts/fix-vbc.ps1 +2 -118
- package/scripts/stress_benchmark.js +358 -0
- package/scripts/sync-version.js +71 -41
- package/scripts/validate-payload.js +23 -30
- package/scripts/visual_audit.js +23 -13
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
* }
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
'use strict';
|
|
37
37
|
|
|
38
|
-
const fs = require(
|
|
39
|
-
const path = require(
|
|
38
|
+
const fs = require('fs');
|
|
39
|
+
const path = require('path');
|
|
40
40
|
|
|
41
41
|
// ── Resolve security_scan patterns (reuse — do not duplicate) ─────────────
|
|
42
42
|
const SCRIPT_DIR = __dirname;
|
|
@@ -44,7 +44,7 @@ let SECURITY_PATTERNS = [];
|
|
|
44
44
|
let SEVERITY_RANK = {};
|
|
45
45
|
|
|
46
46
|
try {
|
|
47
|
-
const secScan = require(path.join(SCRIPT_DIR,
|
|
47
|
+
const secScan = require(path.join(SCRIPT_DIR, 'security_scan.js'));
|
|
48
48
|
SECURITY_PATTERNS = secScan.PATTERNS || [];
|
|
49
49
|
SEVERITY_RANK = secScan.SEVERITY_RANK || {
|
|
50
50
|
critical: 0,
|
|
@@ -57,23 +57,13 @@ try {
|
|
|
57
57
|
SECURITY_PATTERNS = [
|
|
58
58
|
[
|
|
59
59
|
/(?:password|passwd)\s*=\s*["'][^"']+["']/i,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
],
|
|
64
|
-
[
|
|
65
|
-
/\beval\s*\(/,
|
|
66
|
-
"high",
|
|
67
|
-
"Code Injection",
|
|
68
|
-
"eval() is a code injection vector",
|
|
69
|
-
],
|
|
70
|
-
[/\.innerHTML\s*=/, "high", "XSS", "Direct innerHTML assignment"],
|
|
71
|
-
[
|
|
72
|
-
/algorithms\s*:\s*\[\s*["']none["']/,
|
|
73
|
-
"critical",
|
|
74
|
-
"Auth Bypass",
|
|
75
|
-
"JWT 'none' algorithm",
|
|
60
|
+
'critical',
|
|
61
|
+
'Hardcoded Secret',
|
|
62
|
+
'Hardcoded password',
|
|
76
63
|
],
|
|
64
|
+
[/\beval\s*\(/, 'high', 'Code Injection', 'eval() is a code injection vector'],
|
|
65
|
+
[/\.innerHTML\s*=/, 'high', 'XSS', 'Direct innerHTML assignment'],
|
|
66
|
+
[/algorithms\s*:\s*\[\s*["']none["']/, 'critical', 'Auth Bypass', "JWT 'none' algorithm"],
|
|
77
67
|
];
|
|
78
68
|
SEVERITY_RANK = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
79
69
|
}
|
|
@@ -83,68 +73,64 @@ try {
|
|
|
83
73
|
const SYNTAX_HEURISTICS = [
|
|
84
74
|
{
|
|
85
75
|
pattern: /\bconst\s+\w+\s*=\s*require\s*\(\s*["'](?!\.\/|\.\.\/|[a-zA-Z])/,
|
|
86
|
-
severity:
|
|
87
|
-
category:
|
|
88
|
-
message:
|
|
89
|
-
fix:
|
|
76
|
+
severity: 'medium',
|
|
77
|
+
category: 'Hallucination Risk',
|
|
78
|
+
message: 'Suspicious require() path — verify module exists in package.json',
|
|
79
|
+
fix: 'Check that this package is listed in package.json dependencies',
|
|
90
80
|
},
|
|
91
81
|
{
|
|
92
82
|
pattern: /\/\/\s*VERIFY:/,
|
|
93
|
-
severity:
|
|
94
|
-
category:
|
|
95
|
-
message:
|
|
96
|
-
|
|
97
|
-
fix: "The Maker Agent marked this with // VERIFY: — confirm before approving",
|
|
83
|
+
severity: 'low',
|
|
84
|
+
category: 'Verification Flag',
|
|
85
|
+
message: 'Maker Agent flagged this line as uncertain — human review required',
|
|
86
|
+
fix: 'The Maker Agent marked this with // VERIFY: — confirm before approving',
|
|
98
87
|
},
|
|
99
88
|
{
|
|
100
89
|
pattern: /:\s*any\b(?!\s*=)/,
|
|
101
|
-
severity:
|
|
102
|
-
category:
|
|
103
|
-
message:
|
|
104
|
-
fix:
|
|
90
|
+
severity: 'low',
|
|
91
|
+
category: 'Type Safety',
|
|
92
|
+
message: 'TypeScript `any` type used without explanation comment',
|
|
93
|
+
fix: 'Replace :any with a specific type, or add // any: [reason] comment',
|
|
105
94
|
},
|
|
106
95
|
{
|
|
107
96
|
pattern: /process\.env\.\w+(?!\s*\?\?|\s*\|\|)/,
|
|
108
|
-
severity:
|
|
109
|
-
category:
|
|
110
|
-
message:
|
|
111
|
-
"process.env access without nullish fallback — may throw at runtime",
|
|
97
|
+
severity: 'low',
|
|
98
|
+
category: 'Config Safety',
|
|
99
|
+
message: 'process.env access without nullish fallback — may throw at runtime',
|
|
112
100
|
fix: 'Use: process.env.VAR ?? "default" — always guard env var access',
|
|
113
101
|
},
|
|
114
102
|
{
|
|
115
103
|
pattern: /throw\s+["'`]/,
|
|
116
|
-
severity:
|
|
117
|
-
category:
|
|
118
|
-
message:
|
|
119
|
-
"Throwing a string instead of an Error object — stack traces will be lost",
|
|
104
|
+
severity: 'low',
|
|
105
|
+
category: 'Error Quality',
|
|
106
|
+
message: 'Throwing a string instead of an Error object — stack traces will be lost',
|
|
120
107
|
fix: 'Use: throw new Error("message") instead of throw "message"',
|
|
121
108
|
},
|
|
122
109
|
{
|
|
123
110
|
pattern: /catch\s*\(\s*\w+\s*\)\s*\{?\s*\}/,
|
|
124
|
-
severity:
|
|
125
|
-
category:
|
|
126
|
-
message:
|
|
127
|
-
fix:
|
|
111
|
+
severity: 'medium',
|
|
112
|
+
category: 'Error Handling',
|
|
113
|
+
message: 'Empty catch block swallows errors silently',
|
|
114
|
+
fix: 'Add at minimum: catch (err) { console.error(err); throw err; }',
|
|
128
115
|
},
|
|
129
116
|
{
|
|
130
117
|
pattern: /\.then\(\s*\)\s*\.catch\s*\(|\.catch\s*\(\s*\)/,
|
|
131
|
-
severity:
|
|
132
|
-
category:
|
|
133
|
-
message:
|
|
134
|
-
|
|
135
|
-
fix: "Implement proper resolution and rejection handlers",
|
|
118
|
+
severity: 'medium',
|
|
119
|
+
category: 'Error Handling',
|
|
120
|
+
message: 'Empty .then() or .catch() handler — Promise errors may be silenced',
|
|
121
|
+
fix: 'Implement proper resolution and rejection handlers',
|
|
136
122
|
},
|
|
137
123
|
{
|
|
138
124
|
pattern: /window\.|document\.|navigator\./,
|
|
139
|
-
severity:
|
|
140
|
-
category:
|
|
141
|
-
message:
|
|
125
|
+
severity: 'low',
|
|
126
|
+
category: 'Environment Check',
|
|
127
|
+
message: 'Browser global access — may fail in SSR/Node environments',
|
|
142
128
|
fix: 'Guard with: typeof window !== "undefined" before accessing browser globals',
|
|
143
129
|
},
|
|
144
130
|
];
|
|
145
131
|
|
|
146
132
|
// ── ANSI colors (centralized via _colors.js) ─────────────────────────────
|
|
147
|
-
const { GREEN, YELLOW, RED, CYAN, BOLD, DIM, RESET } = require(
|
|
133
|
+
const { GREEN, YELLOW, RED, CYAN, BOLD, DIM, RESET } = require('./_colors');
|
|
148
134
|
|
|
149
135
|
// ── Core scanning ─────────────────────────────────────────────────────────
|
|
150
136
|
|
|
@@ -156,20 +142,16 @@ const { GREEN, YELLOW, RED, CYAN, BOLD, DIM, RESET } = require("./_colors");
|
|
|
156
142
|
* @param {string} [lang] - Language hint ('js' | 'ts' | 'py' | 'jsx' | 'tsx')
|
|
157
143
|
* @returns {Array<{severity, category, line, message, fix, source}>}
|
|
158
144
|
*/
|
|
159
|
-
function scanCode(code, _lang =
|
|
145
|
+
function scanCode(code, _lang = 'js') {
|
|
160
146
|
const findings = [];
|
|
161
|
-
const lines = code.split(
|
|
147
|
+
const lines = code.split('\n');
|
|
162
148
|
|
|
163
149
|
for (let i = 0; i < lines.length; i++) {
|
|
164
150
|
const stripped = lines[i].trim();
|
|
165
151
|
const lineNum = i + 1;
|
|
166
152
|
|
|
167
153
|
// Skip pure comments
|
|
168
|
-
if (
|
|
169
|
-
stripped.startsWith("//") ||
|
|
170
|
-
stripped.startsWith("#") ||
|
|
171
|
-
stripped.startsWith("*")
|
|
172
|
-
) {
|
|
154
|
+
if (stripped.startsWith('//') || stripped.startsWith('#') || stripped.startsWith('*')) {
|
|
173
155
|
continue;
|
|
174
156
|
}
|
|
175
157
|
|
|
@@ -182,7 +164,7 @@ function scanCode(code, _lang = "js") {
|
|
|
182
164
|
line: lineNum,
|
|
183
165
|
message,
|
|
184
166
|
fix: buildSecurityFix(category),
|
|
185
|
-
source:
|
|
167
|
+
source: 'security_scan',
|
|
186
168
|
});
|
|
187
169
|
}
|
|
188
170
|
}
|
|
@@ -196,7 +178,7 @@ function scanCode(code, _lang = "js") {
|
|
|
196
178
|
line: lineNum,
|
|
197
179
|
message: h.message,
|
|
198
180
|
fix: h.fix,
|
|
199
|
-
source:
|
|
181
|
+
source: 'heuristic',
|
|
200
182
|
});
|
|
201
183
|
}
|
|
202
184
|
}
|
|
@@ -212,26 +194,18 @@ function scanCode(code, _lang = "js") {
|
|
|
212
194
|
*/
|
|
213
195
|
function buildSecurityFix(category) {
|
|
214
196
|
const fixes = {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"
|
|
224
|
-
|
|
225
|
-
"Weak Randomness":
|
|
226
|
-
"Use crypto.randomBytes(n) or crypto.randomUUID() for security-sensitive values.",
|
|
227
|
-
"Auth Bypass":
|
|
228
|
-
'Enforce JWT algorithm explicitly: { algorithms: ["HS256"] }',
|
|
229
|
-
"Info Disclosure":
|
|
230
|
-
"Remove logging of sensitive values. Use structured logging with redaction.",
|
|
197
|
+
'Hardcoded Secret': 'Move to environment variable: process.env.SECRET_NAME',
|
|
198
|
+
'SQL Injection': 'Use parameterized queries. Never interpolate user input into SQL.',
|
|
199
|
+
XSS: 'Use textContent instead of innerHTML. Sanitize with DOMPurify if HTML is needed.',
|
|
200
|
+
'Code Injection': 'Remove eval()/new Function(). Use a safe alternative or a JSON parser.',
|
|
201
|
+
'Command Injection': 'Use execFile() with an args array instead of exec() with a shell string.',
|
|
202
|
+
'Weak Crypto': 'Use crypto.createHash("sha256") or bcrypt for password hashing.',
|
|
203
|
+
'Weak Randomness':
|
|
204
|
+
'Use crypto.randomBytes(n) or crypto.randomUUID() for security-sensitive values.',
|
|
205
|
+
'Auth Bypass': 'Enforce JWT algorithm explicitly: { algorithms: ["HS256"] }',
|
|
206
|
+
'Info Disclosure': 'Remove logging of sensitive values. Use structured logging with redaction.',
|
|
231
207
|
};
|
|
232
|
-
return
|
|
233
|
-
fixes[category] || "Review and remediate according to OWASP guidelines."
|
|
234
|
-
);
|
|
208
|
+
return fixes[category] || 'Review and remediate according to OWASP guidelines.';
|
|
235
209
|
}
|
|
236
210
|
|
|
237
211
|
/**
|
|
@@ -243,15 +217,15 @@ function buildSecurityFix(category) {
|
|
|
243
217
|
*/
|
|
244
218
|
function computeVerdict(findings) {
|
|
245
219
|
// Filter out VERIFY flags from blocking logic — they are informational
|
|
246
|
-
const blocking = findings.filter(
|
|
220
|
+
const blocking = findings.filter(f => f.category !== 'Verification Flag');
|
|
247
221
|
const maxSeverityRank = blocking.reduce((min, f) => {
|
|
248
222
|
const rank = SEVERITY_RANK[f.severity] ?? 3;
|
|
249
223
|
return rank < min ? rank : min;
|
|
250
224
|
}, 4); // 4 = no findings
|
|
251
225
|
|
|
252
|
-
if (maxSeverityRank <= 1) return { verdict:
|
|
253
|
-
if (maxSeverityRank === 2) return { verdict:
|
|
254
|
-
return { verdict:
|
|
226
|
+
if (maxSeverityRank <= 1) return { verdict: 'REJECTED', passed: false }; // critical or high
|
|
227
|
+
if (maxSeverityRank === 2) return { verdict: 'WARNING', passed: true }; // medium
|
|
228
|
+
return { verdict: 'APPROVED', passed: true };
|
|
255
229
|
}
|
|
256
230
|
|
|
257
231
|
/**
|
|
@@ -262,7 +236,7 @@ function computeVerdict(findings) {
|
|
|
262
236
|
* @returns {string|null}
|
|
263
237
|
*/
|
|
264
238
|
function buildSelfHealingInstructions(findings) {
|
|
265
|
-
const blocking = findings.filter(
|
|
239
|
+
const blocking = findings.filter(f => {
|
|
266
240
|
const rank = SEVERITY_RANK[f.severity] ?? 3;
|
|
267
241
|
return rank <= 1; // critical + high only
|
|
268
242
|
});
|
|
@@ -270,20 +244,18 @@ function buildSelfHealingInstructions(findings) {
|
|
|
270
244
|
if (!blocking.length) return null;
|
|
271
245
|
|
|
272
246
|
const lines = [
|
|
273
|
-
|
|
247
|
+
'⚠️ Inner-Loop Validator found blocking issues. Auto-correct the following before writing to disk:\n',
|
|
274
248
|
];
|
|
275
249
|
|
|
276
250
|
for (const f of blocking) {
|
|
277
251
|
lines.push(`[${f.severity.toUpperCase()}] Line ${f.line} — ${f.category}`);
|
|
278
252
|
lines.push(` Issue: ${f.message}`);
|
|
279
253
|
lines.push(` Fix: ${f.fix}`);
|
|
280
|
-
lines.push(
|
|
254
|
+
lines.push('');
|
|
281
255
|
}
|
|
282
256
|
|
|
283
|
-
lines.push(
|
|
284
|
-
|
|
285
|
-
);
|
|
286
|
-
return lines.join("\n");
|
|
257
|
+
lines.push('Re-generate the affected lines only. Do not change unaffected code.');
|
|
258
|
+
return lines.join('\n');
|
|
287
259
|
}
|
|
288
260
|
|
|
289
261
|
// ── Output ────────────────────────────────────────────────────────────────
|
|
@@ -291,26 +263,20 @@ function buildSelfHealingInstructions(findings) {
|
|
|
291
263
|
function printHumanReport(result) {
|
|
292
264
|
const { verdict, issues, summary, self_healing_instructions } = result;
|
|
293
265
|
|
|
294
|
-
const verdictColor =
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
console.error(
|
|
300
|
-
`\n${BOLD}${CYAN}━━━ Inner-Loop Validator ━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`,
|
|
301
|
-
);
|
|
302
|
-
console.error(
|
|
303
|
-
` Verdict: ${verdictColor}${BOLD}${verdictIcon} ${verdict}${RESET}`,
|
|
304
|
-
);
|
|
266
|
+
const verdictColor = verdict === 'APPROVED' ? GREEN : verdict === 'WARNING' ? YELLOW : RED;
|
|
267
|
+
const verdictIcon = verdict === 'APPROVED' ? '✅' : verdict === 'WARNING' ? '⚠️' : '❌';
|
|
268
|
+
|
|
269
|
+
console.error(`\n${BOLD}${CYAN}━━━ Inner-Loop Validator ━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`);
|
|
270
|
+
console.error(` Verdict: ${verdictColor}${BOLD}${verdictIcon} ${verdict}${RESET}`);
|
|
305
271
|
console.error(` Summary: ${summary}`);
|
|
306
272
|
|
|
307
273
|
if (issues.length) {
|
|
308
274
|
console.error(`\n ${BOLD}Issues found:${RESET}`);
|
|
309
275
|
for (const iss of issues) {
|
|
310
276
|
const color =
|
|
311
|
-
iss.severity ===
|
|
277
|
+
iss.severity === 'critical' || iss.severity === 'high'
|
|
312
278
|
? RED
|
|
313
|
-
: iss.severity ===
|
|
279
|
+
: iss.severity === 'medium'
|
|
314
280
|
? YELLOW
|
|
315
281
|
: DIM;
|
|
316
282
|
console.error(
|
|
@@ -322,28 +288,22 @@ function printHumanReport(result) {
|
|
|
322
288
|
}
|
|
323
289
|
|
|
324
290
|
if (self_healing_instructions) {
|
|
325
|
-
console.error(
|
|
326
|
-
`\n ${YELLOW}${BOLD}Self-Healing Instructions (for Maker Agent):${RESET}`,
|
|
327
|
-
);
|
|
291
|
+
console.error(`\n ${YELLOW}${BOLD}Self-Healing Instructions (for Maker Agent):${RESET}`);
|
|
328
292
|
console.error(
|
|
329
293
|
self_healing_instructions
|
|
330
|
-
.split(
|
|
331
|
-
.map(
|
|
332
|
-
.join(
|
|
294
|
+
.split('\n')
|
|
295
|
+
.map(l => ` ${l}`)
|
|
296
|
+
.join('\n'),
|
|
333
297
|
);
|
|
334
298
|
}
|
|
335
299
|
|
|
336
|
-
console.error(
|
|
337
|
-
`${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}\n`,
|
|
338
|
-
);
|
|
300
|
+
console.error(`${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}\n`);
|
|
339
301
|
}
|
|
340
302
|
|
|
341
303
|
// ── Built-in test case ────────────────────────────────────────────────────
|
|
342
304
|
|
|
343
305
|
function runTestCase() {
|
|
344
|
-
console.error(
|
|
345
|
-
`\n${BOLD}${CYAN}━━━ Inner-Loop Validator — Self-Test ━━━━━━━━━━━━━━${RESET}`,
|
|
346
|
-
);
|
|
306
|
+
console.error(`\n${BOLD}${CYAN}━━━ Inner-Loop Validator — Self-Test ━━━━━━━━━━━━━━${RESET}`);
|
|
347
307
|
|
|
348
308
|
const badCode = `
|
|
349
309
|
const password = "supersecret123";
|
|
@@ -353,21 +313,17 @@ const token = eval(req.body.expr);
|
|
|
353
313
|
const rand = Math.random() * 1000;
|
|
354
314
|
`;
|
|
355
315
|
|
|
356
|
-
const result = validate(badCode,
|
|
316
|
+
const result = validate(badCode, 'js');
|
|
357
317
|
printHumanReport(result);
|
|
358
318
|
|
|
359
|
-
const hasCritical = result.issues.some(
|
|
360
|
-
|
|
361
|
-
);
|
|
362
|
-
if (hasCritical && result.verdict === "REJECTED") {
|
|
319
|
+
const hasCritical = result.issues.some(i => i.severity === 'critical' || i.severity === 'high');
|
|
320
|
+
if (hasCritical && result.verdict === 'REJECTED') {
|
|
363
321
|
console.error(
|
|
364
322
|
`${GREEN}✅ Self-test PASSED — validator correctly identified and blocked critical issues${RESET}\n`,
|
|
365
323
|
);
|
|
366
324
|
process.exit(0);
|
|
367
325
|
} else {
|
|
368
|
-
console.error(
|
|
369
|
-
`${RED}❌ Self-test FAILED — expected REJECTED verdict for bad code${RESET}\n`,
|
|
370
|
-
);
|
|
326
|
+
console.error(`${RED}❌ Self-test FAILED — expected REJECTED verdict for bad code${RESET}\n`);
|
|
371
327
|
process.exit(1);
|
|
372
328
|
}
|
|
373
329
|
}
|
|
@@ -383,13 +339,13 @@ const rand = Math.random() * 1000;
|
|
|
383
339
|
* @param {object} [opts] - Options: { timeout: number }
|
|
384
340
|
* @returns {{ verdict, passed, issues, summary, self_healing_instructions }}
|
|
385
341
|
*/
|
|
386
|
-
function validate(code, lang =
|
|
387
|
-
if (!code || typeof code !==
|
|
342
|
+
function validate(code, lang = 'js', _opts = {}) {
|
|
343
|
+
if (!code || typeof code !== 'string') {
|
|
388
344
|
return {
|
|
389
|
-
verdict:
|
|
345
|
+
verdict: 'APPROVED',
|
|
390
346
|
passed: true,
|
|
391
347
|
issues: [],
|
|
392
|
-
summary:
|
|
348
|
+
summary: 'No code provided — skipped.',
|
|
393
349
|
self_healing_instructions: null,
|
|
394
350
|
};
|
|
395
351
|
}
|
|
@@ -397,34 +353,28 @@ function validate(code, lang = "js", _opts = {}) {
|
|
|
397
353
|
const issues = scanCode(code, lang);
|
|
398
354
|
|
|
399
355
|
// Sort by severity rank
|
|
400
|
-
issues.sort(
|
|
401
|
-
(a, b) =>
|
|
402
|
-
(SEVERITY_RANK[a.severity] ?? 3) - (SEVERITY_RANK[b.severity] ?? 3),
|
|
403
|
-
);
|
|
356
|
+
issues.sort((a, b) => (SEVERITY_RANK[a.severity] ?? 3) - (SEVERITY_RANK[b.severity] ?? 3));
|
|
404
357
|
|
|
405
358
|
const { verdict, passed } = computeVerdict(issues);
|
|
406
359
|
const healingInstructions = buildSelfHealingInstructions(issues);
|
|
407
360
|
|
|
408
|
-
const critCount = issues.filter(
|
|
409
|
-
const highCount = issues.filter(
|
|
410
|
-
const medCount = issues.filter(
|
|
411
|
-
const lowCount = issues.filter(
|
|
412
|
-
const verifyCount = issues.filter(
|
|
413
|
-
(i) => i.category === "Verification Flag",
|
|
414
|
-
).length;
|
|
361
|
+
const critCount = issues.filter(i => i.severity === 'critical').length;
|
|
362
|
+
const highCount = issues.filter(i => i.severity === 'high').length;
|
|
363
|
+
const medCount = issues.filter(i => i.severity === 'medium').length;
|
|
364
|
+
const lowCount = issues.filter(i => i.severity === 'low').length;
|
|
365
|
+
const verifyCount = issues.filter(i => i.category === 'Verification Flag').length;
|
|
415
366
|
|
|
416
367
|
let summary = `${issues.length} issue(s) found`;
|
|
417
368
|
if (!issues.length) {
|
|
418
|
-
summary =
|
|
369
|
+
summary = 'No issues detected — code is clean';
|
|
419
370
|
} else {
|
|
420
371
|
const parts = [];
|
|
421
372
|
if (critCount) parts.push(`${critCount} critical`);
|
|
422
373
|
if (highCount) parts.push(`${highCount} high`);
|
|
423
374
|
if (medCount) parts.push(`${medCount} medium`);
|
|
424
375
|
if (lowCount) parts.push(`${lowCount} low`);
|
|
425
|
-
if (verifyCount)
|
|
426
|
-
|
|
427
|
-
summary = parts.join(", ");
|
|
376
|
+
if (verifyCount) parts.push(`${verifyCount} VERIFY flag(s) need human review`);
|
|
377
|
+
summary = parts.join(', ');
|
|
428
378
|
}
|
|
429
379
|
|
|
430
380
|
return {
|
|
@@ -434,7 +384,7 @@ function validate(code, lang = "js", _opts = {}) {
|
|
|
434
384
|
summary,
|
|
435
385
|
self_healing_instructions: healingInstructions,
|
|
436
386
|
meta: {
|
|
437
|
-
lines_scanned: code.split(
|
|
387
|
+
lines_scanned: code.split('\n').length,
|
|
438
388
|
lang,
|
|
439
389
|
timestamp: new Date().toISOString(),
|
|
440
390
|
},
|
|
@@ -443,6 +393,7 @@ function validate(code, lang = "js", _opts = {}) {
|
|
|
443
393
|
|
|
444
394
|
module.exports = {
|
|
445
395
|
validate,
|
|
396
|
+
validateSnippet: validate,
|
|
446
397
|
scanCode,
|
|
447
398
|
computeVerdict,
|
|
448
399
|
buildSelfHealingInstructions,
|
|
@@ -453,7 +404,7 @@ module.exports = {
|
|
|
453
404
|
if (require.main === module) {
|
|
454
405
|
const argv = process.argv.slice(2);
|
|
455
406
|
|
|
456
|
-
if (!argv.length || argv.includes(
|
|
407
|
+
if (!argv.length || argv.includes('--help') || argv.includes('-h')) {
|
|
457
408
|
console.log(`
|
|
458
409
|
${BOLD}inner_loop_validator.js${RESET} — Tribunal Self-Healing CI
|
|
459
410
|
|
|
@@ -475,19 +426,19 @@ ${BOLD}Verdict:${RESET}
|
|
|
475
426
|
}
|
|
476
427
|
|
|
477
428
|
// Built-in self-test
|
|
478
|
-
if (argv[0] ===
|
|
429
|
+
if (argv[0] === 'test-case') {
|
|
479
430
|
runTestCase();
|
|
480
431
|
process.exit(0);
|
|
481
432
|
}
|
|
482
433
|
|
|
483
|
-
const jsonOnly = argv.includes(
|
|
484
|
-
const fileFlagIdx = argv.indexOf(
|
|
485
|
-
const snippetIdx = argv.indexOf(
|
|
486
|
-
const langIdx = argv.indexOf(
|
|
434
|
+
const jsonOnly = argv.includes('--json-only');
|
|
435
|
+
const fileFlagIdx = argv.indexOf('--file');
|
|
436
|
+
const snippetIdx = argv.indexOf('--snippet');
|
|
437
|
+
const langIdx = argv.indexOf('--lang');
|
|
487
438
|
|
|
488
|
-
const lang = langIdx !== -1 && argv[langIdx + 1] ? argv[langIdx + 1] :
|
|
439
|
+
const lang = langIdx !== -1 && argv[langIdx + 1] ? argv[langIdx + 1] : 'js';
|
|
489
440
|
|
|
490
|
-
let code =
|
|
441
|
+
let code = '';
|
|
491
442
|
|
|
492
443
|
if (fileFlagIdx !== -1 && argv[fileFlagIdx + 1]) {
|
|
493
444
|
const filePath = path.resolve(argv[fileFlagIdx + 1]);
|
|
@@ -495,16 +446,14 @@ ${BOLD}Verdict:${RESET}
|
|
|
495
446
|
console.error(`${RED}✖ File not found: ${filePath}${RESET}`);
|
|
496
447
|
process.exit(1);
|
|
497
448
|
}
|
|
498
|
-
code = fs.readFileSync(filePath,
|
|
449
|
+
code = fs.readFileSync(filePath, 'utf8');
|
|
499
450
|
} else if (snippetIdx !== -1 && argv[snippetIdx + 1]) {
|
|
500
451
|
code = argv[snippetIdx + 1];
|
|
501
452
|
} else if (!process.stdin.isTTY) {
|
|
502
453
|
// Read from stdin if piped (cross-platform, works on Windows)
|
|
503
|
-
code = fs.readFileSync(0,
|
|
454
|
+
code = fs.readFileSync(0, 'utf8');
|
|
504
455
|
} else {
|
|
505
|
-
console.error(
|
|
506
|
-
`${RED}✖ Provide --snippet "<code>" or --file <path>${RESET}`,
|
|
507
|
-
);
|
|
456
|
+
console.error(`${RED}✖ Provide --snippet "<code>" or --file <path>${RESET}`);
|
|
508
457
|
process.exit(1);
|
|
509
458
|
}
|
|
510
459
|
|