claudecode-omc 5.11.0 → 5.13.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/.local/skills/prompt-pilot/SKILL.md +258 -0
- 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
|
@@ -73,6 +73,7 @@ export const DEFAULT_CONFIG = Object.freeze({
|
|
|
73
73
|
enabled: true,
|
|
74
74
|
quiet: false,
|
|
75
75
|
auditLog: null,
|
|
76
|
+
designSystem: { enabled: true },
|
|
76
77
|
ignoreRules: [],
|
|
77
78
|
ignoreFiles: [],
|
|
78
79
|
ignoreValues: [],
|
|
@@ -135,10 +136,14 @@ export function resolveProjectCwd(event, fallback = process.cwd()) {
|
|
|
135
136
|
|
|
136
137
|
export function readConfig(cwd) {
|
|
137
138
|
const config = cloneDefaultConfig();
|
|
138
|
-
// Hook settings live under
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
// Hook runtime settings live under `hook`; detector filters live under
|
|
140
|
+
// `detector`. Back-compat: older configs stored detector filters in `hook`,
|
|
141
|
+
// so read those first and let canonical `detector` settings win.
|
|
142
|
+
for (const filePath of [getConfigPath(cwd), getLocalConfigPath(cwd)]) {
|
|
143
|
+
const raw = safeReadJson(filePath);
|
|
144
|
+
applyConfigSource(config, hookSection(raw));
|
|
145
|
+
applyDetectorConfigSource(config, detectorSection(raw));
|
|
146
|
+
}
|
|
142
147
|
return config;
|
|
143
148
|
}
|
|
144
149
|
|
|
@@ -148,6 +153,11 @@ function hookSection(raw) {
|
|
|
148
153
|
return raw.hook && typeof raw.hook === 'object' && !Array.isArray(raw.hook) ? raw.hook : null;
|
|
149
154
|
}
|
|
150
155
|
|
|
156
|
+
function detectorSection(raw) {
|
|
157
|
+
if (!raw || typeof raw !== 'object') return null;
|
|
158
|
+
return raw.detector && typeof raw.detector === 'object' && !Array.isArray(raw.detector) ? raw.detector : null;
|
|
159
|
+
}
|
|
160
|
+
|
|
151
161
|
function numberOr(value, fallback) {
|
|
152
162
|
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
153
163
|
}
|
|
@@ -158,20 +168,18 @@ function cloneDefaultConfig() {
|
|
|
158
168
|
ignoreRules: [],
|
|
159
169
|
ignoreFiles: [],
|
|
160
170
|
ignoreValues: [],
|
|
171
|
+
designSystem: { ...DEFAULT_CONFIG.designSystem },
|
|
161
172
|
limits: { ...DEFAULT_CONFIG.limits },
|
|
162
173
|
};
|
|
163
174
|
}
|
|
164
175
|
|
|
165
|
-
function
|
|
176
|
+
function applyDetectorConfigSource(config, raw) {
|
|
166
177
|
if (!raw || typeof raw !== 'object') return config;
|
|
167
|
-
if (
|
|
168
|
-
config.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
if (typeof raw.auditLog === 'string' && raw.auditLog.trim()) {
|
|
174
|
-
config.auditLog = raw.auditLog.trim();
|
|
178
|
+
if (raw.designSystem && typeof raw.designSystem === 'object' && !Array.isArray(raw.designSystem)) {
|
|
179
|
+
config.designSystem = {
|
|
180
|
+
...config.designSystem,
|
|
181
|
+
enabled: raw.designSystem.enabled === false ? false : true,
|
|
182
|
+
};
|
|
175
183
|
}
|
|
176
184
|
if (Array.isArray(raw.ignoreRules)) {
|
|
177
185
|
config.ignoreRules = uniqueStrings([...config.ignoreRules, ...raw.ignoreRules]);
|
|
@@ -182,6 +190,21 @@ function applyConfigSource(config, raw) {
|
|
|
182
190
|
if (Array.isArray(raw.ignoreValues)) {
|
|
183
191
|
config.ignoreValues = mergeIgnoreValues(config.ignoreValues, raw.ignoreValues);
|
|
184
192
|
}
|
|
193
|
+
return config;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function applyConfigSource(config, raw) {
|
|
197
|
+
if (!raw || typeof raw !== 'object') return config;
|
|
198
|
+
if (Object.prototype.hasOwnProperty.call(raw, 'enabled')) {
|
|
199
|
+
config.enabled = raw.enabled === false ? false : true;
|
|
200
|
+
}
|
|
201
|
+
if (Object.prototype.hasOwnProperty.call(raw, 'quiet')) {
|
|
202
|
+
config.quiet = raw.quiet === true;
|
|
203
|
+
}
|
|
204
|
+
if (typeof raw.auditLog === 'string' && raw.auditLog.trim()) {
|
|
205
|
+
config.auditLog = raw.auditLog.trim();
|
|
206
|
+
}
|
|
207
|
+
applyDetectorConfigSource(config, raw);
|
|
185
208
|
if (raw.limits && typeof raw.limits === 'object') {
|
|
186
209
|
config.limits = {
|
|
187
210
|
maxFindings: numberOr(raw.limits.maxFindings, config.limits.maxFindings),
|
|
@@ -208,6 +231,157 @@ function normalizeIgnoreRule(rule) {
|
|
|
208
231
|
return String(rule || '').trim().toLowerCase();
|
|
209
232
|
}
|
|
210
233
|
|
|
234
|
+
function colorIgnoreKey(value) {
|
|
235
|
+
const color = parseIgnoreColor(value);
|
|
236
|
+
if (!color) return '';
|
|
237
|
+
return `${color.r},${color.g},${color.b},${Math.round(color.a * 255)}`;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function parseIgnoreColor(value) {
|
|
241
|
+
const text = String(value || '').trim().toLowerCase();
|
|
242
|
+
if (!text) return null;
|
|
243
|
+
|
|
244
|
+
const hex = text.match(/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i);
|
|
245
|
+
if (hex) return parseHexIgnoreColor(hex[1]);
|
|
246
|
+
|
|
247
|
+
const rgb = text.match(/^rgba?\((.*)\)$/i);
|
|
248
|
+
if (rgb) {
|
|
249
|
+
const parts = splitColorArgs(rgb[1]);
|
|
250
|
+
if (parts.length < 3 || parts.length > 4) return null;
|
|
251
|
+
const r = parseRgbChannel(parts[0]);
|
|
252
|
+
const g = parseRgbChannel(parts[1]);
|
|
253
|
+
const b = parseRgbChannel(parts[2]);
|
|
254
|
+
const a = parts[3] === undefined ? 1 : parseAlphaChannel(parts[3]);
|
|
255
|
+
if ([r, g, b, a].some((v) => v === null)) return null;
|
|
256
|
+
return { r, g, b, a };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const hsl = text.match(/^hsla?\((.*)\)$/i);
|
|
260
|
+
if (hsl) {
|
|
261
|
+
const parts = splitColorArgs(hsl[1]);
|
|
262
|
+
if (parts.length < 3 || parts.length > 4) return null;
|
|
263
|
+
const h = parseHueChannel(parts[0]);
|
|
264
|
+
const s = parsePercentChannel(parts[1]);
|
|
265
|
+
const l = parsePercentChannel(parts[2]);
|
|
266
|
+
const a = parts[3] === undefined ? 1 : parseAlphaChannel(parts[3]);
|
|
267
|
+
if ([h, s, l, a].some((v) => v === null)) return null;
|
|
268
|
+
return hslToRgb(h, s, l, a);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function parseHexIgnoreColor(hex) {
|
|
275
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
276
|
+
const r = parseInt(hex[0] + hex[0], 16);
|
|
277
|
+
const g = parseInt(hex[1] + hex[1], 16);
|
|
278
|
+
const b = parseInt(hex[2] + hex[2], 16);
|
|
279
|
+
const a = hex.length === 4 ? parseInt(hex[3] + hex[3], 16) / 255 : 1;
|
|
280
|
+
return { r, g, b, a };
|
|
281
|
+
}
|
|
282
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
283
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
284
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
285
|
+
const a = hex.length === 8 ? parseInt(hex.slice(6, 8), 16) / 255 : 1;
|
|
286
|
+
return { r, g, b, a };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function splitColorArgs(body) {
|
|
290
|
+
const text = String(body || '').trim();
|
|
291
|
+
if (!text) return [];
|
|
292
|
+
if (text.includes(',')) {
|
|
293
|
+
const parts = text.split(',').map((part) => part.trim()).filter(Boolean);
|
|
294
|
+
const last = parts[parts.length - 1];
|
|
295
|
+
if (last && last.includes('/')) {
|
|
296
|
+
const split = last.split('/').map((part) => part.trim()).filter(Boolean);
|
|
297
|
+
return [...parts.slice(0, -1), ...split];
|
|
298
|
+
}
|
|
299
|
+
return parts;
|
|
300
|
+
}
|
|
301
|
+
return text.replace(/\s*\/\s*/g, ' / ').split(/\s+/).filter((part) => part && part !== '/');
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function parseRgbChannel(raw) {
|
|
305
|
+
const text = String(raw || '').trim();
|
|
306
|
+
const match = text.match(/^(-?\d*\.?\d+)(%)?$/);
|
|
307
|
+
if (!match) return null;
|
|
308
|
+
const value = Number.parseFloat(match[1]);
|
|
309
|
+
if (!Number.isFinite(value)) return null;
|
|
310
|
+
const scaled = match[2] ? value * 2.55 : value;
|
|
311
|
+
if (scaled < 0 || scaled > 255) return null;
|
|
312
|
+
return Math.round(scaled);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function parseAlphaChannel(raw) {
|
|
316
|
+
const text = String(raw || '').trim();
|
|
317
|
+
const match = text.match(/^(-?\d*\.?\d+)(%)?$/);
|
|
318
|
+
if (!match) return null;
|
|
319
|
+
const value = Number.parseFloat(match[1]);
|
|
320
|
+
if (!Number.isFinite(value)) return null;
|
|
321
|
+
const alpha = match[2] ? value / 100 : value;
|
|
322
|
+
return alpha >= 0 && alpha <= 1 ? alpha : null;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function parseHueChannel(raw) {
|
|
326
|
+
const text = String(raw || '').trim();
|
|
327
|
+
const match = text.match(/^(-?\d*\.?\d+)(deg|rad|turn|grad)?$/);
|
|
328
|
+
if (!match) return null;
|
|
329
|
+
const value = Number.parseFloat(match[1]);
|
|
330
|
+
if (!Number.isFinite(value)) return null;
|
|
331
|
+
const unit = match[2] || 'deg';
|
|
332
|
+
if (unit === 'turn') return value * 360;
|
|
333
|
+
if (unit === 'rad') return value * (180 / Math.PI);
|
|
334
|
+
if (unit === 'grad') return value * 0.9;
|
|
335
|
+
return value;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function parsePercentChannel(raw) {
|
|
339
|
+
const text = String(raw || '').trim();
|
|
340
|
+
const match = text.match(/^(-?\d*\.?\d+)%$/);
|
|
341
|
+
if (!match) return null;
|
|
342
|
+
const value = Number.parseFloat(match[1]);
|
|
343
|
+
if (!Number.isFinite(value)) return null;
|
|
344
|
+
return value >= 0 && value <= 100 ? value / 100 : null;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function hslToRgb(hue, saturation, lightness, alpha) {
|
|
348
|
+
const h = (((hue % 360) + 360) % 360) / 360;
|
|
349
|
+
if (saturation === 0) {
|
|
350
|
+
const gray = clampByte(Math.round(lightness * 255));
|
|
351
|
+
return { r: gray, g: gray, b: gray, a: alpha };
|
|
352
|
+
}
|
|
353
|
+
const q = lightness < 0.5
|
|
354
|
+
? lightness * (1 + saturation)
|
|
355
|
+
: lightness + saturation - lightness * saturation;
|
|
356
|
+
const p = 2 * lightness - q;
|
|
357
|
+
const toRgb = (t) => {
|
|
358
|
+
let channel = t;
|
|
359
|
+
if (channel < 0) channel += 1;
|
|
360
|
+
if (channel > 1) channel -= 1;
|
|
361
|
+
if (channel < 1 / 6) return p + (q - p) * 6 * channel;
|
|
362
|
+
if (channel < 1 / 2) return q;
|
|
363
|
+
if (channel < 2 / 3) return p + (q - p) * (2 / 3 - channel) * 6;
|
|
364
|
+
return p;
|
|
365
|
+
};
|
|
366
|
+
return {
|
|
367
|
+
r: clampByte(Math.round(toRgb(h + 1 / 3) * 255)),
|
|
368
|
+
g: clampByte(Math.round(toRgb(h) * 255)),
|
|
369
|
+
b: clampByte(Math.round(toRgb(h - 1 / 3) * 255)),
|
|
370
|
+
a: alpha,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function clampByte(value) {
|
|
375
|
+
return Math.min(255, Math.max(0, value));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function ignoreValueMatches(rule, entryValue, findingValue) {
|
|
379
|
+
if (entryValue === findingValue) return true;
|
|
380
|
+
if (rule !== 'design-system-color') return false;
|
|
381
|
+
const entryColor = colorIgnoreKey(entryValue);
|
|
382
|
+
return Boolean(entryColor && entryColor === colorIgnoreKey(findingValue));
|
|
383
|
+
}
|
|
384
|
+
|
|
211
385
|
export function normalizeIgnoreValueEntries(entries) {
|
|
212
386
|
if (!Array.isArray(entries)) return [];
|
|
213
387
|
const out = [];
|
|
@@ -217,6 +391,11 @@ export function normalizeIgnoreValueEntries(entries) {
|
|
|
217
391
|
const value = normalizeIgnoreValue(entry.value);
|
|
218
392
|
if (!rule || !value) continue;
|
|
219
393
|
const normalized = { rule, value };
|
|
394
|
+
const files = uniqueStrings([
|
|
395
|
+
...(typeof entry.file === 'string' && entry.file.trim() ? [entry.file.trim()] : []),
|
|
396
|
+
...(Array.isArray(entry.files) ? entry.files.filter(v => typeof v === 'string' && v.trim()).map(v => v.trim()) : []),
|
|
397
|
+
]);
|
|
398
|
+
if (files.length > 0) normalized.files = files;
|
|
220
399
|
if (typeof entry.reason === 'string' && entry.reason.trim()) {
|
|
221
400
|
normalized.reason = entry.reason.trim();
|
|
222
401
|
}
|
|
@@ -231,14 +410,18 @@ export function normalizeIgnoreValueEntries(entries) {
|
|
|
231
410
|
function mergeIgnoreValues(existing, incoming) {
|
|
232
411
|
const map = new Map();
|
|
233
412
|
for (const entry of normalizeIgnoreValueEntries(existing)) {
|
|
234
|
-
map.set(`${entry.rule}\0${entry.value}`, entry);
|
|
413
|
+
map.set(`${entry.rule}\0${entry.value}\0${ignoreValueFilesKey(entry.files)}`, entry);
|
|
235
414
|
}
|
|
236
415
|
for (const entry of normalizeIgnoreValueEntries(incoming)) {
|
|
237
|
-
map.set(`${entry.rule}\0${entry.value}`, entry);
|
|
416
|
+
map.set(`${entry.rule}\0${entry.value}\0${ignoreValueFilesKey(entry.files)}`, entry);
|
|
238
417
|
}
|
|
239
418
|
return Array.from(map.values());
|
|
240
419
|
}
|
|
241
420
|
|
|
421
|
+
function ignoreValueFilesKey(files) {
|
|
422
|
+
return Array.isArray(files) && files.length > 0 ? files.join('\x1f') : '';
|
|
423
|
+
}
|
|
424
|
+
|
|
242
425
|
export function readCache(cwd) {
|
|
243
426
|
const raw = safeReadJson(getCachePath(cwd));
|
|
244
427
|
if (!raw || typeof raw !== 'object' || raw.version !== 1) {
|
|
@@ -447,13 +630,39 @@ function isIgnoredFindingValue(finding, ignoreValues) {
|
|
|
447
630
|
const rule = normalizeIgnoreRule(finding.antipattern);
|
|
448
631
|
const value = extractFindingIgnoreValue(finding);
|
|
449
632
|
if (!rule || !value) return false;
|
|
450
|
-
return ignoreValues.some((entry) =>
|
|
633
|
+
return ignoreValues.some((entry) => {
|
|
634
|
+
const wildcardValue = entry.value === '*';
|
|
635
|
+
if (entry.rule !== rule || (!wildcardValue && !ignoreValueMatches(rule, entry.value, value))) return false;
|
|
636
|
+
if (!Array.isArray(entry.files) || entry.files.length === 0) return !wildcardValue;
|
|
637
|
+
return findingMatchesScopedIgnoreFile(finding, entry.files);
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
function findingMatchesScopedIgnoreFile(finding, globs) {
|
|
642
|
+
const filePath = String(finding?.file || '').trim();
|
|
643
|
+
if (!filePath) return false;
|
|
644
|
+
if (matchesAnyGlob(filePath, globs)) return true;
|
|
645
|
+
|
|
646
|
+
const normalized = filePath.split(path.sep).join('/');
|
|
647
|
+
const parts = normalized.split('/').filter(Boolean);
|
|
648
|
+
for (let i = 0; i < parts.length; i++) {
|
|
649
|
+
const suffix = parts.slice(i).join('/');
|
|
650
|
+
if (matchesAnyGlob(suffix, globs)) return true;
|
|
651
|
+
}
|
|
652
|
+
return false;
|
|
451
653
|
}
|
|
452
654
|
|
|
453
655
|
export function extractFindingIgnoreValue(finding) {
|
|
454
656
|
if (!finding || typeof finding !== 'object') return '';
|
|
455
657
|
const rule = normalizeIgnoreRule(finding.antipattern);
|
|
456
|
-
|
|
658
|
+
const directValueRules = new Set([
|
|
659
|
+
'overused-font',
|
|
660
|
+
'bounce-easing',
|
|
661
|
+
'design-system-font',
|
|
662
|
+
'design-system-color',
|
|
663
|
+
'design-system-radius',
|
|
664
|
+
]);
|
|
665
|
+
if (!directValueRules.has(rule)) return '';
|
|
457
666
|
return normalizeIgnoreValue(extractFindingIgnoreValueRaw(finding, rule));
|
|
458
667
|
}
|
|
459
668
|
|
|
@@ -520,7 +729,7 @@ export function dedupeAgainstCache(findings, cache, sessionId, filePath) {
|
|
|
520
729
|
const known = new Set(fileEntry.findings || []);
|
|
521
730
|
const fresh = [];
|
|
522
731
|
for (const f of findings) {
|
|
523
|
-
const key =
|
|
732
|
+
const key = findingCacheKey(f);
|
|
524
733
|
if (known.has(key)) continue;
|
|
525
734
|
known.add(key);
|
|
526
735
|
fresh.push(f);
|
|
@@ -531,11 +740,21 @@ export function dedupeAgainstCache(findings, cache, sessionId, filePath) {
|
|
|
531
740
|
export function rememberFindings(cache, sessionId, filePath, findings) {
|
|
532
741
|
const fileEntry = ensureFile(cache, sessionId, filePath);
|
|
533
742
|
const known = new Set(fileEntry.findings || []);
|
|
534
|
-
for (const f of findings) known.add(
|
|
743
|
+
for (const f of findings) known.add(findingCacheKey(f));
|
|
535
744
|
fileEntry.findings = Array.from(known);
|
|
536
745
|
ensureSession(cache, sessionId).updatedAt = Date.now();
|
|
537
746
|
}
|
|
538
747
|
|
|
748
|
+
function findingCacheKey(finding) {
|
|
749
|
+
const line = finding?.line || 0;
|
|
750
|
+
const value = extractFindingIgnoreValue(finding);
|
|
751
|
+
if (line > 0 && value) return `${finding.antipattern}:${line}:${value}`;
|
|
752
|
+
if (line > 0) return `${finding.antipattern}:${line}`;
|
|
753
|
+
if (value) return `${finding.antipattern}:0:${value}`;
|
|
754
|
+
const snippet = String(finding?.snippet || '').trim().slice(0, 80);
|
|
755
|
+
return snippet ? `${finding.antipattern}:0:${snippet}` : `${finding.antipattern}:0`;
|
|
756
|
+
}
|
|
757
|
+
|
|
539
758
|
export function renderTemplate(findings, filePath, config, opts = {}) {
|
|
540
759
|
if (!Array.isArray(findings) || findings.length === 0) return '';
|
|
541
760
|
const limits = config?.limits || DEFAULT_CONFIG.limits;
|
|
@@ -740,13 +959,114 @@ export function resolveTargetFiles(event, projectCwd) {
|
|
|
740
959
|
export function resolveHarness(env = {}, event = null) {
|
|
741
960
|
const explicit = env?.IMPECCABLE_HOOK_HARNESS;
|
|
742
961
|
if (explicit === 'cursor') return 'cursor';
|
|
962
|
+
if (explicit === 'github') return 'github';
|
|
743
963
|
if (explicit === 'claude' || explicit === 'codex') return 'claude';
|
|
964
|
+
// GitHub Copilot's postToolUse event uses camelCase `toolName`/`toolArgs` and
|
|
965
|
+
// has no `tool_name`/`tool_input`. That shape is the discriminator.
|
|
966
|
+
if (event && typeof event === 'object'
|
|
967
|
+
&& (typeof event.toolName === 'string' || event.toolArgs !== undefined)
|
|
968
|
+
&& event.tool_name === undefined && event.tool_input === undefined) {
|
|
969
|
+
return 'github';
|
|
970
|
+
}
|
|
744
971
|
if (typeof event?.conversation_id === 'string' && event.conversation_id) return 'cursor';
|
|
745
972
|
return 'claude';
|
|
746
973
|
}
|
|
747
974
|
|
|
975
|
+
// GitHub Copilot's postToolUse payload is
|
|
976
|
+
// { sessionId, timestamp, cwd, toolName, toolArgs, toolResult }
|
|
977
|
+
// mapped onto the internal `{ tool_name, tool_input, cwd, session_id }` shape.
|
|
978
|
+
// `toolArgs` shape depends on the tool: the `edit`/`create`/`view` tools send a
|
|
979
|
+
// JSON *string* (double-encoded) carrying the file under `path`, e.g.
|
|
980
|
+
// "{\"path\":\"/abs/app.tsx\",\"old_str\":\"...\",\"new_str\":\"...\"}",
|
|
981
|
+
// while `apply_patch` sends a raw OpenAI-format patch string (handled below in
|
|
982
|
+
// normalizeGitHubEvent). The detector reads the file from disk after the tool
|
|
983
|
+
// ran, so only the path (not the proposed content) is needed here.
|
|
984
|
+
export function parseGitHubToolArgs(toolArgs) {
|
|
985
|
+
if (toolArgs && typeof toolArgs === 'object' && !Array.isArray(toolArgs)) return toolArgs;
|
|
986
|
+
if (typeof toolArgs === 'string' && toolArgs.trim()) {
|
|
987
|
+
try {
|
|
988
|
+
const parsed = JSON.parse(toolArgs);
|
|
989
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
|
|
990
|
+
} catch {
|
|
991
|
+
return {};
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
return {};
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// Copilot's `apply_patch` tool (used by interactive sessions and the cloud
|
|
998
|
+
// agent) sends a raw OpenAI-format patch string in toolArgs, not JSON:
|
|
999
|
+
// *** Begin Patch
|
|
1000
|
+
// *** Add File: /abs/app.css
|
|
1001
|
+
// +body { ... }
|
|
1002
|
+
// *** End Patch
|
|
1003
|
+
// The `view`/`edit`/`create` tools (seen in `copilot -p` runs) instead send a
|
|
1004
|
+
// JSON string with the path under `path`. Both must map onto the internal shape.
|
|
1005
|
+
const APPLY_PATCH_MARKER = /\*\*\* (?:Begin Patch|Add File:|Update File:|Delete File:)/;
|
|
1006
|
+
|
|
1007
|
+
function looksLikeApplyPatch(rawArgs) {
|
|
1008
|
+
if (typeof rawArgs !== 'string' || !APPLY_PATCH_MARKER.test(rawArgs)) return false;
|
|
1009
|
+
// Guard against an edit/create payload whose edited *content* happens to
|
|
1010
|
+
// contain patch markers: that payload is a JSON object string, whereas a real
|
|
1011
|
+
// apply_patch payload is a raw patch string that does not parse as JSON. Only
|
|
1012
|
+
// treat non-JSON-object strings as apply_patch so edit events still get their
|
|
1013
|
+
// `path` extracted.
|
|
1014
|
+
try {
|
|
1015
|
+
const parsed = JSON.parse(rawArgs);
|
|
1016
|
+
if (parsed && typeof parsed === 'object') return false;
|
|
1017
|
+
} catch { /* not JSON → genuine raw patch */ }
|
|
1018
|
+
return true;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
function applyPatchText(rawArgs) {
|
|
1022
|
+
if (typeof rawArgs === 'string') {
|
|
1023
|
+
if (APPLY_PATCH_MARKER.test(rawArgs)) return rawArgs;
|
|
1024
|
+
// Defensive: a future Copilot build might JSON-wrap the patch.
|
|
1025
|
+
const parsed = parseGitHubToolArgs(rawArgs);
|
|
1026
|
+
return parsed.patch || parsed.input || parsed.command || '';
|
|
1027
|
+
}
|
|
1028
|
+
if (rawArgs && typeof rawArgs === 'object' && !Array.isArray(rawArgs)) {
|
|
1029
|
+
return rawArgs.patch || rawArgs.input || rawArgs.command || '';
|
|
1030
|
+
}
|
|
1031
|
+
return '';
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
function normalizeGitHubEvent(event, projectCwd) {
|
|
1035
|
+
const cwd = event.cwd || envProjectDir(projectCwd) || projectCwd;
|
|
1036
|
+
const sessionId = event.sessionId || event.session_id || 'unknown';
|
|
1037
|
+
const toolName = event.toolName || event.tool_name || null;
|
|
1038
|
+
const toolInput = event.tool_input && typeof event.tool_input === 'object' ? { ...event.tool_input } : {};
|
|
1039
|
+
const rawArgs = event.toolArgs;
|
|
1040
|
+
|
|
1041
|
+
let normalizedToolName = toolName;
|
|
1042
|
+
if (toolName === 'apply_patch' || looksLikeApplyPatch(rawArgs)) {
|
|
1043
|
+
// resolveTargetFiles() reads the touched paths from tool_input.command when
|
|
1044
|
+
// tool_name is 'apply_patch', so normalize the name even if a future build
|
|
1045
|
+
// sends the patch under a different tool label.
|
|
1046
|
+
const patch = applyPatchText(rawArgs);
|
|
1047
|
+
if (patch) {
|
|
1048
|
+
toolInput.command = patch;
|
|
1049
|
+
normalizedToolName = 'apply_patch';
|
|
1050
|
+
}
|
|
1051
|
+
} else {
|
|
1052
|
+
const args = parseGitHubToolArgs(rawArgs);
|
|
1053
|
+
const filePath = args.path || args.file_path || args.filePath || args.target_file;
|
|
1054
|
+
if (typeof filePath === 'string' && filePath) toolInput.file_path = filePath;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
return {
|
|
1058
|
+
...event,
|
|
1059
|
+
cwd,
|
|
1060
|
+
session_id: sessionId,
|
|
1061
|
+
tool_name: normalizedToolName,
|
|
1062
|
+
tool_input: toolInput,
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
|
|
748
1066
|
export function normalizeHookEvent(event, projectCwd, harness = 'claude') {
|
|
749
|
-
if (!event || typeof event !== 'object'
|
|
1067
|
+
if (!event || typeof event !== 'object') return event;
|
|
1068
|
+
if (harness === 'github') return normalizeGitHubEvent(event, projectCwd);
|
|
1069
|
+
if (harness !== 'cursor') return event;
|
|
750
1070
|
|
|
751
1071
|
const cwd = event.cwd
|
|
752
1072
|
|| (Array.isArray(event.workspace_roots) && event.workspace_roots[0])
|
|
@@ -942,7 +1262,11 @@ export async function loadDetector(candidates = DETECTOR_CANDIDATES) {
|
|
|
942
1262
|
const found = candidates.find((c) => fs.existsSync(c));
|
|
943
1263
|
if (!found) return null;
|
|
944
1264
|
const mod = await import(pathToFileURL(found));
|
|
945
|
-
detectorCache = {
|
|
1265
|
+
detectorCache = {
|
|
1266
|
+
detectText: mod.detectText,
|
|
1267
|
+
detectHtml: mod.detectHtml,
|
|
1268
|
+
loadDesignSystemForCwd: mod.loadDesignSystemForCwd,
|
|
1269
|
+
};
|
|
946
1270
|
return detectorCache;
|
|
947
1271
|
}
|
|
948
1272
|
|
|
@@ -977,12 +1301,12 @@ export function setDetectorForTesting(impl) {
|
|
|
977
1301
|
// session" so the model knows it's a re-mind, not a new finding.
|
|
978
1302
|
// ────────────────────────────────────────────────────────────────────────
|
|
979
1303
|
|
|
980
|
-
const STEER_LINE = '
|
|
1304
|
+
const STEER_LINE = 'That does not mean the design is good: keep following the project design system and the impeccable skill guidance.';
|
|
981
1305
|
|
|
982
1306
|
export function renderCleanAck(filePath, opts = {}) {
|
|
983
1307
|
const cwd = opts.cwd || process.cwd();
|
|
984
1308
|
const display = relativize(filePath, cwd);
|
|
985
|
-
return `${ENVELOPE_PREFIX} Design hook scanned ${display}. No
|
|
1309
|
+
return `${ENVELOPE_PREFIX} Design hook scanned ${display}. No deterministic design-quality issues found. ${STEER_LINE}`;
|
|
986
1310
|
}
|
|
987
1311
|
|
|
988
1312
|
export function renderPendingAck(filePath, knownFindings, opts = {}) {
|
|
@@ -999,6 +1323,22 @@ export function shouldEmitAckForFile(filePath) {
|
|
|
999
1323
|
return ACK_EXTS.has(path.extname(String(filePath || '')).toLowerCase());
|
|
1000
1324
|
}
|
|
1001
1325
|
|
|
1326
|
+
export function designSystemOptions(config, detector, projectCwd) {
|
|
1327
|
+
if (config?.designSystem?.enabled === false) return {};
|
|
1328
|
+
if (!detector || typeof detector.loadDesignSystemForCwd !== 'function') return {};
|
|
1329
|
+
try {
|
|
1330
|
+
const designSystem = detector.loadDesignSystemForCwd(projectCwd);
|
|
1331
|
+
return designSystem ? { designSystem } : {};
|
|
1332
|
+
} catch {
|
|
1333
|
+
return {};
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
export function appendDesignSystemNote(text, scanOptions) {
|
|
1338
|
+
if (!text || !scanOptions?.designSystem?.mdNewerThanJson) return text;
|
|
1339
|
+
return `${text}\n\n${ENVELOPE_PREFIX} DESIGN.md is newer than .impeccable/design.json. Run /impeccable document to refresh the design-system sidecar.`;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1002
1342
|
// The directive footer is the part of the hook output that steers model
|
|
1003
1343
|
// behavior. Three intentional moves:
|
|
1004
1344
|
// 1. **Imperative, not advisory.** "Handle these..." beats "Consider
|
|
@@ -1022,7 +1362,7 @@ function directiveFooter(display, opts = {}) {
|
|
|
1022
1362
|
'',
|
|
1023
1363
|
'Use context judgment before editing. A finding is not automatically a defect; literal or domain-appropriate motion, intentional demos or fixtures, documentation of bad design, and user-confirmed choices can be valid as-is.',
|
|
1024
1364
|
'',
|
|
1025
|
-
`Do not change intentional design just to satisfy the hook
|
|
1365
|
+
`Do not change intentional design just to satisfy the hook, and do not silence a real finding with an inline ignore comment to skip fixing it. Suppress a finding only after the user explicitly confirms it is intentional. Prefer a config ignore (one reviewable place, the commands below); reach for an inline \`impeccable-disable <rule>\` comment only when the waiver must travel with a file that leaves the repo, such as an exported or standalone document. Prefer the narrowest persisted exception: run the exact \`/impeccable hooks ignore-value ... --shared\` command shown next to a value-specific finding. For \`overused-font\`, use \`ignore-value\` for a specific font and use \`/impeccable hooks ignore-rule overused-font --all-values\` only when the user asks to ignore overused fonts generally. For file-specific findings without an ignore-value command, ${fileIgnoreGuidance}; use \`/impeccable hooks ignore-rule <id>\` only when the user asks to suppress the whole non-value-specific rule. Run /impeccable audit for the full pass.`,
|
|
1026
1366
|
].join('\n');
|
|
1027
1367
|
}
|
|
1028
1368
|
|
|
@@ -1086,6 +1426,7 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
|
|
|
1086
1426
|
persistCache(projectCwd, cache);
|
|
1087
1427
|
return result({ skipped: 'detector-missing', durationMs: Date.now() - started });
|
|
1088
1428
|
}
|
|
1429
|
+
const scanOptions = designSystemOptions(config, det, projectCwd);
|
|
1089
1430
|
|
|
1090
1431
|
let pendingWinner = null;
|
|
1091
1432
|
let cleanWinner = null;
|
|
@@ -1143,9 +1484,9 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
|
|
|
1143
1484
|
let findings;
|
|
1144
1485
|
let detectorThrew = false;
|
|
1145
1486
|
if ((ext === '.html' || ext === '.htm') && typeof det.detectHtml === 'function') {
|
|
1146
|
-
try { findings = await det.detectHtml(filePath); } catch { findings = []; detectorThrew = true; }
|
|
1487
|
+
try { findings = await det.detectHtml(filePath, scanOptions); } catch { findings = []; detectorThrew = true; }
|
|
1147
1488
|
} else {
|
|
1148
|
-
try { findings = await det.detectText(content, filePath); } catch { findings = []; detectorThrew = true; }
|
|
1489
|
+
try { findings = await det.detectText(content, filePath, scanOptions); } catch { findings = []; detectorThrew = true; }
|
|
1149
1490
|
}
|
|
1150
1491
|
|
|
1151
1492
|
const filtered = filterFindings(findings || [], content, ext, config);
|
|
@@ -1176,7 +1517,7 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
|
|
|
1176
1517
|
|
|
1177
1518
|
if (freshGroups.length > 0) {
|
|
1178
1519
|
const firstGroup = freshGroups[0];
|
|
1179
|
-
const text = renderGroupedTemplate(freshGroups, config, { cwd: projectCwd });
|
|
1520
|
+
const text = appendDesignSystemNote(renderGroupedTemplate(freshGroups, config, { cwd: projectCwd }), scanOptions);
|
|
1180
1521
|
const allFindings = freshGroups.flatMap((group) => group.findings);
|
|
1181
1522
|
return {
|
|
1182
1523
|
exitCode: 0,
|
|
@@ -1208,7 +1549,7 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
|
|
|
1208
1549
|
}
|
|
1209
1550
|
|
|
1210
1551
|
if (pendingWinner && shouldEmitAckForFile(pendingWinner.filePath)) {
|
|
1211
|
-
const text = renderPendingAck(pendingWinner.filePath, pendingWinner.known, { cwd: projectCwd });
|
|
1552
|
+
const text = appendDesignSystemNote(renderPendingAck(pendingWinner.filePath, pendingWinner.known, { cwd: projectCwd }), scanOptions);
|
|
1212
1553
|
return {
|
|
1213
1554
|
exitCode: 0,
|
|
1214
1555
|
stdout: payload(text, 'PostToolUse', harness),
|
|
@@ -1242,7 +1583,7 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
|
|
|
1242
1583
|
}
|
|
1243
1584
|
|
|
1244
1585
|
if (cleanWinner && shouldEmitAckForFile(cleanWinner.filePath)) {
|
|
1245
|
-
const text = renderCleanAck(cleanWinner.filePath, { cwd: projectCwd });
|
|
1586
|
+
const text = appendDesignSystemNote(renderCleanAck(cleanWinner.filePath, { cwd: projectCwd }), scanOptions);
|
|
1246
1587
|
return {
|
|
1247
1588
|
exitCode: 0,
|
|
1248
1589
|
stdout: payload(text, 'PostToolUse', harness),
|
|
@@ -1280,6 +1621,11 @@ export function payload(text, eventName = 'PostToolUse', harness = 'claude') {
|
|
|
1280
1621
|
if (harness === 'cursor') {
|
|
1281
1622
|
return JSON.stringify({ additional_context: text });
|
|
1282
1623
|
}
|
|
1624
|
+
// GitHub Copilot's postToolUse hook injects context via a top-level
|
|
1625
|
+
// `additionalContext` string (alongside an optional `modifiedResult`).
|
|
1626
|
+
if (harness === 'github') {
|
|
1627
|
+
return JSON.stringify({ additionalContext: text });
|
|
1628
|
+
}
|
|
1283
1629
|
return JSON.stringify({
|
|
1284
1630
|
hookSpecificOutput: { hookEventName: eventName, additionalContext: text },
|
|
1285
1631
|
});
|
|
@@ -62,7 +62,7 @@ function parseYamlSubset(yaml) {
|
|
|
62
62
|
stack.pop();
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
const key = content.slice(0, colonIdx).trim();
|
|
65
|
+
const key = unquoteYamlKey(content.slice(0, colonIdx).trim());
|
|
66
66
|
const rest = stripInlineYamlComment(content.slice(colonIdx + 1).trim());
|
|
67
67
|
const parent = stack[stack.length - 1].obj;
|
|
68
68
|
|
|
@@ -93,6 +93,13 @@ function findTopLevelColon(s) {
|
|
|
93
93
|
return -1;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
function unquoteYamlKey(key) {
|
|
97
|
+
if ((key.startsWith('"') && key.endsWith('"')) || (key.startsWith("'") && key.endsWith("'"))) {
|
|
98
|
+
return key.slice(1, -1);
|
|
99
|
+
}
|
|
100
|
+
return key;
|
|
101
|
+
}
|
|
102
|
+
|
|
96
103
|
function stripInlineYamlComment(s) {
|
|
97
104
|
let inQuote = null;
|
|
98
105
|
for (let i = 0; i < s.length; i++) {
|