tribunal-kit 6.0.1 ā 8.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/ARCHITECTURE.md +9 -6
- 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/config/claude.json +18 -0
- package/.agent/config/plugin.json +102 -0
- package/.agent/config/slash-commands.json +103 -0
- package/.agent/config/specialist-registry.json +415 -0
- package/.agent/config/system-prompt.md +191 -0
- package/.agent/history/architecture-graph.yaml +302 -3
- package/.agent/history/graph-cache.json +515 -45
- package/.agent/history/memory/.memory.idx +1532 -1
- package/.agent/history/memory/MEMORY.md +102 -1
- package/.agent/history/memory.db +0 -0
- package/.agent/history/snapshots/bin__adapter-install.js.json +13 -0
- package/.agent/history/snapshots/bin__global-store.js.json +15 -0
- package/.agent/history/snapshots/bin__mcp-server.js.json +19 -0
- package/.agent/history/snapshots/bin__proxy-server.js.json +20 -0
- package/.agent/history/snapshots/bin__spawn-agent.js.json +12 -0
- package/.agent/history/snapshots/bin__tk-proxy.js.json +21 -0
- package/.agent/history/snapshots/bin__tribunal-kit.js.json +9 -7
- package/.agent/history/snapshots/bin__wrapper.js.json +14 -0
- package/.agent/history/snapshots/eslint.config.js.json +1 -2
- package/.agent/history/snapshots/scripts__benchmark.js.json +14 -0
- package/.agent/history/snapshots/scripts__changelog.js.json +1 -2
- package/.agent/history/snapshots/scripts__fix-vbc.js.json +11 -0
- package/.agent/history/snapshots/scripts__stress_benchmark.js.json +15 -0
- package/.agent/history/snapshots/scripts__sync-version.js.json +1 -2
- package/.agent/history/snapshots/scripts__validate-payload.js.json +1 -2
- package/.agent/history/snapshots/scripts__visual_audit.js.json +11 -0
- package/.agent/history/snapshots/test__integration__bridges.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__graceful_degradation.test.js.json +12 -0
- package/.agent/history/snapshots/test__integration__init.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__minimal_change_pipeline.test.js.json +13 -0
- package/.agent/history/snapshots/test__integration__parallel_tribunal.test.js.json +12 -0
- package/.agent/history/snapshots/test__integration__routing.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__swarm_dispatcher.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__sync_status.test.js.json +13 -0
- package/.agent/history/snapshots/test__integration__wave2.test.js.json +1 -2
- package/.agent/history/snapshots/test__integration__wrapper.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__align.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__args.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__audit_release.test.js.json +16 -0
- package/.agent/history/snapshots/test__unit__case_law_manager.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__cicd_validator.test.js.json +12 -0
- package/.agent/history/snapshots/test__unit__compile.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__context_broker.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__contract_engine.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__copyDir.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__graph_tools.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__guardrail_engine.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__impact_classifier.test.js.json +12 -0
- package/.agent/history/snapshots/test__unit__init.test.js.json +14 -0
- package/.agent/history/snapshots/test__unit__inner_loop_validator.test.js.json +1 -2
- package/.agent/history/snapshots/test__unit__integrity_manifest.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__learn.test.js.json +11 -0
- package/.agent/history/snapshots/test__unit__marathon.test.js.json +22 -0
- package/.agent/history/snapshots/test__unit__mcp_server.test.js.json +16 -0
- package/.agent/history/snapshots/test__unit__memory.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__minimal_change.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__native.test.js.json +10 -0
- package/.agent/history/snapshots/test__unit__optimize.test.js.json +13 -0
- package/.agent/history/snapshots/test__unit__path_resolution.test.js.json +14 -0
- package/.agent/history/snapshots/test__unit__production_readiness_evidence.test.js.json +21 -0
- package/.agent/history/snapshots/test__unit__selfInstall.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__semver.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__skill_evolution.test.js.json +11 -0
- package/.agent/history/snapshots/test__unit__stress.test.js.json +15 -0
- package/.agent/history/snapshots/test__unit__swarm_dispatcher.test.js.json +3 -3
- package/.agent/history/snapshots/test__unit__utils.test.js.json +10 -0
- package/.agent/mcp_config.json +1 -6
- package/.agent/routing_index.json +2033 -263
- package/.agent/rules/GEMINI.md +11 -9
- 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/ast_context_loader.js +137 -0
- 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/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/memory_engine.js +581 -0
- 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/payload_schemas.js +146 -0
- package/.agent/scripts/pipeline_engine.js +320 -209
- package/.agent/scripts/prompt_compiler.js +166 -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 +397 -200
- package/.agent/scripts/test_runner.js +54 -56
- package/.agent/scripts/token_budget_broker.js +126 -13
- 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 +22 -3
- 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 +6 -2
- package/.agent/skills/ai-app-hardening/SKILL.md +9 -8
- 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 +5 -4
- 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 +7 -3
- package/.agent/skills/edge-ai-mobile/SKILL.md +5 -1
- 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 +2 -1
- 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 +2 -1
- 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 +1 -0
- package/.agent/skills/playwright-ai-e2e/SKILL.md +3 -2
- 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 +10 -12
- 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 +3 -2
- 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 +11 -6
- 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 +2 -1
- 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/.claude/CLAUDE.md +442 -0
- package/CONTRIBUTING.md +3 -3
- package/README.md +105 -45
- package/SECURITY.md +11 -11
- package/bin/adapter-install.js +240 -0
- package/bin/global-store.js +48 -0
- package/bin/mcp-server.js +781 -332
- package/bin/proxy-server.js +113 -0
- package/bin/spawn-agent.js +39 -0
- package/bin/tk-proxy.js +34 -0
- package/bin/tribunal-kit.js +29 -30
- package/bin/wrapper.js +40 -46
- package/dist/cli.js +6 -0
- package/dist/commands/case.js +2 -0
- package/dist/commands/contract.js +440 -0
- package/dist/commands/init.js +8 -51
- package/dist/commands/status.js +61 -30
- package/dist/commands/validate.js +22 -31
- package/dist/index.d.ts +8 -1
- package/dist/tui/banner.js +77 -0
- package/dist/tui/index.js +21 -0
- package/dist/tui/reviewer-grid.js +90 -0
- package/dist/tui/shimmer.js +91 -0
- package/dist/tui/theme.js +130 -0
- package/dist/tui/tree.js +93 -0
- package/dist/tui/wizard.js +148 -0
- package/dist/utils/helpers.js +5 -41
- package/package.json +33 -15
- package/scripts/benchmark.js +62 -86
- package/scripts/build-graph.js +71 -0
- 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
- package/.agent/history/snapshots/migrate_refs.js.json +0 -11
- package/.agent/scripts/compile_router.py +0 -112
- package/.agent/scripts/migrate_skills_frontmatter.py +0 -64
|
@@ -29,42 +29,41 @@
|
|
|
29
29
|
* node .agent/scripts/minimal_change_engine.js search --query "fetchRetry"
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
'use strict';
|
|
33
33
|
|
|
34
|
-
const fs = require(
|
|
35
|
-
const path = require(
|
|
34
|
+
const fs = require('fs');
|
|
35
|
+
const path = require('path');
|
|
36
36
|
|
|
37
37
|
// āā Shared Utilities & Colors āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
38
|
-
const {
|
|
39
|
-
const { findAgentDir, loadJson, walkDir, DEFAULT_SKIP_DIRS } = require("./_utils");
|
|
38
|
+
const { loadJson, DEFAULT_SKIP_DIRS } = require('./_utils');
|
|
40
39
|
|
|
41
40
|
// āā Decision Order Hierarchy āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
42
41
|
const DECISION_HIERARCHY = [
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
'NO_CHANGE',
|
|
43
|
+
'REUSE',
|
|
44
|
+
'CONFIGURE',
|
|
45
|
+
'DELETE',
|
|
46
|
+
'MODIFY',
|
|
47
|
+
'EXTEND',
|
|
48
|
+
'CREATE',
|
|
50
49
|
];
|
|
51
50
|
|
|
52
51
|
// āā 14 Standardized Complexity Flag Types āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
53
52
|
const COMPLEXITY_FLAG_TYPES = [
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
53
|
+
'UNNECESSARY_ABSTRACTION',
|
|
54
|
+
'DUPLICATE_FUNCTIONALITY',
|
|
55
|
+
'DEPENDENCY_BLOAT',
|
|
56
|
+
'FILE_PROLIFERATION',
|
|
57
|
+
'PREMATURE_GENERALIZATION',
|
|
58
|
+
'SCOPE_EXPANSION',
|
|
59
|
+
'UNNECESSARY_REWRITE',
|
|
60
|
+
'FRAMEWORK_REINVENTION',
|
|
61
|
+
'STANDARD_LIBRARY_REINVENTION',
|
|
62
|
+
'EXCESSIVE_BOILERPLATE',
|
|
63
|
+
'SPECULATIVE_FEATURE',
|
|
64
|
+
'UNJUSTIFIED_INFRASTRUCTURE',
|
|
65
|
+
'UNNECESSARY_CONFIGURATION',
|
|
66
|
+
'DEAD_CODE_INTRODUCTION',
|
|
68
67
|
];
|
|
69
68
|
|
|
70
69
|
// āā Strictness Configurations āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
@@ -133,10 +132,10 @@ function calculateMinimalityScore(budget, classification, flags = []) {
|
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
// Penalties for complexity flags based on severity
|
|
136
|
-
flags.forEach(
|
|
137
|
-
if (flag.severity ===
|
|
135
|
+
flags.forEach(flag => {
|
|
136
|
+
if (flag.severity === 'high' || flag.severity === 'critical') {
|
|
138
137
|
score -= 15;
|
|
139
|
-
} else if (flag.severity ===
|
|
138
|
+
} else if (flag.severity === 'medium') {
|
|
140
139
|
score -= 8;
|
|
141
140
|
} else {
|
|
142
141
|
score -= 4;
|
|
@@ -163,55 +162,55 @@ function calculateMinimalityScore(budget, classification, flags = []) {
|
|
|
163
162
|
/**
|
|
164
163
|
* Detects potential complexity flags within a proposed change or spec.
|
|
165
164
|
*/
|
|
166
|
-
function detectComplexityFlags(proposal = {},
|
|
165
|
+
function detectComplexityFlags(proposal = {}, _existingSymbols = [], mode = 'balanced') {
|
|
167
166
|
const flags = [];
|
|
168
167
|
const limits = STRICTNESS_CONFIGS[mode] || STRICTNESS_CONFIGS.balanced;
|
|
169
168
|
|
|
170
169
|
// Check 1: Dependency Bloat
|
|
171
170
|
if (proposal.dependencies_added > limits.max_deps_warn) {
|
|
172
171
|
flags.push({
|
|
173
|
-
type:
|
|
174
|
-
severity: proposal.dependencies_added > 1 ?
|
|
172
|
+
type: 'DEPENDENCY_BLOAT',
|
|
173
|
+
severity: proposal.dependencies_added > 1 ? 'high' : 'medium',
|
|
175
174
|
evidence: `${proposal.dependencies_added} new dependency/dependencies proposed.`,
|
|
176
|
-
location: proposal.target_file ||
|
|
177
|
-
reason:
|
|
178
|
-
recommended_action:
|
|
175
|
+
location: proposal.target_file || 'package.json',
|
|
176
|
+
reason: 'Adding dependencies increases security attack surface and maintenance overhead.',
|
|
177
|
+
recommended_action: 'Use standard library or existing codebase utilities.',
|
|
179
178
|
});
|
|
180
179
|
}
|
|
181
180
|
|
|
182
181
|
// Check 2: File Proliferation
|
|
183
182
|
if (proposal.files_added > limits.max_files_added_warn) {
|
|
184
183
|
flags.push({
|
|
185
|
-
type:
|
|
186
|
-
severity: proposal.files_added > 3 ?
|
|
184
|
+
type: 'FILE_PROLIFERATION',
|
|
185
|
+
severity: proposal.files_added > 3 ? 'high' : 'medium',
|
|
187
186
|
evidence: `${proposal.files_added} new files proposed for creation.`,
|
|
188
|
-
location: proposal.target_file ||
|
|
189
|
-
reason:
|
|
190
|
-
recommended_action:
|
|
187
|
+
location: proposal.target_file || 'workspace',
|
|
188
|
+
reason: 'Creating multiple new files increases architectural noise and fragmentation.',
|
|
189
|
+
recommended_action: 'Modify or extend existing files instead of creating new ones.',
|
|
191
190
|
});
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
// Check 3: Unnecessary Abstraction
|
|
195
194
|
if (proposal.new_abstractions > limits.max_abstractions_warn) {
|
|
196
195
|
flags.push({
|
|
197
|
-
type:
|
|
198
|
-
severity:
|
|
196
|
+
type: 'UNNECESSARY_ABSTRACTION',
|
|
197
|
+
severity: 'medium',
|
|
199
198
|
evidence: `${proposal.new_abstractions} new abstraction layer(s) proposed.`,
|
|
200
|
-
location: proposal.target_file ||
|
|
201
|
-
reason:
|
|
202
|
-
recommended_action:
|
|
199
|
+
location: proposal.target_file || 'codebase',
|
|
200
|
+
reason: 'Adding wrappers or single-consumer interfaces increases complexity without benefit.',
|
|
201
|
+
recommended_action: 'Implement concrete logic directly without extra abstraction.',
|
|
203
202
|
});
|
|
204
203
|
}
|
|
205
204
|
|
|
206
205
|
// Check 4: Duplicate Functionality
|
|
207
206
|
if (proposal.duplicate_candidates && proposal.duplicate_candidates.length > 0) {
|
|
208
|
-
proposal.duplicate_candidates.forEach(
|
|
207
|
+
proposal.duplicate_candidates.forEach(cand => {
|
|
209
208
|
flags.push({
|
|
210
|
-
type:
|
|
211
|
-
severity:
|
|
209
|
+
type: 'DUPLICATE_FUNCTIONALITY',
|
|
210
|
+
severity: 'high',
|
|
212
211
|
evidence: `Existing equivalent symbol '${cand.name}' found in ${cand.file}`,
|
|
213
212
|
location: cand.file,
|
|
214
|
-
reason:
|
|
213
|
+
reason: 'Duplicate functionality leads to fragmented state and maintenance confusion.',
|
|
215
214
|
recommended_action: `Reuse '${cand.name}' from ${cand.file}`,
|
|
216
215
|
});
|
|
217
216
|
});
|
|
@@ -220,11 +219,11 @@ function detectComplexityFlags(proposal = {}, existingSymbols = [], mode = "bala
|
|
|
220
219
|
// Check 5: Framework/Stdlib Reinvention
|
|
221
220
|
if (proposal.reinventing_stdlib) {
|
|
222
221
|
flags.push({
|
|
223
|
-
type:
|
|
224
|
-
severity:
|
|
222
|
+
type: 'STANDARD_LIBRARY_REINVENTION',
|
|
223
|
+
severity: 'medium',
|
|
225
224
|
evidence: `Proposed custom utility '${proposal.reinventing_stdlib.name}'`,
|
|
226
|
-
location: proposal.target_file ||
|
|
227
|
-
reason:
|
|
225
|
+
location: proposal.target_file || 'utils',
|
|
226
|
+
reason: 'Language standard library already provides built-in methods for this.',
|
|
228
227
|
recommended_action: `Use native JS/TS methods (e.g., Array.prototype, URL, crypto).`,
|
|
229
228
|
});
|
|
230
229
|
}
|
|
@@ -238,26 +237,26 @@ function detectComplexityFlags(proposal = {}, existingSymbols = [], mode = "bala
|
|
|
238
237
|
function searchRepositoryForCapability(query, searchDir) {
|
|
239
238
|
const matches = [];
|
|
240
239
|
|
|
241
|
-
if (!query || typeof query !==
|
|
240
|
+
if (!query || typeof query !== 'string') return matches;
|
|
242
241
|
|
|
243
242
|
let agentDir = null;
|
|
244
243
|
let current = path.resolve(searchDir || process.cwd());
|
|
245
244
|
const rootPath = path.parse(current).root;
|
|
246
245
|
while (current !== rootPath) {
|
|
247
|
-
const candidate = path.join(current,
|
|
246
|
+
const candidate = path.join(current, '.agent');
|
|
248
247
|
if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
|
|
249
248
|
agentDir = candidate;
|
|
250
249
|
break;
|
|
251
250
|
}
|
|
252
251
|
current = path.dirname(current);
|
|
253
252
|
}
|
|
254
|
-
const repoRoot = agentDir ? path.dirname(agentDir) :
|
|
253
|
+
const repoRoot = agentDir ? path.dirname(agentDir) : searchDir || process.cwd();
|
|
255
254
|
|
|
256
255
|
const normalizedQuery = query.toLowerCase();
|
|
257
|
-
const searchKeywords = normalizedQuery.split(/\s+/).filter(
|
|
256
|
+
const searchKeywords = normalizedQuery.split(/\s+/).filter(k => k.length > 2);
|
|
258
257
|
|
|
259
258
|
// Search package.json dependencies
|
|
260
|
-
const pkgPath = path.join(repoRoot,
|
|
259
|
+
const pkgPath = path.join(repoRoot, 'package.json');
|
|
261
260
|
if (fs.existsSync(pkgPath)) {
|
|
262
261
|
const pkg = loadJson(pkgPath);
|
|
263
262
|
if (pkg) {
|
|
@@ -265,12 +264,12 @@ function searchRepositoryForCapability(query, searchDir) {
|
|
|
265
264
|
...pkg.dependencies,
|
|
266
265
|
...pkg.devDependencies,
|
|
267
266
|
};
|
|
268
|
-
Object.keys(allDeps).forEach(
|
|
267
|
+
Object.keys(allDeps).forEach(dep => {
|
|
269
268
|
if (dep.toLowerCase().includes(normalizedQuery)) {
|
|
270
269
|
matches.push({
|
|
271
|
-
type:
|
|
270
|
+
type: 'dependency',
|
|
272
271
|
name: dep,
|
|
273
|
-
file:
|
|
272
|
+
file: 'package.json',
|
|
274
273
|
snippet: `Version: ${allDeps[dep]}`,
|
|
275
274
|
});
|
|
276
275
|
}
|
|
@@ -286,28 +285,31 @@ function searchRepositoryForCapability(query, searchDir) {
|
|
|
286
285
|
for (const entry of entries) {
|
|
287
286
|
const fullPath = path.join(dir, entry.name);
|
|
288
287
|
if (entry.isDirectory()) {
|
|
289
|
-
if (DEFAULT_SKIP_DIRS.has(entry.name) || entry.name ===
|
|
288
|
+
if (DEFAULT_SKIP_DIRS.has(entry.name) || entry.name === 'target') {
|
|
290
289
|
continue;
|
|
291
290
|
}
|
|
292
291
|
scan(fullPath);
|
|
293
292
|
} else if (entry.isFile() && /\.(js|ts|tsx|jsx|json|md)$/.test(entry.name)) {
|
|
294
293
|
try {
|
|
295
|
-
const content = fs.readFileSync(fullPath,
|
|
294
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
296
295
|
const lower = content.toLowerCase();
|
|
297
296
|
|
|
298
|
-
const hasMatch = searchKeywords.some(
|
|
297
|
+
const hasMatch = searchKeywords.some(kw => lower.includes(kw));
|
|
299
298
|
if (hasMatch) {
|
|
300
299
|
const relPath = path.relative(repoRoot, fullPath);
|
|
301
300
|
// Extract function/class exports
|
|
302
|
-
const symbolRegex =
|
|
301
|
+
const symbolRegex =
|
|
302
|
+
/(?:export\s+(?:function|class|const|let|var|type|interface)|module\.exports\s*=)\s+([A-Za-z0-9_]+)/g;
|
|
303
303
|
let m;
|
|
304
304
|
while ((m = symbolRegex.exec(content)) !== null) {
|
|
305
305
|
if (m[1].toLowerCase().includes(normalizedQuery)) {
|
|
306
306
|
matches.push({
|
|
307
|
-
type:
|
|
307
|
+
type: 'symbol',
|
|
308
308
|
name: m[1],
|
|
309
309
|
file: relPath,
|
|
310
|
-
snippet: content
|
|
310
|
+
snippet: content
|
|
311
|
+
.substring(Math.max(0, m.index - 40), m.index + 80)
|
|
312
|
+
.replace(/\n/g, ' '),
|
|
311
313
|
});
|
|
312
314
|
}
|
|
313
315
|
}
|
|
@@ -334,37 +336,37 @@ function classifyProposal(taskDescription, proposal = {}, repoMatches = []) {
|
|
|
334
336
|
const estimatedLinesAdded = proposal.estimated_lines_added || 0;
|
|
335
337
|
|
|
336
338
|
if (repoMatches.length > 0 && filesAdded === 0) {
|
|
337
|
-
return
|
|
339
|
+
return 'REUSE';
|
|
338
340
|
}
|
|
339
341
|
|
|
340
342
|
if (filesAdded === 0 && filesModified === 0 && filesDeleted === 0) {
|
|
341
|
-
return
|
|
343
|
+
return 'NO_CHANGE';
|
|
342
344
|
}
|
|
343
345
|
|
|
344
346
|
if (proposal.is_config_only) {
|
|
345
|
-
return
|
|
347
|
+
return 'CONFIGURE';
|
|
346
348
|
}
|
|
347
349
|
|
|
348
350
|
if (filesDeleted > 0 && filesAdded === 0 && estimatedLinesAdded === 0) {
|
|
349
|
-
return
|
|
351
|
+
return 'DELETE';
|
|
350
352
|
}
|
|
351
353
|
|
|
352
354
|
if (filesAdded === 0 && filesModified <= 2 && newAbstractions === 0) {
|
|
353
|
-
return
|
|
355
|
+
return 'MODIFY';
|
|
354
356
|
}
|
|
355
357
|
|
|
356
358
|
if (filesAdded <= 2 && newAbstractions <= 1) {
|
|
357
|
-
return
|
|
359
|
+
return 'EXTEND';
|
|
358
360
|
}
|
|
359
361
|
|
|
360
|
-
return
|
|
362
|
+
return 'CREATE';
|
|
361
363
|
}
|
|
362
364
|
|
|
363
365
|
/**
|
|
364
366
|
* Evaluates an implementation proposal completely.
|
|
365
367
|
*/
|
|
366
368
|
function evaluateMinimalChange(taskDescription, proposal = {}, options = {}) {
|
|
367
|
-
const mode = options.mode ||
|
|
369
|
+
const mode = options.mode || 'balanced';
|
|
368
370
|
const searchDir = options.cwd || process.cwd();
|
|
369
371
|
|
|
370
372
|
const budget = calculateChangeBudget(proposal);
|
|
@@ -379,18 +381,20 @@ function evaluateMinimalChange(taskDescription, proposal = {}, options = {}) {
|
|
|
379
381
|
const score = calculateMinimalityScore(budget, classification, flags);
|
|
380
382
|
|
|
381
383
|
const reuseOpportunities = repoMatches.map(
|
|
382
|
-
|
|
384
|
+
m => `Reuse existing ${m.type} '${m.name}' in ${m.file}`,
|
|
383
385
|
);
|
|
384
386
|
|
|
385
387
|
const recommendedReductions = [];
|
|
386
388
|
if (budget.dependencies_added > 0) {
|
|
387
|
-
recommendedReductions.push(
|
|
389
|
+
recommendedReductions.push(
|
|
390
|
+
'Avoid introducing new npm dependencies; leverage existing utilities.',
|
|
391
|
+
);
|
|
388
392
|
}
|
|
389
393
|
if (budget.files_added > 1) {
|
|
390
|
-
recommendedReductions.push(
|
|
394
|
+
recommendedReductions.push('Combine proposed new files into existing module structure.');
|
|
391
395
|
}
|
|
392
396
|
if (budget.new_abstractions > 0) {
|
|
393
|
-
recommendedReductions.push(
|
|
397
|
+
recommendedReductions.push('Remove single-use interface/class abstractions.');
|
|
394
398
|
}
|
|
395
399
|
|
|
396
400
|
return {
|
|
@@ -399,7 +403,7 @@ function evaluateMinimalChange(taskDescription, proposal = {}, options = {}) {
|
|
|
399
403
|
change_budget: budget,
|
|
400
404
|
complexity_flags: flags,
|
|
401
405
|
reuse_opportunities: reuseOpportunities,
|
|
402
|
-
unnecessary_changes: flags.map(
|
|
406
|
+
unnecessary_changes: flags.map(f => f.evidence),
|
|
403
407
|
recommended_reductions: recommendedReductions,
|
|
404
408
|
decision_order: DECISION_HIERARCHY,
|
|
405
409
|
passed: score >= (STRICTNESS_CONFIGS[mode]?.min_score_pass || 75),
|
|
@@ -409,14 +413,18 @@ function evaluateMinimalChange(taskDescription, proposal = {}, options = {}) {
|
|
|
409
413
|
// āā CLI Main Entry Point āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
410
414
|
if (require.main === module) {
|
|
411
415
|
const args = process.argv.slice(2);
|
|
412
|
-
const command = args[0] ||
|
|
413
|
-
const taskArg = args.find(
|
|
414
|
-
const modeArg = args.find(
|
|
415
|
-
|
|
416
|
-
if (command ===
|
|
417
|
-
const result = evaluateMinimalChange(
|
|
416
|
+
const command = args[0] || 'evaluate';
|
|
417
|
+
const taskArg = args.find(a => a.startsWith('--task='))?.split('=')[1] || 'Default Task';
|
|
418
|
+
const modeArg = args.find(a => a.startsWith('--mode='))?.split('=')[1] || 'balanced';
|
|
419
|
+
|
|
420
|
+
if (command === 'evaluate' || command === 'audit') {
|
|
421
|
+
const result = evaluateMinimalChange(
|
|
422
|
+
taskArg,
|
|
423
|
+
{ files_modified: 1, estimated_lines_added: 12 },
|
|
424
|
+
{ mode: modeArg },
|
|
425
|
+
);
|
|
418
426
|
console.log(JSON.stringify(result, null, 2));
|
|
419
|
-
} else if (command ===
|
|
427
|
+
} else if (command === 'search') {
|
|
420
428
|
const matches = searchRepositoryForCapability(taskArg);
|
|
421
429
|
console.log(JSON.stringify(matches, null, 2));
|
|
422
430
|
} else {
|
|
@@ -8,24 +8,24 @@
|
|
|
8
8
|
* line number reporting, configurable --max-mutants.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const fs = require(
|
|
12
|
-
const path = require(
|
|
13
|
-
const { spawnSync } = require(
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const { spawnSync } = require('child_process');
|
|
14
14
|
|
|
15
15
|
// āā Mutation Definitions āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
16
16
|
const MUTATIONS = [
|
|
17
|
-
{ name:
|
|
18
|
-
{ name:
|
|
19
|
-
{ name:
|
|
20
|
-
{ name:
|
|
21
|
-
{ name:
|
|
22
|
-
{ name:
|
|
23
|
-
{ name:
|
|
24
|
-
{ name:
|
|
17
|
+
{ name: 'Strict Equality', pattern: /===/g, replacement: '!==' },
|
|
18
|
+
{ name: 'Strict Inequality', pattern: /!==/g, replacement: '===' },
|
|
19
|
+
{ name: 'Logical AND', pattern: /&&/g, replacement: '||' },
|
|
20
|
+
{ name: 'Logical OR', pattern: /\|\|/g, replacement: '&&' },
|
|
21
|
+
{ name: 'True -> False', pattern: /\btrue\b/g, replacement: 'false' },
|
|
22
|
+
{ name: 'False -> True', pattern: /\bfalse\b/g, replacement: 'true' },
|
|
23
|
+
{ name: 'Greater Than', pattern: /(?<!=)>(?!=)/g, replacement: '<' },
|
|
24
|
+
{ name: 'Less Than', pattern: /(?<!=)<(?!=)/g, replacement: '>' },
|
|
25
25
|
{
|
|
26
|
-
name:
|
|
26
|
+
name: 'Return Early Removal',
|
|
27
27
|
pattern: /\breturn\b/g,
|
|
28
|
-
replacement:
|
|
28
|
+
replacement: '/* return */',
|
|
29
29
|
},
|
|
30
30
|
];
|
|
31
31
|
|
|
@@ -34,17 +34,17 @@ const MUTATIONS = [
|
|
|
34
34
|
function buildCodeMask(source) {
|
|
35
35
|
const mask = new Array(source.length).fill(true);
|
|
36
36
|
let inString = false;
|
|
37
|
-
let stringChar =
|
|
37
|
+
let stringChar = '';
|
|
38
38
|
let inBlockComment = false;
|
|
39
39
|
let inLineComment = false;
|
|
40
40
|
|
|
41
41
|
for (let i = 0; i < source.length; i++) {
|
|
42
42
|
const ch = source[i];
|
|
43
|
-
const next = source[i + 1] ||
|
|
43
|
+
const next = source[i + 1] || '';
|
|
44
44
|
|
|
45
45
|
if (inBlockComment) {
|
|
46
46
|
mask[i] = false;
|
|
47
|
-
if (ch ===
|
|
47
|
+
if (ch === '*' && next === '/') {
|
|
48
48
|
mask[i + 1] = false;
|
|
49
49
|
inBlockComment = false;
|
|
50
50
|
i++;
|
|
@@ -54,7 +54,7 @@ function buildCodeMask(source) {
|
|
|
54
54
|
|
|
55
55
|
if (inLineComment) {
|
|
56
56
|
mask[i] = false;
|
|
57
|
-
if (ch ===
|
|
57
|
+
if (ch === '\n') {
|
|
58
58
|
inLineComment = false;
|
|
59
59
|
}
|
|
60
60
|
continue;
|
|
@@ -62,7 +62,7 @@ function buildCodeMask(source) {
|
|
|
62
62
|
|
|
63
63
|
if (inString) {
|
|
64
64
|
mask[i] = false;
|
|
65
|
-
if (ch ===
|
|
65
|
+
if (ch === '\\') {
|
|
66
66
|
i++;
|
|
67
67
|
if (i < source.length) mask[i] = false;
|
|
68
68
|
continue;
|
|
@@ -74,7 +74,7 @@ function buildCodeMask(source) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
// Entering block comment
|
|
77
|
-
if (ch ===
|
|
77
|
+
if (ch === '/' && next === '*') {
|
|
78
78
|
mask[i] = false;
|
|
79
79
|
mask[i + 1] = false;
|
|
80
80
|
inBlockComment = true;
|
|
@@ -83,7 +83,7 @@ function buildCodeMask(source) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// Entering line comment
|
|
86
|
-
if (ch ===
|
|
86
|
+
if (ch === '/' && next === '/') {
|
|
87
87
|
mask[i] = false;
|
|
88
88
|
mask[i + 1] = false;
|
|
89
89
|
inLineComment = true;
|
|
@@ -92,7 +92,7 @@ function buildCodeMask(source) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
// Entering string
|
|
95
|
-
if (ch === '"' || ch === "'" || ch ===
|
|
95
|
+
if (ch === '"' || ch === "'" || ch === '`') {
|
|
96
96
|
mask[i] = false;
|
|
97
97
|
inString = true;
|
|
98
98
|
stringChar = ch;
|
|
@@ -110,7 +110,7 @@ function buildCodeMask(source) {
|
|
|
110
110
|
function getLineNumber(source, charIndex) {
|
|
111
111
|
let line = 1;
|
|
112
112
|
for (let i = 0; i < charIndex && i < source.length; i++) {
|
|
113
|
-
if (source[i] ===
|
|
113
|
+
if (source[i] === '\n') line++;
|
|
114
114
|
}
|
|
115
115
|
return line;
|
|
116
116
|
}
|
|
@@ -123,7 +123,7 @@ let backupPath = null;
|
|
|
123
123
|
function safeRestore() {
|
|
124
124
|
if (targetFile && originalContent) {
|
|
125
125
|
try {
|
|
126
|
-
fs.writeFileSync(targetFile, originalContent,
|
|
126
|
+
fs.writeFileSync(targetFile, originalContent, 'utf-8');
|
|
127
127
|
} catch {
|
|
128
128
|
// Last resort: tell user where the backup is
|
|
129
129
|
if (backupPath) {
|
|
@@ -141,29 +141,29 @@ function safeRestore() {
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
// š ABSOLUTE SAFETY NET
|
|
144
|
-
process.on(
|
|
144
|
+
process.on('SIGINT', () => {
|
|
145
145
|
safeRestore();
|
|
146
|
-
console.error(
|
|
146
|
+
console.error('\n[Tribunal] Mutation Engine aborted. Target file restored.');
|
|
147
147
|
process.exit(1);
|
|
148
148
|
});
|
|
149
149
|
|
|
150
|
-
process.on(
|
|
150
|
+
process.on('uncaughtException', err => {
|
|
151
151
|
safeRestore();
|
|
152
|
-
console.error(
|
|
152
|
+
console.error('\n[Tribunal] Critical error. File restored.', err);
|
|
153
153
|
process.exit(1);
|
|
154
154
|
});
|
|
155
155
|
|
|
156
|
-
process.on(
|
|
156
|
+
process.on('exit', safeRestore);
|
|
157
157
|
|
|
158
158
|
// āā CLI Argument Parsing āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
159
159
|
function parseCliArgs(argv) {
|
|
160
160
|
const args = argv.slice(2);
|
|
161
161
|
let maxMutants = 5; // default per mutation type
|
|
162
162
|
let fileToMutate = null;
|
|
163
|
-
|
|
163
|
+
const testCommandParts = [];
|
|
164
164
|
|
|
165
165
|
for (let i = 0; i < args.length; i++) {
|
|
166
|
-
if (args[i] ===
|
|
166
|
+
if (args[i] === '--max-mutants' && args[i + 1]) {
|
|
167
167
|
maxMutants = parseInt(args[i + 1], 10) || 5;
|
|
168
168
|
i++; // skip next
|
|
169
169
|
} else if (!fileToMutate) {
|
|
@@ -173,7 +173,7 @@ function parseCliArgs(argv) {
|
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
return { fileToMutate, testCommand: testCommandParts.join(
|
|
176
|
+
return { fileToMutate, testCommand: testCommandParts.join(' '), maxMutants };
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
// āā Main Engine āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
@@ -185,9 +185,9 @@ function runMutationTesting(fileToMutate, testCommand, maxMutantsPerType) {
|
|
|
185
185
|
process.exit(1);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
originalContent = fs.readFileSync(targetFile,
|
|
189
|
-
backupPath = targetFile +
|
|
190
|
-
fs.writeFileSync(backupPath, originalContent,
|
|
188
|
+
originalContent = fs.readFileSync(targetFile, 'utf-8');
|
|
189
|
+
backupPath = targetFile + '.bak';
|
|
190
|
+
fs.writeFileSync(backupPath, originalContent, 'utf-8');
|
|
191
191
|
|
|
192
192
|
console.log(`\nāāā Tribunal Mutation Engine v2.1 āāā`);
|
|
193
193
|
console.log(`Target: ${fileToMutate}`);
|
|
@@ -195,11 +195,9 @@ function runMutationTesting(fileToMutate, testCommand, maxMutantsPerType) {
|
|
|
195
195
|
console.log(`Max/type: ${maxMutantsPerType}`);
|
|
196
196
|
console.log(`\nExecuting baseline test run...`);
|
|
197
197
|
|
|
198
|
-
const baseline = spawnSync(testCommand, { shell: true, stdio:
|
|
198
|
+
const baseline = spawnSync(testCommand, { shell: true, stdio: 'pipe' });
|
|
199
199
|
if (baseline.status !== 0) {
|
|
200
|
-
console.error(
|
|
201
|
-
`ERROR: Baseline test failed! Fix your tests before mutating.`,
|
|
202
|
-
);
|
|
200
|
+
console.error(`ERROR: Baseline test failed! Fix your tests before mutating.`);
|
|
203
201
|
console.error(baseline.stderr.toString());
|
|
204
202
|
safeRestore();
|
|
205
203
|
process.exit(1);
|
|
@@ -220,10 +218,7 @@ function runMutationTesting(fileToMutate, testCommand, maxMutantsPerType) {
|
|
|
220
218
|
const matchIndices = [];
|
|
221
219
|
let m;
|
|
222
220
|
|
|
223
|
-
while (
|
|
224
|
-
(m = regex.exec(originalContent)) !== null &&
|
|
225
|
-
matchIndices.length < maxMutantsPerType
|
|
226
|
-
) {
|
|
221
|
+
while ((m = regex.exec(originalContent)) !== null && matchIndices.length < maxMutantsPerType) {
|
|
227
222
|
// Context-aware: skip matches that are inside strings or comments
|
|
228
223
|
const matchStart = m.index;
|
|
229
224
|
const matchEnd = m.index + m[0].length - 1;
|
|
@@ -250,12 +245,10 @@ function runMutationTesting(fileToMutate, testCommand, maxMutantsPerType) {
|
|
|
250
245
|
mutatedString +
|
|
251
246
|
originalContent.substring(index + length);
|
|
252
247
|
|
|
253
|
-
fs.writeFileSync(targetFile, mutatedContent,
|
|
248
|
+
fs.writeFileSync(targetFile, mutatedContent, 'utf-8');
|
|
254
249
|
|
|
255
|
-
process.stdout.write(
|
|
256
|
-
|
|
257
|
-
);
|
|
258
|
-
const run = spawnSync(testCommand, { shell: true, stdio: "pipe" });
|
|
250
|
+
process.stdout.write(` [Mutant #${totalMutants}] ${mutation.name} (L${lineNum}) ... `);
|
|
251
|
+
const run = spawnSync(testCommand, { shell: true, stdio: 'pipe' });
|
|
259
252
|
|
|
260
253
|
if (run.status !== 0) {
|
|
261
254
|
console.log(`ā
KILLED`);
|
|
@@ -272,12 +265,11 @@ function runMutationTesting(fileToMutate, testCommand, maxMutantsPerType) {
|
|
|
272
265
|
}
|
|
273
266
|
|
|
274
267
|
// Restore immediately after each mutant
|
|
275
|
-
fs.writeFileSync(targetFile, originalContent,
|
|
268
|
+
fs.writeFileSync(targetFile, originalContent, 'utf-8');
|
|
276
269
|
}
|
|
277
270
|
}
|
|
278
271
|
|
|
279
|
-
const score =
|
|
280
|
-
totalMutants > 0 ? Math.round((killedMutants / totalMutants) * 100) : 100;
|
|
272
|
+
const score = totalMutants > 0 ? Math.round((killedMutants / totalMutants) * 100) : 100;
|
|
281
273
|
|
|
282
274
|
console.log(`\nāāā Mutation Summary āāā`);
|
|
283
275
|
console.log(` Total Mutants: ${totalMutants}`);
|
|
@@ -288,14 +280,10 @@ function runMutationTesting(fileToMutate, testCommand, maxMutantsPerType) {
|
|
|
288
280
|
if (survivors.length > 0) {
|
|
289
281
|
console.log(`\nāāā Surviving Mutants (Weak Test Coverage) āāā`);
|
|
290
282
|
survivors.forEach((s, i) => {
|
|
291
|
-
console.log(
|
|
292
|
-
` ${i + 1}. Line ${s.line}: ${s.type} (${s.original} ā ${s.mutated})`,
|
|
293
|
-
);
|
|
283
|
+
console.log(` ${i + 1}. Line ${s.line}: ${s.type} (${s.original} ā ${s.mutated})`);
|
|
294
284
|
});
|
|
295
285
|
console.log(`\n ā These lines have no test that catches the mutation.`);
|
|
296
|
-
console.log(
|
|
297
|
-
` Add assertions that would FAIL if the operator were swapped.`,
|
|
298
|
-
);
|
|
286
|
+
console.log(` Add assertions that would FAIL if the operator were swapped.`);
|
|
299
287
|
}
|
|
300
288
|
|
|
301
289
|
process.exit(score < 80 ? 1 : 0);
|
|
@@ -305,13 +293,9 @@ function runMutationTesting(fileToMutate, testCommand, maxMutantsPerType) {
|
|
|
305
293
|
const { fileToMutate, testCommand, maxMutants } = parseCliArgs(process.argv);
|
|
306
294
|
|
|
307
295
|
if (!fileToMutate || !testCommand) {
|
|
308
|
-
console.log(
|
|
309
|
-
`Usage: node mutation_runner.js <target_file> [--max-mutants N] <test_command>`,
|
|
310
|
-
);
|
|
296
|
+
console.log(`Usage: node mutation_runner.js <target_file> [--max-mutants N] <test_command>`);
|
|
311
297
|
console.log(`\nExamples:`);
|
|
312
|
-
console.log(
|
|
313
|
-
` node mutation_runner.js src/math.js "npx jest src/math.test.js"`,
|
|
314
|
-
);
|
|
298
|
+
console.log(` node mutation_runner.js src/math.js "npx jest src/math.test.js"`);
|
|
315
299
|
console.log(
|
|
316
300
|
` node mutation_runner.js src/auth.js --max-mutants 10 "npx jest test/auth.test.js"`,
|
|
317
301
|
);
|