claudecode-omc 5.11.0 → 5.12.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/bundled/manifest.json +3 -3
- package/bundled/upstream/anthropic-skills/.omc-source/bundle.json +2 -2
- package/bundled/upstream/anthropic-skills/.omc-source/provenance.json +394 -390
- package/bundled/upstream/anthropic-skills/skills/claude-api/SKILL.md +60 -29
- package/bundled/upstream/anthropic-skills/skills/claude-api/csharp/claude-api.md +46 -1
- package/bundled/upstream/anthropic-skills/skills/claude-api/curl/examples.md +2 -2
- package/bundled/upstream/anthropic-skills/skills/claude-api/curl/managed-agents.md +3 -1
- package/bundled/upstream/anthropic-skills/skills/claude-api/go/claude-api.md +23 -4
- package/bundled/upstream/anthropic-skills/skills/claude-api/java/claude-api.md +32 -3
- package/bundled/upstream/anthropic-skills/skills/claude-api/php/claude-api.md +27 -0
- package/bundled/upstream/anthropic-skills/skills/claude-api/python/claude-api/README.md +123 -7
- package/bundled/upstream/anthropic-skills/skills/claude-api/python/claude-api/batches.md +13 -0
- package/bundled/upstream/anthropic-skills/skills/claude-api/python/claude-api/files-api.md +7 -2
- package/bundled/upstream/anthropic-skills/skills/claude-api/python/claude-api/streaming.md +18 -1
- package/bundled/upstream/anthropic-skills/skills/claude-api/python/managed-agents/README.md +9 -7
- package/bundled/upstream/anthropic-skills/skills/claude-api/ruby/claude-api.md +27 -0
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/agent-design.md +1 -1
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/anthropic-cli.md +246 -0
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/claude-platform-on-aws.md +59 -0
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/error-codes.md +24 -4
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/live-sources.md +8 -0
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-api-reference.md +48 -4
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-client-patterns.md +3 -1
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-core.md +15 -1
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-environments.md +10 -6
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-events.md +25 -0
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-onboarding.md +48 -18
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-overview.md +8 -5
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-scheduled-deployments.md +144 -0
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +2 -1
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/managed-agents-tools.md +46 -9
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/model-migration.md +259 -3
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/models.md +17 -9
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/prompt-caching.md +55 -3
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/token-counting.md +56 -0
- package/bundled/upstream/anthropic-skills/skills/claude-api/shared/tool-use-concepts.md +22 -2
- package/bundled/upstream/anthropic-skills/skills/claude-api/typescript/claude-api/README.md +45 -6
- package/bundled/upstream/anthropic-skills/skills/claude-api/typescript/claude-api/streaming.md +1 -1
- package/bundled/upstream/anthropic-skills/skills/claude-api/typescript/managed-agents/README.md +10 -12
- package/bundled/upstream/anthropic-skills/skills/frontend-design/SKILL.md +39 -26
- package/bundled/upstream/ecc/.omc-source/bundle.json +2 -2
- package/bundled/upstream/ecc/.omc-source/manifests/.claude-plugin/marketplace.json +2 -2
- package/bundled/upstream/ecc/.omc-source/provenance.json +602 -550
- package/bundled/upstream/ecc/agents/agent-evaluator.md +206 -0
- package/bundled/upstream/ecc/agents/performance-optimizer.md +9 -9
- package/bundled/upstream/ecc/agents/php-reviewer.md +109 -0
- package/bundled/upstream/ecc/agents/spec-miner.md +217 -0
- package/bundled/upstream/ecc/agents/vue-reviewer.md +206 -0
- package/bundled/upstream/ecc/commands/cost-report.md +58 -84
- package/bundled/upstream/ecc/commands/epic-claim.md +26 -0
- package/bundled/upstream/ecc/commands/epic-decompose.md +23 -0
- package/bundled/upstream/ecc/commands/epic-publish.md +23 -0
- package/bundled/upstream/ecc/commands/epic-review.md +23 -0
- package/bundled/upstream/ecc/commands/epic-sync.md +23 -0
- package/bundled/upstream/ecc/commands/epic-unblock.md +22 -0
- package/bundled/upstream/ecc/commands/epic-validate.md +22 -0
- package/bundled/upstream/ecc/commands/instinct-status.md +8 -8
- package/bundled/upstream/ecc/commands/multi-backend.md +2 -0
- package/bundled/upstream/ecc/commands/multi-execute.md +2 -0
- package/bundled/upstream/ecc/commands/multi-frontend.md +2 -0
- package/bundled/upstream/ecc/commands/multi-plan.md +2 -0
- package/bundled/upstream/ecc/commands/multi-workflow.md +2 -0
- package/bundled/upstream/ecc/commands/orch-add-feature.md +36 -0
- package/bundled/upstream/ecc/commands/orch-build-mvp.md +36 -0
- package/bundled/upstream/ecc/commands/orch-change-feature.md +38 -0
- package/bundled/upstream/ecc/commands/orch-fix-defect.md +38 -0
- package/bundled/upstream/ecc/commands/orch-refine-code.md +39 -0
- package/bundled/upstream/ecc/commands/quality-gate.md +34 -16
- package/bundled/upstream/ecc/commands/vue-review.md +174 -0
- package/bundled/upstream/ecc/skills/accessibility/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/agent-architecture-audit/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/agent-eval/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/agent-harness-construction/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/agent-introspection-debugging/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/agent-payment-x402/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/agent-self-evaluation/SKILL.md +182 -0
- package/bundled/upstream/ecc/skills/agent-self-evaluation/examples/high-score-example.md +87 -0
- package/bundled/upstream/ecc/skills/agent-self-evaluation/examples/low-score-example.md +86 -0
- package/bundled/upstream/ecc/skills/agent-self-evaluation/references/evaluation-criteria.md +71 -0
- package/bundled/upstream/ecc/skills/agent-self-evaluation/references/hook-integration.md +64 -0
- package/bundled/upstream/ecc/skills/agent-self-evaluation/scripts/evaluate.py +408 -0
- package/bundled/upstream/ecc/skills/agent-self-evaluation/templates/evaluation-report.md +86 -0
- package/bundled/upstream/ecc/skills/agent-sort/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/agentic-engineering/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/agentic-os/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ai-first-engineering/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ai-regression-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/android-clean-architecture/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/angular-developer/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/api-connector-builder/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/api-design/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/architecture-decision-records/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/article-writing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/automation-audit-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/autonomous-agent-harness/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/autonomous-loops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/backend-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/benchmark/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/benchmark-methodology/SKILL.md +190 -0
- package/bundled/upstream/ecc/skills/benchmark-optimization-loop/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/blender-motion-state-inspection/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/blueprint/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/brand-discovery/SKILL.md +145 -0
- package/bundled/upstream/ecc/skills/brand-discovery/references/10_purpose-why.md +40 -0
- package/bundled/upstream/ecc/skills/brand-discovery/references/20_positioning.md +44 -0
- package/bundled/upstream/ecc/skills/brand-discovery/references/30_audience-niche.md +52 -0
- package/bundled/upstream/ecc/skills/brand-discovery/references/40_personality-archetype.md +57 -0
- package/bundled/upstream/ecc/skills/brand-discovery/references/50_voice-tone.md +59 -0
- package/bundled/upstream/ecc/skills/brand-discovery/references/60_narrative-story.md +50 -0
- package/bundled/upstream/ecc/skills/brand-discovery/references/70_founder-tension.md +49 -0
- package/bundled/upstream/ecc/skills/brand-discovery/references/90_SYNTHESIS.md +133 -0
- package/bundled/upstream/ecc/skills/brand-voice/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/browser-qa/SKILL.md +22 -4
- package/bundled/upstream/ecc/skills/bun-runtime/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/canary-watch/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/carrier-relationship-management/SKILL.md +1 -1
- package/bundled/upstream/ecc/skills/cisco-ios-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ck/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/claude-devfleet/SKILL.md +11 -2
- package/bundled/upstream/ecc/skills/click-path-audit/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/clickhouse-io/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/code-tour/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/codebase-onboarding/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/codehealth-mcp/SKILL.md +167 -0
- package/bundled/upstream/ecc/skills/coding-standards/SKILL.md +4 -2
- package/bundled/upstream/ecc/skills/competitive-platform-analysis/SKILL.md +214 -0
- package/bundled/upstream/ecc/skills/competitive-report-structure/SKILL.md +162 -0
- package/bundled/upstream/ecc/skills/compose-multiplatform-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/config-gc/SKILL.md +120 -0
- package/bundled/upstream/ecc/skills/configure-ecc/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/connections-optimizer/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/content-engine/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/content-hash-cache-pattern/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/context-budget/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/continuous-agent-loop/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/continuous-learning/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/continuous-learning-v2/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/continuous-learning-v2/agents/observer-loop.sh +14 -1
- package/bundled/upstream/ecc/skills/continuous-learning-v2/hooks/observe.sh +31 -7
- package/bundled/upstream/ecc/skills/continuous-learning-v2/scripts/instinct-cli.py +90 -2
- package/bundled/upstream/ecc/skills/continuous-learning-v2/scripts/test_parse_instinct.py +27 -0
- package/bundled/upstream/ecc/skills/cost-aware-llm-pipeline/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/cost-tracking/SKILL.md +58 -108
- package/bundled/upstream/ecc/skills/council/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/cpp-coding-standards/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/cpp-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/crosspost/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/csharp-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/customer-billing-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/customs-trade-compliance/SKILL.md +1 -1
- package/bundled/upstream/ecc/skills/dart-flutter-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/dashboard-builder/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/data-scraper-agent/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/data-throughput-accelerator/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/database-migrations/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/deep-research/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/defi-amm-security/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/deployment-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/design-system/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/django-celery/SKILL.md +3 -2
- package/bundled/upstream/ecc/skills/django-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/django-security/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/django-tdd/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/django-verification/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/dmux-workflows/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/docker-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/documentation-lookup/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/dotnet-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/dynamic-workflow-mode/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/e2e-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ecc-guide/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ecc-tools-cost-audit/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/email-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/energy-procurement/SKILL.md +1 -1
- package/bundled/upstream/ecc/skills/enterprise-agent-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/error-handling/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/eval-harness/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/evm-token-decimals/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/exa-search/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/fal-ai-media/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/fastapi-patterns/SKILL.md +375 -188
- package/bundled/upstream/ecc/skills/finance-billing-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/flox-environments/SKILL.md +3 -2
- package/bundled/upstream/ecc/skills/flutter-dart-code-review/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/frontend-a11y/SKILL.md +3 -3
- package/bundled/upstream/ecc/skills/frontend-design-direction/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/frontend-patterns/SKILL.md +23 -8
- package/bundled/upstream/ecc/skills/frontend-slides/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/frontend-slides/scripts/export-pdf.sh +1 -1
- package/bundled/upstream/ecc/skills/fsharp-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/gan-style-harness/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/gateguard/SKILL.md +9 -1
- package/bundled/upstream/ecc/skills/generating-python-installer/SKILL.md +820 -0
- package/bundled/upstream/ecc/skills/git-workflow/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/github-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/golang-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/golang-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/google-workspace-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/healthcare-cdss-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/healthcare-emr-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/healthcare-eval-harness/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/healthcare-phi-compliance/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/hermes-imports/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/hexagonal-architecture/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/hipaa-compliance/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/homelab-network-readiness/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/homelab-network-setup/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/homelab-pihole-dns/SKILL.md +10 -9
- package/bundled/upstream/ecc/skills/homelab-vlan-segmentation/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/homelab-wireguard-vpn/SKILL.md +4 -3
- package/bundled/upstream/ecc/skills/inherit-legacy-style/SKILL.md +157 -0
- package/bundled/upstream/ecc/skills/intent-driven-development/SKILL.md +360 -0
- package/bundled/upstream/ecc/skills/inventory-demand-planning/SKILL.md +1 -1
- package/bundled/upstream/ecc/skills/investor-materials/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/investor-outreach/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ios-icon-gen/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/iterative-retrieval/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ito-basket-compare/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ito-data-atlas-agent/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ito-market-intelligence/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ito-trade-planner/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/java-coding-standards/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/jira-integration/SKILL.md +17 -7
- package/bundled/upstream/ecc/skills/jpa-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/knowledge-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/kotlin-coroutines-flows/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/kotlin-exposed-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/kotlin-ktor-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/kotlin-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/kotlin-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/kubernetes-patterns/SKILL.md +756 -0
- package/bundled/upstream/ecc/skills/laravel-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/laravel-plugin-discovery/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/laravel-security/SKILL.md +826 -163
- package/bundled/upstream/ecc/skills/laravel-tdd/SKILL.md +541 -149
- package/bundled/upstream/ecc/skills/laravel-verification/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/latency-critical-systems/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/lead-intelligence/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/llm-trading-agent-security/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/logistics-exception-management/SKILL.md +1 -1
- package/bundled/upstream/ecc/skills/make-interfaces-feel-better/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/manim-video/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/market-research/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/marketing-campaign/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/mcp-server-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/messages-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ml-adoption-playbook/SKILL.md +57 -0
- package/bundled/upstream/ecc/skills/mle-workflow/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/motion-patterns/SKILL.md +1 -2
- package/bundled/upstream/ecc/skills/motion-ui/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/mysql-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/nanoclaw-repl/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/nestjs-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/netmiko-ssh-automation/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/network-bgp-diagnostics/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/network-config-validation/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/network-interface-health/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/nextjs-turbopack/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/nodejs-keccak256/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/nutrient-document-processing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/nuxt4-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/openclaw-persona-forge/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/opensource-pipeline/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/orch-add-feature/SKILL.md +45 -0
- package/bundled/upstream/ecc/skills/orch-build-mvp/SKILL.md +49 -0
- package/bundled/upstream/ecc/skills/orch-change-feature/SKILL.md +43 -0
- package/bundled/upstream/ecc/skills/orch-fix-defect/SKILL.md +43 -0
- package/bundled/upstream/ecc/skills/orch-pipeline/SKILL.md +121 -0
- package/bundled/upstream/ecc/skills/orch-refine-code/SKILL.md +44 -0
- package/bundled/upstream/ecc/skills/parallel-execution-optimizer/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/perl-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/perl-security/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/perl-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/plan-orchestrate/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/plankton-code-quality/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/postgres-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/prediction-market-oracle-research/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/prediction-market-risk-review/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/prisma-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/product-capability/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/product-lens/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/production-audit/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/production-scheduling/SKILL.md +1 -1
- package/bundled/upstream/ecc/skills/project-flow-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/prompt-optimizer/SKILL.md +1 -1
- package/bundled/upstream/ecc/skills/python-patterns/SKILL.md +4 -3
- package/bundled/upstream/ecc/skills/python-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/pytorch-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/quality-nonconformance/SKILL.md +1 -1
- package/bundled/upstream/ecc/skills/quarkus-patterns/SKILL.md +51 -50
- package/bundled/upstream/ecc/skills/quarkus-security/SKILL.md +25 -24
- package/bundled/upstream/ecc/skills/quarkus-tdd/SKILL.md +73 -72
- package/bundled/upstream/ecc/skills/quarkus-verification/SKILL.md +8 -7
- package/bundled/upstream/ecc/skills/ralphinho-rfc-pipeline/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/react-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/react-performance/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/react-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/recsys-pipeline-architect/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/recursive-decision-ledger/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/redis-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/regex-vs-llm-structured-text/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/repo-scan/SKILL.md +64 -63
- package/bundled/upstream/ecc/skills/research-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/returns-reverse-logistics/SKILL.md +1 -1
- package/bundled/upstream/ecc/skills/rules-distill/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/rust-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/rust-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/safety-guard/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/santa-method/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/scientific-db-pubmed-database/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/scientific-db-uspto-database/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/scientific-pkg-gget/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/scientific-thinking-literature-review/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/scientific-thinking-scholar-evaluation/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/search-first/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/security-bounty-hunter/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/security-review/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/security-scan/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/seo/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/skill-comply/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/skill-comply/scripts/runner.py +8 -0
- package/bundled/upstream/ecc/skills/skill-scout/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/skill-stocktake/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/social-graph-ranker/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/social-publisher/SKILL.md +17 -2
- package/bundled/upstream/ecc/skills/springboot-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/springboot-security/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/springboot-tdd/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/springboot-verification/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/strategic-compact/SKILL.md +10 -5
- package/bundled/upstream/ecc/skills/swift-actor-persistence/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/swift-protocol-di-testing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/taste/SKILL.md +264 -0
- package/bundled/upstream/ecc/skills/taste/references/genre-taxonomy.md +87 -0
- package/bundled/upstream/ecc/skills/tdd-workflow/SKILL.md +64 -1
- package/bundled/upstream/ecc/skills/team-agent-orchestration/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/team-builder/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/terminal-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/tinystruct-patterns/SKILL.md +77 -1
- package/bundled/upstream/ecc/skills/token-budget-advisor/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ui-demo/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/ui-to-vue/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/uncloud/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/unified-notifications-ops/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/verification-loop/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/video-editing/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/videodb/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/vite-patterns/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/vue-patterns/SKILL.md +471 -0
- package/bundled/upstream/ecc/skills/windows-desktop-e2e/SKILL.md +9 -8
- package/bundled/upstream/ecc/skills/workspace-surface-audit/SKILL.md +2 -1
- package/bundled/upstream/ecc/skills/x-api/SKILL.md +2 -1
- package/bundled/upstream/impeccable/.omc-source/bundle.json +2 -2
- package/bundled/upstream/impeccable/.omc-source/provenance.json +30 -25
- package/bundled/upstream/impeccable/skills/impeccable/SKILL.md +2 -2
- package/bundled/upstream/impeccable/skills/impeccable/reference/hooks.md +10 -8
- package/bundled/upstream/impeccable/skills/impeccable/reference/live.md +1 -1
- package/bundled/upstream/impeccable/skills/impeccable/scripts/context.mjs +707 -26
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/browser/injected/index.mjs +202 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/cli/main.mjs +57 -11
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/design-system.mjs +750 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +231 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/detect-antipatterns.mjs +7 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +29 -4
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +20 -4
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +2 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +27 -1
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/registry/antipatterns.mjs +29 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/shared/inline-ignores.mjs +148 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/hook-admin.mjs +135 -48
- package/bundled/upstream/impeccable/skills/impeccable/scripts/hook-before-edit.mjs +5 -2
- package/bundled/upstream/impeccable/skills/impeccable/scripts/hook-lib.mjs +375 -29
- package/bundled/upstream/impeccable/skills/impeccable/scripts/lib/design-parser.mjs +8 -1
- package/bundled/upstream/impeccable/skills/impeccable/scripts/lib/impeccable-config.mjs +638 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/lib/impeccable-paths.mjs +37 -35
- package/bundled/upstream/impeccable/skills/impeccable/scripts/lib/target-args.mjs +42 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/live-browser.js +159 -72
- package/bundled/upstream/impeccable/skills/impeccable/scripts/live-poll.mjs +16 -11
- package/bundled/upstream/impeccable/skills/impeccable/scripts/live-server.mjs +9 -8
- package/bundled/upstream/impeccable/skills/impeccable/scripts/live-target.mjs +30 -0
- package/bundled/upstream/impeccable/skills/impeccable/scripts/live-wrap.mjs +1 -1
- package/bundled/upstream/impeccable/skills/impeccable/scripts/live.mjs +72 -21
- package/bundled/upstream/oh-my-claudecode/.omc-source/bundle.json +2 -2
- package/bundled/upstream/oh-my-claudecode/.omc-source/provenance.json +103 -103
- package/bundled/upstream/oh-my-claudecode/agents/analyst.md +6 -0
- package/bundled/upstream/oh-my-claudecode/agents/architect.md +6 -0
- package/bundled/upstream/oh-my-claudecode/agents/code-reviewer.md +6 -0
- package/bundled/upstream/oh-my-claudecode/agents/critic.md +6 -0
- package/bundled/upstream/oh-my-claudecode/agents/debugger.md +6 -0
- package/bundled/upstream/oh-my-claudecode/agents/security-reviewer.md +6 -0
- package/bundled/upstream/oh-my-claudecode/agents/tracer.md +6 -0
- package/bundled/upstream/oh-my-claudecode/agents/verifier.md +7 -0
- package/bundled/upstream/oh-my-claudecode/hooks/hooks.json +9 -2
- package/bundled/upstream/oh-my-claudecode/skills/ask/SKILL.md +15 -4
- package/bundled/upstream/oh-my-claudecode/skills/autopilot/SKILL.md +30 -1
- package/bundled/upstream/oh-my-claudecode/skills/cancel/SKILL.md +29 -35
- package/bundled/upstream/oh-my-claudecode/skills/ccg/SKILL.md +20 -9
- package/bundled/upstream/oh-my-claudecode/skills/configure-notifications/SKILL.md +2 -2
- package/bundled/upstream/oh-my-claudecode/skills/omc-reference/SKILL.md +6 -4
- package/bundled/upstream/oh-my-claudecode/skills/omc-setup/phases/02-configure.md +1 -1
- package/bundled/upstream/oh-my-claudecode/skills/omc-setup/phases/03-integrations.md +2 -1
- package/bundled/upstream/oh-my-claudecode/skills/omc-setup/phases/04-welcome.md +2 -2
- package/bundled/upstream/oh-my-claudecode/skills/omc-teams/SKILL.md +29 -18
- package/bundled/upstream/oh-my-claudecode/skills/team/SKILL.md +127 -165
- package/bundled/upstream/superpowers/.omc-source/bundle.json +2 -2
- package/bundled/upstream/superpowers/.omc-source/provenance.json +59 -52
- package/bundled/upstream/superpowers/hooks/hooks-codex.json +16 -0
- package/bundled/upstream/superpowers/hooks/session-start +4 -12
- package/bundled/upstream/superpowers/hooks/session-start-codex +26 -0
- package/bundled/upstream/superpowers/skills/brainstorming/SKILL.md +5 -10
- package/bundled/upstream/superpowers/skills/brainstorming/scripts/frame-template.html +25 -26
- package/bundled/upstream/superpowers/skills/brainstorming/scripts/helper.js +101 -22
- package/bundled/upstream/superpowers/skills/brainstorming/scripts/server.cjs +399 -30
- package/bundled/upstream/superpowers/skills/brainstorming/scripts/start-server.sh +70 -9
- package/bundled/upstream/superpowers/skills/brainstorming/scripts/stop-server.sh +66 -2
- package/bundled/upstream/superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +1 -1
- package/bundled/upstream/superpowers/skills/brainstorming/visual-companion.md +33 -22
- package/bundled/upstream/superpowers/skills/dispatching-parallel-agents/SKILL.md +9 -6
- package/bundled/upstream/superpowers/skills/executing-plans/SKILL.md +2 -2
- package/bundled/upstream/superpowers/skills/finishing-a-development-branch/SKILL.md +2 -12
- package/bundled/upstream/superpowers/skills/receiving-code-review/SKILL.md +2 -2
- package/bundled/upstream/superpowers/skills/requesting-code-review/SKILL.md +2 -2
- package/bundled/upstream/superpowers/skills/requesting-code-review/code-reviewer.md +15 -11
- package/bundled/upstream/superpowers/skills/subagent-driven-development/SKILL.md +206 -67
- package/bundled/upstream/superpowers/skills/subagent-driven-development/implementer-prompt.md +30 -4
- package/bundled/upstream/superpowers/skills/subagent-driven-development/scripts/review-package +44 -0
- package/bundled/upstream/superpowers/skills/subagent-driven-development/scripts/sdd-workspace +22 -0
- package/bundled/upstream/superpowers/skills/subagent-driven-development/scripts/task-brief +40 -0
- package/bundled/upstream/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +188 -0
- package/bundled/upstream/superpowers/skills/systematic-debugging/SKILL.md +1 -1
- package/bundled/upstream/superpowers/skills/test-driven-development/SKILL.md +1 -1
- package/bundled/upstream/superpowers/skills/using-git-worktrees/SKILL.md +9 -22
- package/bundled/upstream/superpowers/skills/using-superpowers/SKILL.md +19 -15
- package/bundled/upstream/superpowers/skills/using-superpowers/references/antigravity-tools.md +96 -0
- package/bundled/upstream/superpowers/skills/using-superpowers/references/claude-code-tools.md +50 -0
- package/bundled/upstream/superpowers/skills/using-superpowers/references/codex-tools.md +25 -12
- package/bundled/upstream/superpowers/skills/using-superpowers/references/copilot-tools.md +27 -20
- package/bundled/upstream/superpowers/skills/using-superpowers/references/gemini-tools.md +44 -32
- package/bundled/upstream/superpowers/skills/using-superpowers/references/pi-tools.md +28 -0
- package/bundled/upstream/superpowers/skills/writing-plans/SKILL.md +22 -0
- package/bundled/upstream/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +1 -1
- package/bundled/upstream/superpowers/skills/writing-skills/SKILL.md +52 -18
- package/bundled/upstream/superpowers/skills/writing-skills/anthropic-best-practices.md +88 -88
- package/bundled/upstream/superpowers/skills/writing-skills/persuasion-principles.md +3 -3
- package/package.json +1 -1
- package/bundled/upstream/superpowers/skills/subagent-driven-development/code-quality-reviewer-prompt.md +0 -25
- package/bundled/upstream/superpowers/skills/subagent-driven-development/spec-reviewer-prompt.md +0 -61
|
@@ -425,6 +425,35 @@ const ANTIPATTERNS = [
|
|
|
425
425
|
skillSection: 'Layout & Space',
|
|
426
426
|
skillGuideline: 'overflow container clipping positioned children',
|
|
427
427
|
},
|
|
428
|
+
{
|
|
429
|
+
id: 'design-system-font',
|
|
430
|
+
category: 'quality',
|
|
431
|
+
name: 'Font outside DESIGN.md',
|
|
432
|
+
description:
|
|
433
|
+
'A font is used that is not declared in DESIGN.md typography. Use the documented type system or update DESIGN.md if this is an intentional brand addition.',
|
|
434
|
+
skillSection: 'Typography',
|
|
435
|
+
skillGuideline: 'font family outside the project design system',
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
id: 'design-system-color',
|
|
439
|
+
category: 'quality',
|
|
440
|
+
severity: 'advisory',
|
|
441
|
+
name: 'Color outside DESIGN.md',
|
|
442
|
+
description:
|
|
443
|
+
'A literal color is outside the DESIGN.md palette and sidecar tonal ramps. This may be legitimate, but it should be an intentional design-system addition rather than drift.',
|
|
444
|
+
skillSection: 'Color & Contrast',
|
|
445
|
+
skillGuideline: 'literal color outside the project design system',
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
id: 'design-system-radius',
|
|
449
|
+
category: 'quality',
|
|
450
|
+
severity: 'advisory',
|
|
451
|
+
name: 'Radius outside DESIGN.md',
|
|
452
|
+
description:
|
|
453
|
+
'A border-radius value is outside the DESIGN.md rounded scale. Use a documented radius token or update the design system if the new shape is intentional.',
|
|
454
|
+
skillSection: 'Visual Details',
|
|
455
|
+
skillGuideline: 'border radius outside the project design system',
|
|
456
|
+
},
|
|
428
457
|
|
|
429
458
|
// ── Provider tells: opt-in via --gpt / --gemini (gated off by default) ──
|
|
430
459
|
{
|
|
@@ -4394,6 +4423,7 @@ if (IS_BROWSER) {
|
|
|
4394
4423
|
category: ap ? ap.category : 'quality',
|
|
4395
4424
|
severity: ap?.severity || 'warning',
|
|
4396
4425
|
detail: f.detail || f.snippet,
|
|
4426
|
+
ignoreValue: f.ignoreValue || f.value || '',
|
|
4397
4427
|
name: ap ? ap.name : (f.type || f.id),
|
|
4398
4428
|
description: ap ? ap.description : '',
|
|
4399
4429
|
};
|
|
@@ -4430,10 +4460,203 @@ if (IS_BROWSER) {
|
|
|
4430
4460
|
return [...groupMap.entries()].map(([el, findings]) => ({ el, findings }));
|
|
4431
4461
|
}
|
|
4432
4462
|
|
|
4463
|
+
const DESIGN_COLOR_TOLERANCE = 6;
|
|
4464
|
+
const DESIGN_RADIUS_TOLERANCE_PX = 0.5;
|
|
4465
|
+
const DESIGN_SKIP_TAGS = new Set(['head', 'title', 'meta', 'link', 'style', 'script', 'noscript', 'template', 'source']);
|
|
4466
|
+
|
|
4467
|
+
function normalizeBrowserFontName(value) {
|
|
4468
|
+
return String(value || '')
|
|
4469
|
+
.trim()
|
|
4470
|
+
.replace(/^["']|["']$/g, '')
|
|
4471
|
+
.replace(/\+/g, ' ')
|
|
4472
|
+
.replace(/\s+/g, ' ')
|
|
4473
|
+
.toLowerCase();
|
|
4474
|
+
}
|
|
4475
|
+
|
|
4476
|
+
function browserPrimaryFont(stack) {
|
|
4477
|
+
if (!stack || /var\(/i.test(stack)) return '';
|
|
4478
|
+
return String(stack || '')
|
|
4479
|
+
.split(',')
|
|
4480
|
+
.map(normalizeBrowserFontName)
|
|
4481
|
+
.find(font => font && !GENERIC_FONTS.has(font)) || '';
|
|
4482
|
+
}
|
|
4483
|
+
|
|
4484
|
+
function browserDesignSystemConfig() {
|
|
4485
|
+
const raw = window.__IMPECCABLE_CONFIG__?.designSystem;
|
|
4486
|
+
if (!raw?.present) return null;
|
|
4487
|
+
const allowedFonts = new Set((raw.allowedFonts || []).map(normalizeBrowserFontName).filter(Boolean));
|
|
4488
|
+
const allowedColors = (raw.allowedColors || [])
|
|
4489
|
+
.filter(color => color && Number.isFinite(color.r) && Number.isFinite(color.g) && Number.isFinite(color.b))
|
|
4490
|
+
.map(color => ({ r: color.r, g: color.g, b: color.b }));
|
|
4491
|
+
const allowedRadii = (raw.allowedRadii || [])
|
|
4492
|
+
.map(Number)
|
|
4493
|
+
.filter(px => Number.isFinite(px));
|
|
4494
|
+
return {
|
|
4495
|
+
present: true,
|
|
4496
|
+
hasFonts: raw.hasFonts === true && allowedFonts.size > 0,
|
|
4497
|
+
allowedFonts,
|
|
4498
|
+
hasColors: raw.hasColors === true && allowedColors.length > 0,
|
|
4499
|
+
allowedColors,
|
|
4500
|
+
hasRadii: raw.hasRadii === true && allowedRadii.length > 0,
|
|
4501
|
+
allowedRadii,
|
|
4502
|
+
hasPillRadius: raw.hasPillRadius === true,
|
|
4503
|
+
};
|
|
4504
|
+
}
|
|
4505
|
+
|
|
4506
|
+
function browserColorsClose(a, b) {
|
|
4507
|
+
if (!a || !b) return false;
|
|
4508
|
+
return Math.max(
|
|
4509
|
+
Math.abs(a.r - b.r),
|
|
4510
|
+
Math.abs(a.g - b.g),
|
|
4511
|
+
Math.abs(a.b - b.b),
|
|
4512
|
+
) <= DESIGN_COLOR_TOLERANCE;
|
|
4513
|
+
}
|
|
4514
|
+
|
|
4515
|
+
function isBrowserDesignColorAllowed(raw, designSystem) {
|
|
4516
|
+
if (!designSystem?.hasColors) return true;
|
|
4517
|
+
const text = String(raw || '').trim().toLowerCase();
|
|
4518
|
+
if (!text || text === 'transparent' || text === 'currentcolor' || text === 'inherit' || text === 'initial') return true;
|
|
4519
|
+
if (text.includes('var(')) return true;
|
|
4520
|
+
const parsed = parseAnyColor(text);
|
|
4521
|
+
if (!parsed) return true;
|
|
4522
|
+
if ((parsed.a ?? 1) <= 0.05) return true;
|
|
4523
|
+
return designSystem.allowedColors.some(color => browserColorsClose(parsed, color));
|
|
4524
|
+
}
|
|
4525
|
+
|
|
4526
|
+
function isBrowserTransparentCss(value) {
|
|
4527
|
+
const text = String(value || '').trim().toLowerCase();
|
|
4528
|
+
if (!text || text === 'transparent') return true;
|
|
4529
|
+
const parsed = parseAnyColor(text);
|
|
4530
|
+
return parsed ? (parsed.a ?? 1) <= 0.05 : false;
|
|
4531
|
+
}
|
|
4532
|
+
|
|
4533
|
+
function isBrowserDesignRadiusAllowed(raw, designSystem) {
|
|
4534
|
+
if (!designSystem?.hasRadii) return true;
|
|
4535
|
+
const text = String(raw || '').trim().toLowerCase();
|
|
4536
|
+
if (!text || text === '0' || text === 'none' || text === 'initial' || text === 'inherit') return true;
|
|
4537
|
+
if (text.includes('var(') || text.includes('%')) return true;
|
|
4538
|
+
const px = resolveLengthPx(text, 16);
|
|
4539
|
+
if (px == null || !Number.isFinite(px) || px <= DESIGN_RADIUS_TOLERANCE_PX) return true;
|
|
4540
|
+
if (designSystem.hasPillRadius && px >= 99) return true;
|
|
4541
|
+
return designSystem.allowedRadii.some(allowed => Math.abs(allowed - px) <= DESIGN_RADIUS_TOLERANCE_PX);
|
|
4542
|
+
}
|
|
4543
|
+
|
|
4544
|
+
function browserRadiusTokens(value) {
|
|
4545
|
+
return String(value || '')
|
|
4546
|
+
.replace(/\s*\/\s*/g, ' ')
|
|
4547
|
+
.split(/\s+/)
|
|
4548
|
+
.map(token => token.trim())
|
|
4549
|
+
.filter(Boolean);
|
|
4550
|
+
}
|
|
4551
|
+
|
|
4552
|
+
function browserHasDirectText(el) {
|
|
4553
|
+
return [...(el.childNodes || [])].some(node => node.nodeType === 3 && node.textContent.trim().length > 0);
|
|
4554
|
+
}
|
|
4555
|
+
|
|
4556
|
+
function browserSampleText(el) {
|
|
4557
|
+
const text = String(el.textContent || '').replace(/\s+/g, ' ').trim();
|
|
4558
|
+
return text ? ` "${text.slice(0, 40)}"` : '';
|
|
4559
|
+
}
|
|
4560
|
+
|
|
4561
|
+
function shouldSkipDesignElement(el) {
|
|
4562
|
+
const tag = el.tagName?.toLowerCase?.() || '';
|
|
4563
|
+
return DESIGN_SKIP_TAGS.has(tag) || isElementHidden(el);
|
|
4564
|
+
}
|
|
4565
|
+
|
|
4566
|
+
function checkElementDesignSystemDOM(el, designSystem, seen) {
|
|
4567
|
+
if (!designSystem?.present || shouldSkipDesignElement(el)) return [];
|
|
4568
|
+
const findings = [];
|
|
4569
|
+
const tag = el.tagName?.toLowerCase?.() || 'unknown';
|
|
4570
|
+
const style = getComputedStyle(el);
|
|
4571
|
+
|
|
4572
|
+
if (designSystem.hasFonts && browserHasDirectText(el)) {
|
|
4573
|
+
const font = browserPrimaryFont(style.fontFamily || '');
|
|
4574
|
+
if (font && !designSystem.allowedFonts.has(font) && !seen.fonts.has(font)) {
|
|
4575
|
+
seen.fonts.add(font);
|
|
4576
|
+
findings.push({
|
|
4577
|
+
type: 'design-system-font',
|
|
4578
|
+
detail: `${tag}${browserSampleText(el)} uses ${font}; not declared in DESIGN.md typography`,
|
|
4579
|
+
ignoreValue: font,
|
|
4580
|
+
});
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4583
|
+
|
|
4584
|
+
if (designSystem.hasColors) {
|
|
4585
|
+
const colorChecks = [];
|
|
4586
|
+
if (browserHasDirectText(el)) colorChecks.push(['text color', style.color]);
|
|
4587
|
+
if (!isBrowserTransparentCss(style.backgroundColor)) colorChecks.push(['background', style.backgroundColor]);
|
|
4588
|
+
for (const side of ['Top', 'Right', 'Bottom', 'Left']) {
|
|
4589
|
+
if ((parseFloat(style[`border${side}Width`]) || 0) > 0) {
|
|
4590
|
+
colorChecks.push([`border-${side.toLowerCase()}`, style[`border${side}Color`]]);
|
|
4591
|
+
}
|
|
4592
|
+
}
|
|
4593
|
+
if ((parseFloat(style.outlineWidth) || 0) > 0) colorChecks.push(['outline', style.outlineColor]);
|
|
4594
|
+
|
|
4595
|
+
for (const [kind, raw] of colorChecks) {
|
|
4596
|
+
const label = String(raw || '').trim().replace(/\s+/g, ' ');
|
|
4597
|
+
if (isBrowserDesignColorAllowed(label, designSystem)) continue;
|
|
4598
|
+
const key = `${kind}:${label}`;
|
|
4599
|
+
if (seen.colors.has(key)) continue;
|
|
4600
|
+
seen.colors.add(key);
|
|
4601
|
+
findings.push({
|
|
4602
|
+
type: 'design-system-color',
|
|
4603
|
+
detail: `${kind} ${label} on ${tag}${browserSampleText(el)} is outside DESIGN.md colors`,
|
|
4604
|
+
ignoreValue: label,
|
|
4605
|
+
});
|
|
4606
|
+
}
|
|
4607
|
+
}
|
|
4608
|
+
|
|
4609
|
+
if (designSystem.hasRadii) {
|
|
4610
|
+
for (const token of browserRadiusTokens(style.borderRadius || '')) {
|
|
4611
|
+
if (isBrowserDesignRadiusAllowed(token, designSystem)) continue;
|
|
4612
|
+
if (seen.radii.has(token)) continue;
|
|
4613
|
+
seen.radii.add(token);
|
|
4614
|
+
findings.push({
|
|
4615
|
+
type: 'design-system-radius',
|
|
4616
|
+
detail: `border-radius ${token} on ${tag}${browserSampleText(el)} is outside the DESIGN.md rounded scale`,
|
|
4617
|
+
ignoreValue: token,
|
|
4618
|
+
});
|
|
4619
|
+
}
|
|
4620
|
+
}
|
|
4621
|
+
|
|
4622
|
+
return findings;
|
|
4623
|
+
}
|
|
4624
|
+
|
|
4625
|
+
function decodeBrowserGoogleFamily(value) {
|
|
4626
|
+
const family = String(value || '').split(':')[0].replace(/\+/g, ' ');
|
|
4627
|
+
try {
|
|
4628
|
+
return decodeURIComponent(family);
|
|
4629
|
+
} catch {
|
|
4630
|
+
return family;
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
|
|
4634
|
+
function checkBrowserDesignSystemSources(designSystem, seen) {
|
|
4635
|
+
if (!designSystem?.hasFonts) return [];
|
|
4636
|
+
const findings = [];
|
|
4637
|
+
for (const link of document.querySelectorAll('link[href*="fonts.googleapis.com/css"]')) {
|
|
4638
|
+
const href = link.getAttribute('href') || '';
|
|
4639
|
+
for (const match of href.matchAll(/[?&]family=([^&]+)/g)) {
|
|
4640
|
+
const display = decodeBrowserGoogleFamily(match[1]);
|
|
4641
|
+
const font = normalizeBrowserFontName(display);
|
|
4642
|
+
if (!font || designSystem.allowedFonts.has(font) || seen.fonts.has(font)) continue;
|
|
4643
|
+
seen.fonts.add(font);
|
|
4644
|
+
findings.push({
|
|
4645
|
+
type: 'design-system-font',
|
|
4646
|
+
detail: `Google Fonts: ${display} is not declared in DESIGN.md typography`,
|
|
4647
|
+
ignoreValue: display,
|
|
4648
|
+
});
|
|
4649
|
+
}
|
|
4650
|
+
}
|
|
4651
|
+
return findings;
|
|
4652
|
+
}
|
|
4653
|
+
|
|
4433
4654
|
function collectBrowserFindings() {
|
|
4434
4655
|
const groupMap = new Map();
|
|
4435
4656
|
const _disabled = EXTENSION_MODE ? (window.__IMPECCABLE_CONFIG__?.disabledRules || []) : [];
|
|
4436
4657
|
const _ruleOk = (id) => !_disabled.length || !_disabled.includes(id);
|
|
4658
|
+
const designSystem = browserDesignSystemConfig();
|
|
4659
|
+
const designSeen = { fonts: new Set(), colors: new Set(), radii: new Set() };
|
|
4437
4660
|
// Note: provider-gated rules (--gpt / --gemini) are NOT filtered here. In a
|
|
4438
4661
|
// real browser env (detector page, live overlay, extension) running every
|
|
4439
4662
|
// check is free, so we always surface them; the gating is purely a CLI
|
|
@@ -4464,6 +4687,7 @@ if (IS_BROWSER) {
|
|
|
4464
4687
|
...checkElementClippedOverflowDOM(el).map(f => ({ type: f.id, detail: f.snippet })),
|
|
4465
4688
|
...checkElementGptBorderShadowDOM(el).map(f => ({ type: f.id, detail: f.snippet })),
|
|
4466
4689
|
...checkElementTextOverflowDOM(el).map(f => ({ type: f.id, detail: f.snippet })),
|
|
4690
|
+
...checkElementDesignSystemDOM(el, designSystem, designSeen),
|
|
4467
4691
|
].filter(f => _ruleOk(f.type));
|
|
4468
4692
|
|
|
4469
4693
|
addBrowserFindings(groupMap, el, findings);
|
|
@@ -4480,6 +4704,13 @@ if (IS_BROWSER) {
|
|
|
4480
4704
|
|
|
4481
4705
|
const pageLevelFindings = [];
|
|
4482
4706
|
|
|
4707
|
+
const designSourceFindings = checkBrowserDesignSystemSources(designSystem, designSeen)
|
|
4708
|
+
.filter(f => _ruleOk(f.type));
|
|
4709
|
+
if (designSourceFindings.length > 0) {
|
|
4710
|
+
pageLevelFindings.push(...designSourceFindings);
|
|
4711
|
+
addBrowserFindings(groupMap, document.body, designSourceFindings);
|
|
4712
|
+
}
|
|
4713
|
+
|
|
4483
4714
|
const typoFindings = checkTypography().filter(f => _ruleOk(f.type));
|
|
4484
4715
|
if (typoFindings.length > 0) {
|
|
4485
4716
|
pageLevelFindings.push(...typoFindings);
|
package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/detect-antipatterns.mjs
CHANGED
|
@@ -23,6 +23,13 @@ export {
|
|
|
23
23
|
checkHtmlPatterns,
|
|
24
24
|
} from './rules/checks.mjs';
|
|
25
25
|
export { createDetectorProfile, summarizeDetectorProfile } from './profile/profiler.mjs';
|
|
26
|
+
export {
|
|
27
|
+
parseFrontmatter as parseDesignFrontmatter,
|
|
28
|
+
normalizeDesignSystem,
|
|
29
|
+
loadDesignSystemForCwd,
|
|
30
|
+
checkSourceDesignSystem,
|
|
31
|
+
collectStaticDesignSystemFindings,
|
|
32
|
+
} from './design-system.mjs';
|
|
26
33
|
export { detectHtml } from './engines/static-html/detect-html.mjs';
|
|
27
34
|
export { detectUrl, createBrowserDetector } from './engines/browser/detect-url.mjs';
|
|
28
35
|
export { detectText, extractStyleBlocks, extractCSSinJS } from './engines/regex/detect-text.mjs';
|
|
@@ -7,6 +7,25 @@ import { filterByProviders } from '../../registry/antipatterns.mjs';
|
|
|
7
7
|
import { profileFindingsAsync, profileStep, profileStepAsync } from '../../profile/profiler.mjs';
|
|
8
8
|
import { captureVisualContrastCandidate } from '../visual/screenshot-contrast.mjs';
|
|
9
9
|
|
|
10
|
+
function serializeDesignSystemForBrowser(designSystem) {
|
|
11
|
+
if (!designSystem?.present) return null;
|
|
12
|
+
return {
|
|
13
|
+
present: true,
|
|
14
|
+
hasFonts: designSystem.hasFonts === true,
|
|
15
|
+
allowedFonts: Array.from(designSystem.allowedFonts || []),
|
|
16
|
+
hasColors: designSystem.hasColors === true,
|
|
17
|
+
allowedColors: Array.from(designSystem.allowedColorKeys?.values?.() || [])
|
|
18
|
+
.map(entry => entry?.color)
|
|
19
|
+
.filter(color => color && Number.isFinite(color.r) && Number.isFinite(color.g) && Number.isFinite(color.b))
|
|
20
|
+
.map(color => ({ r: color.r, g: color.g, b: color.b })),
|
|
21
|
+
hasRadii: designSystem.hasRadii === true,
|
|
22
|
+
allowedRadii: (designSystem.allowedRadii || [])
|
|
23
|
+
.map(entry => Number(entry?.px))
|
|
24
|
+
.filter(px => Number.isFinite(px)),
|
|
25
|
+
hasPillRadius: designSystem.hasPillRadius === true,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
10
29
|
async function runVisualContrastFallback(page, serializedGroups, options, profile, target) {
|
|
11
30
|
if (options?.visualContrast === false) return [];
|
|
12
31
|
const maxCandidates = Number.isFinite(options?.visualContrastMaxCandidates)
|
|
@@ -163,17 +182,19 @@ async function detectUrl(url, options = {}) {
|
|
|
163
182
|
}
|
|
164
183
|
|
|
165
184
|
// Inject the browser detection script and collect results
|
|
185
|
+
const browserDesignSystem = serializeDesignSystemForBrowser(options?.designSystem);
|
|
166
186
|
await profileStepAsync(profile, {
|
|
167
187
|
engine: 'browser',
|
|
168
188
|
phase: 'scan',
|
|
169
189
|
ruleId: 'configure-pure-detect',
|
|
170
190
|
target: url,
|
|
171
|
-
}, () => page.evaluate(() => {
|
|
191
|
+
}, () => page.evaluate((designSystem) => {
|
|
172
192
|
window.__IMPECCABLE_CONFIG__ = {
|
|
173
193
|
...(window.__IMPECCABLE_CONFIG__ || {}),
|
|
174
194
|
autoScan: false,
|
|
195
|
+
...(designSystem ? { designSystem } : {}),
|
|
175
196
|
};
|
|
176
|
-
}));
|
|
197
|
+
}, browserDesignSystem));
|
|
177
198
|
await profileStepAsync(profile, {
|
|
178
199
|
engine: 'browser',
|
|
179
200
|
phase: 'scan',
|
|
@@ -192,7 +213,7 @@ async function detectUrl(url, options = {}) {
|
|
|
192
213
|
return window.impeccableDetect({ decorate: false, serialize: true });
|
|
193
214
|
});
|
|
194
215
|
return serializedGroups.flatMap(({ findings }) =>
|
|
195
|
-
findings.map(f => ({ id: f.type, snippet: f.detail }))
|
|
216
|
+
findings.map(f => ({ id: f.type, snippet: f.detail, ignoreValue: f.ignoreValue || '' }))
|
|
196
217
|
);
|
|
197
218
|
});
|
|
198
219
|
const visualFindings = await runVisualContrastFallback(page, serializedGroups, options, profile, url);
|
|
@@ -213,7 +234,11 @@ async function detectUrl(url, options = {}) {
|
|
|
213
234
|
}, () => browser.close());
|
|
214
235
|
}
|
|
215
236
|
}
|
|
216
|
-
return filterByProviders(results.map(f =>
|
|
237
|
+
return filterByProviders(results.map(f => {
|
|
238
|
+
const item = finding(f.id, url, f.snippet);
|
|
239
|
+
if (f.ignoreValue) item.ignoreValue = f.ignoreValue;
|
|
240
|
+
return item;
|
|
241
|
+
}), options.providers);
|
|
217
242
|
}
|
|
218
243
|
|
|
219
244
|
async function createBrowserDetector(options = {}) {
|
package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { GENERIC_FONTS } from '../../shared/constants.mjs';
|
|
2
|
+
import { isNeutralColor } from '../../shared/color.mjs';
|
|
3
|
+
import { checkSourceDesignSystem } from '../../design-system.mjs';
|
|
2
4
|
import { isFullPage } from '../../shared/page.mjs';
|
|
5
|
+
import { applyInlineIgnores } from '../../shared/inline-ignores.mjs';
|
|
3
6
|
import { finding } from '../../findings.mjs';
|
|
4
7
|
import { filterByProviders } from '../../registry/antipatterns.mjs';
|
|
5
8
|
import { profileFindings, profileStep } from '../../profile/profiler.mjs';
|
|
@@ -36,10 +39,11 @@ function shouldRunPageAnalyzers(content, filePath) {
|
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
function isNeutralBorderColor(str) {
|
|
39
|
-
const m = str.match(/solid\s+(
|
|
42
|
+
const m = str.match(/solid\s+((?:rgba?|hsla?|oklch|oklab|lab|lch|hwb|color)\([^)]*\)|#[0-9a-f]{3,8}\b|[a-z]+)/i);
|
|
40
43
|
if (!m) return false;
|
|
41
44
|
const c = m[1].toLowerCase();
|
|
42
45
|
if (['gray', 'grey', 'silver', 'white', 'black', 'transparent', 'currentcolor'].includes(c)) return true;
|
|
46
|
+
if (/^(?:rgba?|hsla?|oklch|oklab|lab|lch|hwb)\(/i.test(c)) return isNeutralColor(c);
|
|
43
47
|
const hex = c.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/);
|
|
44
48
|
if (hex) {
|
|
45
49
|
const [r, g, b] = [parseInt(hex[1], 16), parseInt(hex[2], 16), parseInt(hex[3], 16)];
|
|
@@ -56,10 +60,10 @@ function isNeutralBorderColor(str) {
|
|
|
56
60
|
const REGEX_MATCHERS = [
|
|
57
61
|
// --- Side-tab ---
|
|
58
62
|
{ id: 'side-tab', regex: /\bborder-[lrse]-(\d+)\b/g,
|
|
59
|
-
test: (m, line) => { const n = +m[1]; return hasRounded(line) ? n >=
|
|
63
|
+
test: (m, line) => { const n = +m[1]; return hasRounded(line) ? n >= 2 : n >= 4; },
|
|
60
64
|
fmt: (m) => m[0] },
|
|
61
65
|
{ id: 'side-tab', regex: /border-(?:left|right)\s*:\s*(\d+)px\s+solid[^;]*/gi,
|
|
62
|
-
test: (m, line) => { if (isSafeElement(line)) return false; if (isNeutralBorderColor(m[0])) return false; const n = +m[1]; return hasBorderRadius(line) ? n >=
|
|
66
|
+
test: (m, line) => { if (isSafeElement(line)) return false; if (isNeutralBorderColor(m[0])) return false; const n = +m[1]; return hasBorderRadius(line) ? n >= 2 : n >= 3; },
|
|
63
67
|
fmt: (m) => m[0].replace(/\s*;?\s*$/, '') },
|
|
64
68
|
{ id: 'side-tab', regex: /border-(?:left|right)-width\s*:\s*(\d+)px/gi,
|
|
65
69
|
test: (m, line) => !isSafeElement(line) && +m[1] >= 3,
|
|
@@ -503,6 +507,15 @@ function detectText(content, filePath, options = {}) {
|
|
|
503
507
|
}));
|
|
504
508
|
}
|
|
505
509
|
|
|
510
|
+
if (options?.designSystem) {
|
|
511
|
+
findings.push(...profileFindings(profile, {
|
|
512
|
+
engine: 'regex',
|
|
513
|
+
phase: 'source',
|
|
514
|
+
ruleId: 'design-system',
|
|
515
|
+
target: filePath,
|
|
516
|
+
}, () => checkSourceDesignSystem(content, filePath, { designSystem: options.designSystem })));
|
|
517
|
+
}
|
|
518
|
+
|
|
506
519
|
// Deduplicate findings (same antipattern + similar snippet, within 2 lines)
|
|
507
520
|
const deduped = [];
|
|
508
521
|
for (const f of findings) {
|
|
@@ -537,7 +550,10 @@ function detectText(content, filePath, options = {}) {
|
|
|
537
550
|
}
|
|
538
551
|
}
|
|
539
552
|
|
|
540
|
-
|
|
553
|
+
const byProvider = filterByProviders(deduped, options?.providers);
|
|
554
|
+
// Inline `impeccable-disable*` waivers travel with the file; honor them unless
|
|
555
|
+
// explicitly bypassed (`--no-config` / `--no-inline-ignores`).
|
|
556
|
+
return options?.inlineIgnores === false ? byProvider : applyInlineIgnores(byProvider, content);
|
|
541
557
|
}
|
|
542
558
|
|
|
543
559
|
export {
|
|
@@ -272,6 +272,7 @@ const STATIC_DEFAULT_STYLE = {
|
|
|
272
272
|
marginBottom: '0px',
|
|
273
273
|
marginLeft: '0px',
|
|
274
274
|
position: 'static',
|
|
275
|
+
visibility: 'visible',
|
|
275
276
|
top: 'auto',
|
|
276
277
|
right: 'auto',
|
|
277
278
|
bottom: 'auto',
|
|
@@ -326,6 +327,7 @@ const STATIC_PROP_MAP = {
|
|
|
326
327
|
'margin-bottom': 'marginBottom',
|
|
327
328
|
'margin-left': 'marginLeft',
|
|
328
329
|
'position': 'position',
|
|
330
|
+
'visibility': 'visibility',
|
|
329
331
|
'top': 'top',
|
|
330
332
|
'right': 'right',
|
|
331
333
|
'bottom': 'bottom',
|
|
@@ -2,7 +2,13 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
import { GENERIC_FONTS, OVERUSED_FONTS } from '../../shared/constants.mjs';
|
|
5
|
+
import {
|
|
6
|
+
checkSourceDesignSystem,
|
|
7
|
+
collectStaticDesignSystemFindings,
|
|
8
|
+
mergeDesignSystemFindings,
|
|
9
|
+
} from '../../design-system.mjs';
|
|
5
10
|
import { isFullPage } from '../../shared/page.mjs';
|
|
11
|
+
import { applyInlineIgnores } from '../../shared/inline-ignores.mjs';
|
|
6
12
|
import { finding } from '../../findings.mjs';
|
|
7
13
|
import { profileFindings, profileStep, profileStepAsync } from '../../profile/profiler.mjs';
|
|
8
14
|
import {
|
|
@@ -168,6 +174,22 @@ async function detectHtml(filePath, options = {}) {
|
|
|
168
174
|
}
|
|
169
175
|
}
|
|
170
176
|
|
|
177
|
+
if (options?.designSystem) {
|
|
178
|
+
const sourceDesignFindings = profileFindings(profile, {
|
|
179
|
+
engine: 'static-html',
|
|
180
|
+
phase: 'source',
|
|
181
|
+
ruleId: 'design-system',
|
|
182
|
+
target: filePath,
|
|
183
|
+
}, () => checkSourceDesignSystem(html, filePath, { designSystem: options.designSystem }));
|
|
184
|
+
const staticDesignFindings = profileFindings(profile, {
|
|
185
|
+
engine: 'static-html',
|
|
186
|
+
phase: 'page',
|
|
187
|
+
ruleId: 'design-system',
|
|
188
|
+
target: filePath,
|
|
189
|
+
}, () => collectStaticDesignSystemFindings(document, window, filePath, options.designSystem));
|
|
190
|
+
findings.push(...mergeDesignSystemFindings(staticDesignFindings, sourceDesignFindings));
|
|
191
|
+
}
|
|
192
|
+
|
|
171
193
|
if (isFullPage(html)) {
|
|
172
194
|
const runPageCheck = (ruleId, callback) => profile
|
|
173
195
|
? profileFindings(profile, { engine: 'static-html', phase: 'page', ruleId, target: filePath }, callback)
|
|
@@ -202,7 +224,11 @@ async function detectHtml(filePath, options = {}) {
|
|
|
202
224
|
}
|
|
203
225
|
}
|
|
204
226
|
|
|
205
|
-
|
|
227
|
+
const byProvider = filterByProviders(findings, options.providers);
|
|
228
|
+
// Static-HTML findings carry no line number, so only whole-file
|
|
229
|
+
// `impeccable-disable` directives apply here — exactly the standalone-document
|
|
230
|
+
// waiver this primitive targets. Bypassed by `--no-config` / `--no-inline-ignores`.
|
|
231
|
+
return options?.inlineIgnores === false ? byProvider : applyInlineIgnores(byProvider, html);
|
|
206
232
|
}
|
|
207
233
|
|
|
208
234
|
export { checkStaticPageTypography, STATIC_ELEMENT_RULES, detectHtml };
|
package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/registry/antipatterns.mjs
CHANGED
|
@@ -323,6 +323,35 @@ const ANTIPATTERNS = [
|
|
|
323
323
|
skillSection: 'Layout & Space',
|
|
324
324
|
skillGuideline: 'overflow container clipping positioned children',
|
|
325
325
|
},
|
|
326
|
+
{
|
|
327
|
+
id: 'design-system-font',
|
|
328
|
+
category: 'quality',
|
|
329
|
+
name: 'Font outside DESIGN.md',
|
|
330
|
+
description:
|
|
331
|
+
'A font is used that is not declared in DESIGN.md typography. Use the documented type system or update DESIGN.md if this is an intentional brand addition.',
|
|
332
|
+
skillSection: 'Typography',
|
|
333
|
+
skillGuideline: 'font family outside the project design system',
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
id: 'design-system-color',
|
|
337
|
+
category: 'quality',
|
|
338
|
+
severity: 'advisory',
|
|
339
|
+
name: 'Color outside DESIGN.md',
|
|
340
|
+
description:
|
|
341
|
+
'A literal color is outside the DESIGN.md palette and sidecar tonal ramps. This may be legitimate, but it should be an intentional design-system addition rather than drift.',
|
|
342
|
+
skillSection: 'Color & Contrast',
|
|
343
|
+
skillGuideline: 'literal color outside the project design system',
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
id: 'design-system-radius',
|
|
347
|
+
category: 'quality',
|
|
348
|
+
severity: 'advisory',
|
|
349
|
+
name: 'Radius outside DESIGN.md',
|
|
350
|
+
description:
|
|
351
|
+
'A border-radius value is outside the DESIGN.md rounded scale. Use a documented radius token or update the design system if the new shape is intentional.',
|
|
352
|
+
skillSection: 'Visual Details',
|
|
353
|
+
skillGuideline: 'border radius outside the project design system',
|
|
354
|
+
},
|
|
326
355
|
|
|
327
356
|
// ── Provider tells: opt-in via --gpt / --gemini (gated off by default) ──
|
|
328
357
|
{
|
package/bundled/upstream/impeccable/skills/impeccable/scripts/detector/shared/inline-ignores.mjs
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline, in-file ignore directives — eslint-disable-style waivers that live at
|
|
3
|
+
* the point they apply and travel with the artifact instead of (or alongside)
|
|
4
|
+
* an ignore in `.impeccable/config.json`.
|
|
5
|
+
*
|
|
6
|
+
* A config ignore is the right default for repo-wide policy. This complements it
|
|
7
|
+
* for the one case config can't cover: a waiver that belongs to a single file and
|
|
8
|
+
* needs to follow that file when it leaves the repo — a generated/exported
|
|
9
|
+
* standalone document, an emailed HTML file, a snippet scanned out of context.
|
|
10
|
+
*
|
|
11
|
+
* Comment-syntax-agnostic: the directive is a raw token matched anywhere on a
|
|
12
|
+
* line, so the same marker works across every comment style impeccable scans —
|
|
13
|
+
* `//`, `/* *\/`, `<!-- -->`, `#`, `{/* *\/}`, `{# #}`. Trailing comment closers
|
|
14
|
+
* are stripped before the rule list is parsed.
|
|
15
|
+
*
|
|
16
|
+
* Syntax (reason optional; eslint `--` or biome `:` separator):
|
|
17
|
+
*
|
|
18
|
+
* impeccable-disable <rule>[, <rule>...] [-- reason] whole file
|
|
19
|
+
* impeccable-disable-line <rule>... [-- reason] the same line
|
|
20
|
+
* impeccable-disable-next-line <rule>... [-- reason] the following line
|
|
21
|
+
* impeccable-disable bare / `*` = every rule
|
|
22
|
+
*
|
|
23
|
+
* Examples:
|
|
24
|
+
*
|
|
25
|
+
* <!-- impeccable-disable overused-font -- exported brand doc, font is first-party -->
|
|
26
|
+
* .brand { font-family: Inter; } /* impeccable-disable-line overused-font *\/
|
|
27
|
+
* // impeccable-disable-next-line bounce-easing: intentional playful affordance
|
|
28
|
+
*
|
|
29
|
+
* Behavior is suppression, for parity with config ignores: a matched directive
|
|
30
|
+
* drops the finding. The inline reason is self-documenting in the diff; it is not
|
|
31
|
+
* required and is discarded at scan time (only used here to keep reason words out
|
|
32
|
+
* of the parsed rule list).
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
const DIRECTIVE_RE = /impeccable-(disable-next-line|disable-line|disable)\b[ \t]*([^\n\r]*)/gi;
|
|
36
|
+
|
|
37
|
+
// Trailing comment closers, so `*/`, `*/}`, `-->`, `*}`, `#}`, `%>`, `}}` don't
|
|
38
|
+
// leak into the rule list. Anchored to end-of-line; the leading `\s*` mops up the
|
|
39
|
+
// space before the closer. `--+>` covers `-->` and any longer dash run.
|
|
40
|
+
const TRAILING_CLOSER_RE = /\s*(?:\*\/\}?|--+>|\*\}|#\}|%>|\}\})\s*$/;
|
|
41
|
+
|
|
42
|
+
function normalizeRule(token) {
|
|
43
|
+
return String(token || '').trim().toLowerCase();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Split the directive remainder into rule tokens, dropping any human reason that
|
|
47
|
+
// follows an eslint-style `--` or biome-style `:` separator. Rule ids only ever
|
|
48
|
+
// contain single hyphens (`overused-font`, `bounce-easing`), so `--` and `:`
|
|
49
|
+
// are unambiguous separators.
|
|
50
|
+
function parseRuleList(remainder) {
|
|
51
|
+
let text = String(remainder || '').replace(TRAILING_CLOSER_RE, '').trim();
|
|
52
|
+
// Cut off a human reason at the first `--` (eslint) or `:` (biome) separator.
|
|
53
|
+
const reasonSep = text.match(/\s*(?:--+|:)\s*/);
|
|
54
|
+
if (reasonSep) text = text.slice(0, reasonSep.index);
|
|
55
|
+
const tokens = text.split(/[\s,]+/).map(normalizeRule).filter(Boolean);
|
|
56
|
+
if (tokens.length === 0 || tokens.includes('*')) return ['*'];
|
|
57
|
+
return tokens;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function addRules(set, rules) {
|
|
61
|
+
for (const rule of rules) set.add(rule);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getSet(map, key) {
|
|
65
|
+
let set = map.get(key);
|
|
66
|
+
if (!set) {
|
|
67
|
+
set = new Set();
|
|
68
|
+
map.set(key, set);
|
|
69
|
+
}
|
|
70
|
+
return set;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Parse every inline ignore directive in a file's raw text.
|
|
75
|
+
*
|
|
76
|
+
* Returns sets keyed by the 1-based line the directive *targets* so matching is a
|
|
77
|
+
* direct lookup:
|
|
78
|
+
* - file: rules disabled for the whole file
|
|
79
|
+
* - line: line -> rules disabled on that exact line (disable-line)
|
|
80
|
+
* - nextLine: line -> rules disabled on that line (disable-next-line on line-1)
|
|
81
|
+
*
|
|
82
|
+
* `*` in any set means "every rule".
|
|
83
|
+
*/
|
|
84
|
+
function parseInlineIgnores(content) {
|
|
85
|
+
const result = { file: new Set(), line: new Map(), nextLine: new Map() };
|
|
86
|
+
const text = typeof content === 'string' ? content : '';
|
|
87
|
+
// Cheap bail-out: the substring must be present for any directive to exist.
|
|
88
|
+
// Case-insensitive to match DIRECTIVE_RE's `i` flag (e.g. `Impeccable-Disable`).
|
|
89
|
+
if (!/impeccable-disable/i.test(text)) return result;
|
|
90
|
+
|
|
91
|
+
// Split on `\n` only, exactly as detectText numbers lines, so directive line
|
|
92
|
+
// keys line up with finding `line` values (incl. on `\r`-only line endings).
|
|
93
|
+
// The directive regex excludes `\r`, so a trailing `\r` on `\r\n` files is
|
|
94
|
+
// never captured into the rule list.
|
|
95
|
+
const lines = text.split('\n');
|
|
96
|
+
for (let i = 0; i < lines.length; i++) {
|
|
97
|
+
DIRECTIVE_RE.lastIndex = 0;
|
|
98
|
+
let m;
|
|
99
|
+
while ((m = DIRECTIVE_RE.exec(lines[i])) !== null) {
|
|
100
|
+
const variant = m[1].toLowerCase();
|
|
101
|
+
const rules = parseRuleList(m[2]);
|
|
102
|
+
if (variant === 'disable') {
|
|
103
|
+
addRules(result.file, rules);
|
|
104
|
+
} else if (variant === 'disable-line') {
|
|
105
|
+
addRules(getSet(result.line, i + 1), rules);
|
|
106
|
+
} else {
|
|
107
|
+
// disable-next-line on line i+1 targets line i+2.
|
|
108
|
+
addRules(getSet(result.nextLine, i + 2), rules);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function setMatches(set, rule) {
|
|
116
|
+
return Boolean(set) && (set.has('*') || set.has(rule));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function isInlineIgnored(finding, directives) {
|
|
120
|
+
const rule = normalizeRule(finding && finding.antipattern);
|
|
121
|
+
if (!rule) return false;
|
|
122
|
+
if (setMatches(directives.file, rule)) return true;
|
|
123
|
+
const line = Number(finding && finding.line) || 0;
|
|
124
|
+
if (line > 0) {
|
|
125
|
+
if (setMatches(directives.line.get(line), rule)) return true;
|
|
126
|
+
if (setMatches(directives.nextLine.get(line), rule)) return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function hasDirectives(directives) {
|
|
132
|
+
return directives.file.size > 0 || directives.line.size > 0 || directives.nextLine.size > 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Drop findings waived by an inline directive in the same file's source text.
|
|
137
|
+
* Findings without a usable line number (e.g. static-HTML page-level findings)
|
|
138
|
+
* are only matched by whole-file directives — which is the standalone-document
|
|
139
|
+
* case this primitive exists for.
|
|
140
|
+
*/
|
|
141
|
+
function applyInlineIgnores(findings, content) {
|
|
142
|
+
if (!Array.isArray(findings) || findings.length === 0) return findings;
|
|
143
|
+
const directives = parseInlineIgnores(content);
|
|
144
|
+
if (!hasDirectives(directives)) return findings;
|
|
145
|
+
return findings.filter((finding) => !isInlineIgnored(finding, directives));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export { parseInlineIgnores, applyInlineIgnores, isInlineIgnored };
|