pi-dev-team 0.2.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/LICENSE +21 -0
- package/PORTING.md +134 -0
- package/README.md +207 -0
- package/UPSTREAM.json +64 -0
- package/agents/Explore.md +15 -0
- package/agents/a11y-review.md +118 -0
- package/agents/adr-author.md +70 -0
- package/agents/ai-provenance-review.md +120 -0
- package/agents/angular-reactivity-review.md +95 -0
- package/agents/arch-review.md +135 -0
- package/agents/architect.md +78 -0
- package/agents/autoship-batch-proposer.md +69 -0
- package/agents/claude-setup-review.md +136 -0
- package/agents/codebase-recon.md +184 -0
- package/agents/component-architecture-review.md +119 -0
- package/agents/concurrency-review.md +109 -0
- package/agents/correctness-review.md +290 -0
- package/agents/data-flow-tracer.md +120 -0
- package/agents/doc-review.md +165 -0
- package/agents/domain-review.md +136 -0
- package/agents/general-purpose.md +10 -0
- package/agents/gherkin-quality-critic.md +113 -0
- package/agents/js-fp-review.md +114 -0
- package/agents/mutation-kill.md +684 -0
- package/agents/naming-review.md +142 -0
- package/agents/orchestrator.md +339 -0
- package/agents/performance-review.md +105 -0
- package/agents/plan-review-acceptance.md +115 -0
- package/agents/plan-review-design.md +90 -0
- package/agents/plan-review-parallelization.md +84 -0
- package/agents/plan-review-strategic.md +96 -0
- package/agents/plan-review-ux.md +110 -0
- package/agents/platform-engineer.md +64 -0
- package/agents/product-manager.md +68 -0
- package/agents/progress-guardian.md +79 -0
- package/agents/qa-engineer.md +289 -0
- package/agents/quality-reviewer.md +132 -0
- package/agents/react-reactivity-review.md +102 -0
- package/agents/refactor-opportunity-review.md +128 -0
- package/agents/security-engineer.md +60 -0
- package/agents/security-review.md +218 -0
- package/agents/session-analysis.md +95 -0
- package/agents/software-engineer.md +105 -0
- package/agents/spec-compliance-review.md +100 -0
- package/agents/spec-reviewer.md +114 -0
- package/agents/structure-review.md +146 -0
- package/agents/tech-writer.md +84 -0
- package/agents/test-review.md +246 -0
- package/agents/test-smell-review.md +188 -0
- package/agents/token-efficiency-review.md +139 -0
- package/agents/ui-ux-designer.md +54 -0
- package/agents/vue-reactivity-review.md +95 -0
- package/bin/__pycache__/claudecpython-314.pyc +0 -0
- package/bin/claude +258 -0
- package/docs/upstream/.pages +1 -0
- package/docs/upstream/CHANGELOG.md +2586 -0
- package/docs/upstream/README.md +155 -0
- package/docs/upstream/agent-architecture.md +214 -0
- package/docs/upstream/agent_info.md +187 -0
- package/docs/upstream/artifact-migration.md +124 -0
- package/docs/upstream/code-intelligence-nudge.md +149 -0
- package/docs/upstream/code-review-process.md +294 -0
- package/docs/upstream/concurrent-use.md +73 -0
- package/docs/upstream/context-management.md +111 -0
- package/docs/upstream/developer-notes.md +280 -0
- package/docs/upstream/diagrams/architecture-overview.svg +101 -0
- package/docs/upstream/diagrams/review-dispatch.svg +139 -0
- package/docs/upstream/diagrams/team-agents.svg +128 -0
- package/docs/upstream/diagrams/test-improve-flow.svg +166 -0
- package/docs/upstream/diagrams/workflow-linear.svg +66 -0
- package/docs/upstream/diagrams/workflow-three-phase.svg +200 -0
- package/docs/upstream/eval-maintenance.md +95 -0
- package/docs/upstream/eval-running-guide.md +147 -0
- package/docs/upstream/eval-system.md +291 -0
- package/docs/upstream/session-review-oss-complements.md +75 -0
- package/docs/upstream/session-review.md +212 -0
- package/docs/upstream/skills.md +188 -0
- package/docs/upstream/team-structure.md +21 -0
- package/docs/upstream/telemetry-ci-access.md +129 -0
- package/docs/upstream/telemetry-repo-security.md +120 -0
- package/docs/upstream/test-evaluation.md +277 -0
- package/docs/upstream/test-improve.md +154 -0
- package/docs/upstream/triage-workflow.md +282 -0
- package/docs/upstream/workflows.md +289 -0
- package/extensions/dev-team/index.ts +539 -0
- package/extensions/dev-team/lib/agents.ts +272 -0
- package/extensions/dev-team/lib/ai-credits.ts +92 -0
- package/extensions/dev-team/lib/autocompact.ts +81 -0
- package/extensions/dev-team/lib/child-run.ts +102 -0
- package/extensions/dev-team/lib/config.ts +236 -0
- package/extensions/dev-team/lib/gh-command.ts +103 -0
- package/extensions/dev-team/lib/github-style.ts +307 -0
- package/extensions/dev-team/lib/hooks.ts +350 -0
- package/extensions/dev-team/lib/metrics.ts +115 -0
- package/extensions/dev-team/lib/safe-read.ts +49 -0
- package/extensions/dev-team/lib/session-files.ts +57 -0
- package/extensions/dev-team/lib/session-spend.ts +123 -0
- package/extensions/dev-team/lib/shell-scan.ts +205 -0
- package/extensions/dev-team/lib/skills.ts +213 -0
- package/extensions/dev-team/lib/subagent-render.ts +245 -0
- package/extensions/dev-team/lib/subagent-types.ts +164 -0
- package/extensions/dev-team/lib/subagent.ts +596 -0
- package/extensions/dev-team/lib/terminal-text.ts +54 -0
- package/extensions/dev-team/lib/tools-misc.ts +152 -0
- package/extensions/dev-team/lib/transcript.ts +110 -0
- package/extensions/dev-team/lib/trust.ts +52 -0
- package/extensions/dev-team/lib/usage-breakdown.ts +176 -0
- package/extensions/dev-team/lib/usage-chart.ts +153 -0
- package/extensions/dev-team/lib/usage-command.ts +107 -0
- package/extensions/dev-team/lib/usage-history.ts +203 -0
- package/extensions/dev-team/lib/usage-render.ts +225 -0
- package/extensions/dev-team/lib/usage-split-bar.ts +127 -0
- package/extensions/dev-team/lib/usage-state.ts +116 -0
- package/extensions/dev-team/lib/usage-text.ts +159 -0
- package/extensions/dev-team/lib/usage-view.ts +109 -0
- package/hooks/__pycache__/refactor_test_freeze_guard.cpython-314.pyc +0 -0
- package/hooks/agent_dispatch_ledger.py +190 -0
- package/hooks/autocompact_setup_nudge.py +99 -0
- package/hooks/bash_retry_guard.py +228 -0
- package/hooks/boundary_events_write_guard.py +352 -0
- package/hooks/code_intelligence_nudge.py +293 -0
- package/hooks/code_intelligence_turn_mark.py +317 -0
- package/hooks/codegraph_bootstrap.py +139 -0
- package/hooks/contract_version_guard.py +362 -0
- package/hooks/cost_meter.py +106 -0
- package/hooks/destructive-commands.json +62 -0
- package/hooks/destructive_guard.py +477 -0
- package/hooks/eval_compliance_check.py +440 -0
- package/hooks/guards.json +17 -0
- package/hooks/hooks.json +323 -0
- package/hooks/internal_double_gate.py +296 -0
- package/hooks/js_fp_review.py +212 -0
- package/hooks/knowledge_index.py +119 -0
- package/hooks/lib/__pycache__/artifact_paths.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/atomic_state.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/autocompact_config.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/boundary_events.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/doc_classification.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/gh_pr_create_detect.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/git_safe_diff.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/instrument_log.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/metrics_query.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/plugin_version.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/pre_commit_doc_classifier.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/review_agent_registry.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/review_gate_corroboration.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/review_gate_hash.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/review_verdicts.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/stdin_json.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/stryker_invocation.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/telemetry_consent.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/test_file_classify.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/token_efficiency_limits.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/verify_guard_state.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/xunit_v3_operator_gate.cpython-314.pyc +0 -0
- package/hooks/lib/agent_skill_hints.py +74 -0
- package/hooks/lib/artifact_paths.py +263 -0
- package/hooks/lib/atomic_state.py +557 -0
- package/hooks/lib/autocompact_config.py +103 -0
- package/hooks/lib/autoship_log.py +106 -0
- package/hooks/lib/banned_scripts_policy.py +51 -0
- package/hooks/lib/boundary_events.py +436 -0
- package/hooks/lib/build_knowledge_index.py +504 -0
- package/hooks/lib/build_skills_index.py +361 -0
- package/hooks/lib/build_state.py +116 -0
- package/hooks/lib/classify_ship_outcome.py +126 -0
- package/hooks/lib/config_changelog_schema.py +115 -0
- package/hooks/lib/cost_meter.py +955 -0
- package/hooks/lib/doc_classification.py +116 -0
- package/hooks/lib/gh_pr_create_detect.py +136 -0
- package/hooks/lib/git_safe_diff.py +123 -0
- package/hooks/lib/instrument_log.py +66 -0
- package/hooks/lib/iteration_journal_gate.py +197 -0
- package/hooks/lib/knowledge_index_paths.py +88 -0
- package/hooks/lib/mcp_json_repowise.py +177 -0
- package/hooks/lib/metrics_query.py +202 -0
- package/hooks/lib/minimal_yaml.py +434 -0
- package/hooks/lib/plugin_version.py +142 -0
- package/hooks/lib/pre_commit_detect.py +537 -0
- package/hooks/lib/pre_commit_doc_classifier.py +126 -0
- package/hooks/lib/pricing.py +118 -0
- package/hooks/lib/report_pdf.py +371 -0
- package/hooks/lib/review_agent_registry.py +142 -0
- package/hooks/lib/review_dispatch_ledger.py +101 -0
- package/hooks/lib/review_gate_corroboration.py +521 -0
- package/hooks/lib/review_gate_hash.py +252 -0
- package/hooks/lib/review_gate_normalized_hash.py +1115 -0
- package/hooks/lib/review_verdicts.py +301 -0
- package/hooks/lib/run_report.py +160 -0
- package/hooks/lib/skill_categories.yaml +125 -0
- package/hooks/lib/stdin_json.py +57 -0
- package/hooks/lib/stryker_invocation.py +102 -0
- package/hooks/lib/telemetry_consent.py +41 -0
- package/hooks/lib/telemetry_report.py +108 -0
- package/hooks/lib/test_file_classify.py +160 -0
- package/hooks/lib/token_efficiency_limits.py +51 -0
- package/hooks/lib/turn_identity.py +77 -0
- package/hooks/lib/verify_guard_state.py +110 -0
- package/hooks/lib/workflow_state.py +206 -0
- package/hooks/lib/xunit_v3_operator_gate.py +596 -0
- package/hooks/mcp_json_repowise_nudge.py +74 -0
- package/hooks/mutation_adapters/__init__.py +7 -0
- package/hooks/mutation_adapters/__pycache__/__init__.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/lib.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/mutmut.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/pitest.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/stryker.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/stryker_net.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/lib.py +478 -0
- package/hooks/mutation_adapters/mutmut.py +188 -0
- package/hooks/mutation_adapters/pitest.py +266 -0
- package/hooks/mutation_adapters/stryker.py +157 -0
- package/hooks/mutation_adapters/stryker_net.py +264 -0
- package/hooks/mutation_gate.py +193 -0
- package/hooks/mutation_testing_smoke_gate.py +371 -0
- package/hooks/pending_review_notify.py +121 -0
- package/hooks/phase_marker.py +138 -0
- package/hooks/post_compact_state_reinject.py +180 -0
- package/hooks/post_format.py +115 -0
- package/hooks/pre_commit_knowledge_index.py +128 -0
- package/hooks/pre_commit_review.py +66 -0
- package/hooks/pre_pr_review.py +694 -0
- package/hooks/pre_tool_guard.py +405 -0
- package/hooks/py.sh +73 -0
- package/hooks/refactor-bash-write-patterns.json +29 -0
- package/hooks/refactor_test_bash_guard.py +253 -0
- package/hooks/refactor_test_freeze_guard.py +139 -0
- package/hooks/refactor_test_revert_guard.py +186 -0
- package/hooks/repo_review_nudge.py +287 -0
- package/hooks/review_verdict_recorder.py +464 -0
- package/hooks/scan_bash_command_for_banned_scripts.py +428 -0
- package/hooks/scan_worktree_for_banned_scripts.py +238 -0
- package/hooks/session_learning_trigger.py +248 -0
- package/hooks/skills_index.py +126 -0
- package/hooks/stryker_xunit_shim_guard.py +571 -0
- package/hooks/subagent_completion_guard.py +309 -0
- package/hooks/subagent_skill_context.py +139 -0
- package/hooks/task_completion_metrics.py +216 -0
- package/hooks/tdd_guard.py +229 -0
- package/hooks/telemetry.py +341 -0
- package/hooks/token_efficiency_review.py +194 -0
- package/hooks/verify_guard.py +183 -0
- package/hooks/verify_guard_edit_marker.py +73 -0
- package/hooks/version_check.py +173 -0
- package/knowledge/accepted-risks-schema.md +98 -0
- package/knowledge/adr-decision-criteria.md +64 -0
- package/knowledge/adversarial-review-protocol.md +139 -0
- package/knowledge/agent-registry.md +228 -0
- package/knowledge/agent-review-methodology.md +80 -0
- package/knowledge/ai-friendly-repo-guidelines.md +67 -0
- package/knowledge/architecture-assessment.md +96 -0
- package/knowledge/artifact-lifecycle.md +57 -0
- package/knowledge/cd-maturity-model.md +82 -0
- package/knowledge/cd-test-architecture.md +190 -0
- package/knowledge/ci-cd-file-scope.md +24 -0
- package/knowledge/codegraph-vs-graphify.md +192 -0
- package/knowledge/component-test-patterns.md +139 -0
- package/knowledge/database-change-management.md +80 -0
- package/knowledge/database-test-patterns.md +79 -0
- package/knowledge/decision-defaults.md +88 -0
- package/knowledge/dependency-breaking-techniques.md +116 -0
- package/knowledge/deployment-pipeline.md +86 -0
- package/knowledge/design-smells.md +122 -0
- package/knowledge/directory-enumeration.md +38 -0
- package/knowledge/domain-modeling.md +123 -0
- package/knowledge/evidence-bundle.md +90 -0
- package/knowledge/exploratory-testing-field-guide.md +122 -0
- package/knowledge/failure-routing.md +28 -0
- package/knowledge/fixture-construction.md +56 -0
- package/knowledge/frontend-component-architecture.md +139 -0
- package/knowledge/gherkin-quality-review-dispatch.md +135 -0
- package/knowledge/index.json +6766 -0
- package/knowledge/internal-collaborator-doubling.md +101 -0
- package/knowledge/legacy-test-strategy.md +71 -0
- package/knowledge/long-run-waiting.md +66 -0
- package/knowledge/microservice-testing.md +71 -0
- package/knowledge/model-pricing.json +23 -0
- package/knowledge/mutation-score-formulas.md +60 -0
- package/knowledge/object-calisthenics.md +147 -0
- package/knowledge/oracle-provenance.md +94 -0
- package/knowledge/orchestrator-script-implementation.md +185 -0
- package/knowledge/owasp-detection.md +148 -0
- package/knowledge/plan-review-rubric.md +56 -0
- package/knowledge/proxy-connectivity.md +62 -0
- package/knowledge/reactive-effect-patterns.md +73 -0
- package/knowledge/recon-inventory-excludes.txt +32 -0
- package/knowledge/references/bdd-value-guide.md +61 -0
- package/knowledge/references/csharp-http-client-testing.md +264 -0
- package/knowledge/release-strategies.md +74 -0
- package/knowledge/report-output-location.md +117 -0
- package/knowledge/report-pdf-integration.md +63 -0
- package/knowledge/report-print.css +129 -0
- package/knowledge/report-template.md +114 -0
- package/knowledge/report-to-pdf.md +69 -0
- package/knowledge/request-processing-flow.md +63 -0
- package/knowledge/result-verification.md +52 -0
- package/knowledge/review-agent-output-contract.md +121 -0
- package/knowledge/review-lens-classification.md +113 -0
- package/knowledge/review-rubric.md +62 -0
- package/knowledge/review-template.md +104 -0
- package/knowledge/rule-fixtures/A02.insecure-random-js/negative.js +1 -0
- package/knowledge/rule-fixtures/A02.insecure-random-js/positive.js +1 -0
- package/knowledge/rule-fixtures/A02.weak-hashing-md5/negative.py +1 -0
- package/knowledge/rule-fixtures/A02.weak-hashing-md5/positive.py +1 -0
- package/knowledge/rule-fixtures/A03.command-injection/negative.js +1 -0
- package/knowledge/rule-fixtures/A03.command-injection/positive.js +1 -0
- package/knowledge/rule-fixtures/A03.sql-injection/negative.js +1 -0
- package/knowledge/rule-fixtures/A03.sql-injection/positive.js +1 -0
- package/knowledge/rule-fixtures/A03.xss-innerhtml/negative.js +1 -0
- package/knowledge/rule-fixtures/A03.xss-innerhtml/positive.js +1 -0
- package/knowledge/rule-fixtures/A05.cors-wildcard/negative.js +1 -0
- package/knowledge/rule-fixtures/A05.cors-wildcard/positive.js +1 -0
- package/knowledge/rule-fixtures/A05.default-credentials/negative.js +1 -0
- package/knowledge/rule-fixtures/A05.default-credentials/positive.js +1 -0
- package/knowledge/rule-fixtures/A07.jwt-alg-none/negative.js +1 -0
- package/knowledge/rule-fixtures/A07.jwt-alg-none/positive.js +1 -0
- package/knowledge/rule-fixtures/A08.binary-formatter/negative.cs +1 -0
- package/knowledge/rule-fixtures/A08.binary-formatter/positive.cs +1 -0
- package/knowledge/rule-fixtures/A08.js-eval/negative.js +1 -0
- package/knowledge/rule-fixtures/A08.js-eval/positive.js +1 -0
- package/knowledge/rule-fixtures/A08.object-input-stream/negative.java +1 -0
- package/knowledge/rule-fixtures/A08.object-input-stream/positive.java +1 -0
- package/knowledge/schemas/disposition-register-v1.json +65 -0
- package/knowledge/schemas/recon-envelope-v1.json +198 -0
- package/knowledge/schemas/unified-finding-v1.json +72 -0
- package/knowledge/security-primitives-contract.md +301 -0
- package/knowledge/security-review-rule-map.yaml +107 -0
- package/knowledge/skills-registry.md +72 -0
- package/knowledge/task-size-classifier.md +103 -0
- package/knowledge/telemetry-schema.md +881 -0
- package/knowledge/test-automation-maturity.md +56 -0
- package/knowledge/test-automation-principles.md +71 -0
- package/knowledge/test-cadence-tradeoffs.md +68 -0
- package/knowledge/test-doubles.md +105 -0
- package/knowledge/test-file-indicators.md +22 -0
- package/knowledge/test-layer-gates.md +35 -0
- package/knowledge/test-matrix-examples/django-batch.md +24 -0
- package/knowledge/test-matrix-examples/dotnet-grpc-fronting-api.md +90 -0
- package/knowledge/test-matrix-examples/dotnet-http-consumer.md +131 -0
- package/knowledge/test-matrix-examples/react-node-spa.md +24 -0
- package/knowledge/test-matrix-examples/spring-boot-service.md +25 -0
- package/knowledge/test-matrix-examples/ssr-htmx.md +24 -0
- package/knowledge/test-organization.md +70 -0
- package/knowledge/test-pyramid.md +84 -0
- package/knowledge/test-refactoring.md +67 -0
- package/knowledge/test-review-division-of-labor.md +85 -0
- package/knowledge/test-smells.md +80 -0
- package/knowledge/test-stack-profiles/bdd-frameworks.md +235 -0
- package/knowledge/test-stack-profiles/django.md +13 -0
- package/knowledge/test-stack-profiles/dotnet.md +18 -0
- package/knowledge/test-stack-profiles/go.md +16 -0
- package/knowledge/test-stack-profiles/node.md +16 -0
- package/knowledge/test-stack-profiles/react.md +12 -0
- package/knowledge/test-stack-profiles/spring-boot.md +16 -0
- package/knowledge/test-stack-profiles/ssr-htmx.md +14 -0
- package/knowledge/test-stack-profiles/vue.md +12 -0
- package/knowledge/test-strategy.md +70 -0
- package/knowledge/testability-patterns.md +240 -0
- package/knowledge/testing-quadrants.md +44 -0
- package/knowledge/testing-techniques/approval.md +15 -0
- package/knowledge/testing-techniques/chaos.md +17 -0
- package/knowledge/testing-techniques/fuzz.md +15 -0
- package/knowledge/testing-techniques/property-based.md +15 -0
- package/knowledge/testing-techniques/schema-validation.md +15 -0
- package/knowledge/testing-techniques/screenshot.md +15 -0
- package/knowledge/three-phase-workflow.md +198 -0
- package/knowledge/value-patterns.md +55 -0
- package/knowledge/verification-mode.md +116 -0
- package/knowledge/virtual-service-libraries.md +75 -0
- package/knowledge/wave-consolidation-guidance.md +21 -0
- package/overrides/agents/Explore.md +15 -0
- package/overrides/agents/general-purpose.md +10 -0
- package/overrides/notes/autoship.md +6 -0
- package/overrides/notes/issues-from-assessment.md +3 -0
- package/overrides/notes/issues-from-plan.md +3 -0
- package/overrides/notes/mutation-night-watch.md +3 -0
- package/overrides/notes/mutation-testing.md +3 -0
- package/overrides/notes/pr.md +7 -0
- package/overrides/notes/project-init.md +6 -0
- package/overrides/notes/setup.md +13 -0
- package/overrides/notes/specs.md +3 -0
- package/overrides/skills/headless-run/SKILL.md +45 -0
- package/overrides/skills/upgrade/SKILL.md +30 -0
- package/overrides/skills/version/SKILL.md +25 -0
- package/package.json +36 -0
- package/scripts/authoring_digest.py +93 -0
- package/scripts/autoship_discover.py +121 -0
- package/scripts/autoship_group.py +409 -0
- package/scripts/autoship_proposals.py +494 -0
- package/scripts/autoship_queue.py +291 -0
- package/scripts/autoship_reclaim.py +495 -0
- package/scripts/build_jobs.py +108 -0
- package/scripts/build_rollback_point.py +240 -0
- package/scripts/build_slice_scope.py +157 -0
- package/scripts/build_wave.py +109 -0
- package/scripts/build_wave_reconcile.py +252 -0
- package/scripts/build_worktree_baseref.py +113 -0
- package/scripts/check_agent_scope.py +117 -0
- package/scripts/check_agent_tool_mapping.py +213 -0
- package/scripts/check_review_agent_mcp_tools.py +317 -0
- package/scripts/check_security_assessment_mcp_tools.py +165 -0
- package/scripts/checkpoint_abort.py +502 -0
- package/scripts/claude_setup_review.py +438 -0
- package/scripts/codebase_recon.py +556 -0
- package/scripts/coverage_config.py +623 -0
- package/scripts/coverage_delta_steering.py +330 -0
- package/scripts/coverage_discovery_dotnet.py +315 -0
- package/scripts/coverage_discovery_java.py +742 -0
- package/scripts/coverage_discovery_js.py +546 -0
- package/scripts/coverage_gap_ranking.py +556 -0
- package/scripts/coverage_readiness.py +455 -0
- package/scripts/coverage_report_parse.py +521 -0
- package/scripts/detect_bdd_convention.py +252 -0
- package/scripts/eval_ablation.py +376 -0
- package/scripts/gherkin_analysis_coverage_gate.py +306 -0
- package/scripts/gherkin_cross_feature_duplicate_titles_gate.py +173 -0
- package/scripts/gherkin_effectiveness_rollup.py +238 -0
- package/scripts/gherkin_failure_path_gate.py +206 -0
- package/scripts/gherkin_feature_merge.py +720 -0
- package/scripts/gherkin_stub_gate.py +163 -0
- package/scripts/gherkin_stub_merge.py +479 -0
- package/scripts/git_origin_host.py +88 -0
- package/scripts/install-java-static-analysis.py +110 -0
- package/scripts/issue_deps.py +74 -0
- package/scripts/lib/_bdd_markers.py +28 -0
- package/scripts/lib/_gherkin_text.py +93 -0
- package/scripts/lib/_vendored_tree.py +70 -0
- package/scripts/lib/autoship_state.py +397 -0
- package/scripts/lib/claude_md_guard.py +226 -0
- package/scripts/lib/deterministic_recon.py +446 -0
- package/scripts/lib/mcp_tool_grants.py +211 -0
- package/scripts/lib/plan_parse.py +386 -0
- package/scripts/lib/review_result.py +84 -0
- package/scripts/lib/review_roster.py +86 -0
- package/scripts/lib/session_log/__init__.py +34 -0
- package/scripts/lib/session_log/__pycache__/__init__.cpython-314.pyc +0 -0
- package/scripts/lib/session_log/__pycache__/records.cpython-314.pyc +0 -0
- package/scripts/lib/session_log/classify.py +231 -0
- package/scripts/lib/session_log/corrections.py +194 -0
- package/scripts/lib/session_log/discovery.py +108 -0
- package/scripts/lib/session_log/records.py +218 -0
- package/scripts/lib/session_log/redact.py +76 -0
- package/scripts/lib/session_log/signals.py +373 -0
- package/scripts/lib/session_report_downstream.py +614 -0
- package/scripts/lib/session_report_maintainer.py +1273 -0
- package/scripts/lib/session_report_shared.py +262 -0
- package/scripts/lib/settings_hook_guard.py +157 -0
- package/scripts/lib/slug.py +33 -0
- package/scripts/lib/stub_extractors/__init__.py +82 -0
- package/scripts/lib/stub_extractors/_common.py +328 -0
- package/scripts/lib/stub_extractors/csharp.py +19 -0
- package/scripts/lib/stub_extractors/go.py +173 -0
- package/scripts/lib/stub_extractors/java.py +18 -0
- package/scripts/lib/stub_extractors/jsts.py +126 -0
- package/scripts/mutation_stack_sections.py +149 -0
- package/scripts/mutation_yield_steering.py +345 -0
- package/scripts/orchestrator.py +895 -0
- package/scripts/plan_gherkin_export.py +227 -0
- package/scripts/plan_waves.py +208 -0
- package/scripts/pr_close_keyword_lint.py +108 -0
- package/scripts/progress_guardian.py +888 -0
- package/scripts/recon_inventory.py +273 -0
- package/scripts/review_findings_log.py +93 -0
- package/scripts/run_invariants.py +124 -0
- package/scripts/select_lenses.py +640 -0
- package/scripts/session_report.py +486 -0
- package/scripts/set_autocompact_env.py +221 -0
- package/scripts/ship_resume_guard.py +135 -0
- package/scripts/ship_review_gate.py +63 -0
- package/scripts/specs_convention_marker.py +103 -0
- package/scripts/test_improve_resume.py +277 -0
- package/scripts/test_review_mechanics.py +958 -0
- package/scripts/token_efficiency_review.py +322 -0
- package/scripts/verdict_scope.py +285 -0
- package/scripts/verify_gherkin_quality_critic_isolation.py +296 -0
- package/scripts/verify_tier.py +157 -0
- package/skills/adr-tools/SKILL.md +118 -0
- package/skills/agent-readiness/SKILL.md +105 -0
- package/skills/agent-readiness/ai_friendly_analyzers.py +326 -0
- package/skills/agent-readiness/scanner.py +441 -0
- package/skills/agent-readiness/scorecard.yaml +88 -0
- package/skills/api-design/SKILL.md +115 -0
- package/skills/apply-fixes/SKILL.md +171 -0
- package/skills/apply-test-doubles/SKILL.md +321 -0
- package/skills/artifact-lifecycle/SKILL.md +127 -0
- package/skills/autoship/SKILL.md +1124 -0
- package/skills/benchmark/SKILL.md +105 -0
- package/skills/branch-workflow/SKILL.md +89 -0
- package/skills/browse/SKILL.md +184 -0
- package/skills/browser-testing/SKILL.md +62 -0
- package/skills/browser-testing/references/playwright-patterns.md +216 -0
- package/skills/build/SKILL.md +422 -0
- package/skills/build/references/static-self-heal.md +245 -0
- package/skills/careful/SKILL.md +72 -0
- package/skills/cd-test-architecture/SKILL.md +371 -0
- package/skills/ci-debugging/SKILL.md +105 -0
- package/skills/co-evolution-audit/SKILL.md +269 -0
- package/skills/code-review/SKILL.md +1015 -0
- package/skills/code-review/examples/aggregated-sample.json +56 -0
- package/skills/code-review/examples/sample-report.md +41 -0
- package/skills/code-review/output-format.md +478 -0
- package/skills/code-review/scripts/activation.py +86 -0
- package/skills/code-review/scripts/change_impact.py +357 -0
- package/skills/code-review/scripts/change_shape.py +372 -0
- package/skills/code-review/scripts/change_size.py +212 -0
- package/skills/code-review/scripts/changed_file_list.py +141 -0
- package/skills/code-review/scripts/closing_pass.py +187 -0
- package/skills/code-review/scripts/consolidate.py +277 -0
- package/skills/code-review/scripts/contract_failure_report.py +185 -0
- package/skills/code-review/scripts/dispatch_reconcile.py +66 -0
- package/skills/code-review/scripts/dispatch_waves.py +164 -0
- package/skills/code-review/scripts/finding_signature.py +446 -0
- package/skills/code-review/scripts/ledger.py +283 -0
- package/skills/code-review/scripts/partition.py +169 -0
- package/skills/code-review/scripts/render_tiered_findings.py +274 -0
- package/skills/code-review/scripts/repo_invariants.py +1066 -0
- package/skills/code-review/scripts/review_context_pack.py +306 -0
- package/skills/code-review/scripts/review_round_log.py +345 -0
- package/skills/code-review/scripts/review_value_coverage.py +297 -0
- package/skills/code-review/scripts/validate_review_output.py +467 -0
- package/skills/code-review/sliced-mode.md +205 -0
- package/skills/competitive-analysis/SKILL.md +191 -0
- package/skills/context-loading-protocol/SKILL.md +157 -0
- package/skills/continue/SKILL.md +90 -0
- package/skills/cost-report/SKILL.md +178 -0
- package/skills/coverage-baseline/SKILL.md +335 -0
- package/skills/coverage-baseline/references/multi-project-discovery.md +202 -0
- package/skills/coverage-delta/SKILL.md +181 -0
- package/skills/coverage-delta/references/mutation-gate.md +70 -0
- package/skills/design-doc/SKILL.md +95 -0
- package/skills/design-interrogation/SKILL.md +89 -0
- package/skills/design-it-twice/SKILL.md +91 -0
- package/skills/docker-image-audit/SKILL.md +108 -0
- package/skills/docker-image-audit/references/install-guide.md +64 -0
- package/skills/docker-image-audit/references/report-template.md +73 -0
- package/skills/docker-image-create/SKILL.md +185 -0
- package/skills/domain-analysis/SKILL.md +183 -0
- package/skills/domain-driven-design/SKILL.md +194 -0
- package/skills/exploratory-testing/SKILL.md +108 -0
- package/skills/explore/SKILL.md +51 -0
- package/skills/farley-score/SKILL.md +165 -0
- package/skills/feature-file-validation/SKILL.md +78 -0
- package/skills/feature-file-validation/references/validation-rules.md +115 -0
- package/skills/feedback-learning/SKILL.md +414 -0
- package/skills/fix/SKILL.md +450 -0
- package/skills/freeze/SKILL.md +68 -0
- package/skills/frontend-architecture/SKILL.md +113 -0
- package/skills/gherkin-derive/SKILL.md +630 -0
- package/skills/gherkin-public/SKILL.md +266 -0
- package/skills/governance-compliance/SKILL.md +150 -0
- package/skills/guard/SKILL.md +75 -0
- package/skills/handoff/SKILL.md +139 -0
- package/skills/handoff/references/summary-templates.md +242 -0
- package/skills/harness-audit/SKILL.md +751 -0
- package/skills/harness-audit/scripts/lesson_validate.py +386 -0
- package/skills/harness-audit/scripts/redundancy_criterion.py +188 -0
- package/skills/headless-run/SKILL.md +45 -0
- package/skills/headless-run/scripts/isolated_dispatch.py +381 -0
- package/skills/help/SKILL.md +72 -0
- package/skills/hexagonal-architecture/SKILL.md +85 -0
- package/skills/human-oversight-protocol/SKILL.md +224 -0
- package/skills/issues-from-assessment/SKILL.md +223 -0
- package/skills/issues-from-plan/SKILL.md +133 -0
- package/skills/legacy-code/SKILL.md +132 -0
- package/skills/mermaid-diagramming/SKILL.md +120 -0
- package/skills/mutation-night-watch/SKILL.md +154 -0
- package/skills/mutation-night-watch/references/scheduling.md +135 -0
- package/skills/mutation-testing/SKILL.md +396 -0
- package/skills/mutation-testing/references/languages/csharp-stryker-net.md +676 -0
- package/skills/mutation-testing/references/languages/go-go-mutesting.md +95 -0
- package/skills/mutation-testing/references/languages/java-pitest.md +77 -0
- package/skills/mutation-testing/references/languages/javascript-stryker.md +188 -0
- package/skills/mutation-testing/references/languages/python-mutmut.md +97 -0
- package/skills/mutation-testing/references/time-estimation.md +34 -0
- package/skills/mutation-testing/references/tool-detection.md +15 -0
- package/skills/mutation-testing/references/workflow-callers.md +23 -0
- package/skills/mutation-testing/scripts/__pycache__/xunit_v3_feature_detector.cpython-314.pyc +0 -0
- package/skills/mutation-testing/scripts/csharp_stryker_net_slice_runner.py +635 -0
- package/skills/mutation-testing/scripts/csharp_stryker_net_status_loop.py +525 -0
- package/skills/mutation-testing/scripts/csharp_stryker_net_wrapper.py +681 -0
- package/skills/mutation-testing/scripts/mutation_baseline_reuse.py +292 -0
- package/skills/mutation-testing/scripts/mutation_exclude_policy.py +268 -0
- package/skills/mutation-testing/scripts/mutation_feasibility_gate.py +463 -0
- package/skills/mutation-testing/scripts/mutation_kill_headless.py +331 -0
- package/skills/mutation-testing/scripts/mutation_kill_insert.py +199 -0
- package/skills/mutation-testing/scripts/mutation_kill_insert_python.py +150 -0
- package/skills/mutation-testing/scripts/mutation_kill_loop.py +869 -0
- package/skills/mutation-testing/scripts/mutation_kill_loop_python.py +949 -0
- package/skills/mutation-testing/scripts/mutation_kill_retry.py +592 -0
- package/skills/mutation-testing/scripts/mutation_kill_shared.py +620 -0
- package/skills/mutation-testing/scripts/mutation_nightwatch.py +462 -0
- package/skills/mutation-testing/scripts/mutation_nightwatch_stacks.py +425 -0
- package/skills/mutation-testing/scripts/mutation_report.py +743 -0
- package/skills/mutation-testing/scripts/mutation_report_cli.py +175 -0
- package/skills/mutation-testing/scripts/mutation_safety_gate.py +69 -0
- package/skills/mutation-testing/scripts/stryker_shard_pipeline.py +847 -0
- package/skills/mutation-testing/scripts/stryker_shard_setup.py +440 -0
- package/skills/mutation-testing/scripts/stryker_timeout_retry.py +142 -0
- package/skills/mutation-testing/scripts/xunit_v3_feature_detector.py +341 -0
- package/skills/performance-benchmark/SKILL.md +174 -0
- package/skills/performance-benchmark/examples/report-format.md +43 -0
- package/skills/performance-benchmark/references/benchmark-script.md +169 -0
- package/skills/performance-metrics/SKILL.md +265 -0
- package/skills/plan/SKILL.md +199 -0
- package/skills/plan/references/gherkin-persistence.md +43 -0
- package/skills/plan/references/plan-template.md +182 -0
- package/skills/pr/SKILL.md +289 -0
- package/skills/pr/scripts/gate_retry_state.py +368 -0
- package/skills/project-init/README.md +141 -0
- package/skills/project-init/SKILL.md +1197 -0
- package/skills/project-init/evals/evals.json +200 -0
- package/skills/project-init/references/capability-tools.md +55 -0
- package/skills/project-init/references/configs.md +221 -0
- package/skills/property-based-testing/SKILL.md +121 -0
- package/skills/property-based-testing/fixtures/invariant_fixture.py +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/README.md +42 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/LICENSE +21 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/README.md +263 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/fast-check.d.ts +5165 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/fast-check.js +12147 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/package.json +3 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/types57/fast-check.d.ts +5165 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/fast-check.d.ts +5165 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/fast-check.js +12011 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/rolldown-runtime-D7D4PA-g.js +13 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/types57/fast-check.d.ts +5165 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/package.json +94 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/LICENSE +21 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/README.md +168 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/RandomGenerator-DcXj09Ch.d.ts +14 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformBigInt.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformBigInt.js +38 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat32.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat32.js +18 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat64.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat64.js +22 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformInt.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformInt.js +134 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/RandomGenerator-DcXj09Ch.d.ts +14 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformBigInt.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformBigInt.js +37 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat32.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat32.js +17 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat64.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat64.js +21 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformInt.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformInt.js +133 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/congruential32.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/congruential32.js +44 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/mersenne.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/mersenne.js +90 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xoroshiro128plus.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xoroshiro128plus.js +80 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xorshift128plus.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xorshift128plus.js +78 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/package.json +3 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/JumpableRandomGenerator.d.ts +16 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/JumpableRandomGenerator.js +0 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/RandomGenerator.d.ts +2 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/RandomGenerator.js +0 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/generateN.d.ts +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/generateN.js +8 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/purify.d.ts +12 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/purify.js +9 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/skipN.d.ts +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/skipN.js +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/congruential32.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/congruential32.js +46 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/mersenne.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/mersenne.js +92 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xoroshiro128plus.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xoroshiro128plus.js +82 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xorshift128plus.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xorshift128plus.js +80 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/JumpableRandomGenerator.d.ts +16 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/JumpableRandomGenerator.js +0 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/RandomGenerator.d.ts +2 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/RandomGenerator.js +0 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/generateN.d.ts +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/generateN.js +9 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/purify.d.ts +12 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/purify.js +10 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/skipN.d.ts +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/skipN.js +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/package.json +133 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/package-lock.json +1179 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/package.json +14 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/roundtrip.js +29 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/roundtrip.properties.test.js +16 -0
- package/skills/property-based-testing/fixtures/no_property_fixture.py +10 -0
- package/skills/property-based-testing/fixtures/roundtrip_fixture.py +16 -0
- package/skills/property-based-testing/references/languages/javascript.md +54 -0
- package/skills/property-based-testing/scripts/detect_and_dispatch.py +80 -0
- package/skills/property-based-testing/scripts/hypothesis_scaffold.py +276 -0
- package/skills/proxy-resilience/SKILL.md +84 -0
- package/skills/quality-gate-pipeline/SKILL.md +184 -0
- package/skills/quality-targets-converge/SKILL.md +254 -0
- package/skills/repo-review/SKILL.md +159 -0
- package/skills/report-pdf/SKILL.md +66 -0
- package/skills/review/SKILL.md +47 -0
- package/skills/review-agent/SKILL.md +152 -0
- package/skills/review-summary/SKILL.md +73 -0
- package/skills/run-report/SKILL.md +70 -0
- package/skills/semantic-duplication-scan/SKILL.md +337 -0
- package/skills/semantic-scan/SKILL.md +53 -0
- package/skills/semgrep-analyze/SKILL.md +139 -0
- package/skills/setup/SKILL.md +1122 -0
- package/skills/ship/SKILL.md +240 -0
- package/skills/source-verification/SKILL.md +210 -0
- package/skills/source-verification/scripts/claim_extractor.py +155 -0
- package/skills/specs/.size-baseline.json +4 -0
- package/skills/specs/SKILL.md +243 -0
- package/skills/specs/references/completeness-checklist.md +83 -0
- package/skills/specs/references/extraction.md +58 -0
- package/skills/specs/references/glossary.md +59 -0
- package/skills/specs/references/persistence.md +115 -0
- package/skills/specs/references/predictability-check.md +77 -0
- package/skills/static-analysis-integration/SKILL.md +235 -0
- package/skills/static-analysis-integration/adapters/_envelope.py +26 -0
- package/skills/static-analysis-integration/adapters/jscpd-adapter.py +66 -0
- package/skills/static-analysis-integration/adapters/lizard-adapter.py +81 -0
- package/skills/static-analysis-integration/adapters/mypy-adapter.py +50 -0
- package/skills/static-analysis-integration/adapters/mypy-src-layout.py +93 -0
- package/skills/static-analysis-integration/adapters/security-review-adapter.py +212 -0
- package/skills/static-analysis-integration/maintenance.md +23 -0
- package/skills/static-analysis-integration/references/language-setup.md +228 -0
- package/skills/static-analysis-integration/references/sarif-parser.md +124 -0
- package/skills/static-analysis-integration/references/security-review-adapter.md +118 -0
- package/skills/static-analysis-integration/references/tool-configs.md +617 -0
- package/skills/static-analysis-integration/rulesets/pmd-quickstart.xml +24 -0
- package/skills/stryker-xunit-v2-shim/SKILL.md +274 -0
- package/skills/stryker-xunit-v2-shim/references/shim-howto.md +256 -0
- package/skills/stryker-xunit-v2-shim/scripts/generate_shim.py +143 -0
- package/skills/systematic-debugging/SKILL.md +130 -0
- package/skills/telemetry/SKILL.md +75 -0
- package/skills/test-audit-disable/SKILL.md +129 -0
- package/skills/test-design/SKILL.md +177 -0
- package/skills/test-design/scripts/__pycache__/internal_double_detector.cpython-314.pyc +0 -0
- package/skills/test-design/scripts/internal_double_detector.py +631 -0
- package/skills/test-design-advisor/SKILL.md +166 -0
- package/skills/test-driven-development/SKILL.md +169 -0
- package/skills/test-health/SKILL.md +262 -0
- package/skills/test-improve/SKILL.md +239 -0
- package/skills/test-improve/references/phase-0-approach-contract.md +228 -0
- package/skills/test-improve/references/phase-1-analyze.md +131 -0
- package/skills/test-improve/references/phase-2-baseline.md +121 -0
- package/skills/test-improve/references/phase-3-derive-gherkin.md +53 -0
- package/skills/test-improve/references/phase-4-plan-fixes.md +34 -0
- package/skills/test-improve/references/phase-5-improve.md +215 -0
- package/skills/test-improve/references/phase-6-refactor-decision.md +45 -0
- package/skills/test-improve/references/phase-7-refactor.md +44 -0
- package/skills/test-improve/references/phase-8-validate.md +66 -0
- package/skills/test-improve/references/phase-9-close-out-prompt.md +11 -0
- package/skills/test-improve/references/phase-9-report.md +62 -0
- package/skills/test-improve/references/review-loop.md +92 -0
- package/skills/test-improve/templates/executive-summary.md +123 -0
- package/skills/threat-modeling/SKILL.md +108 -0
- package/skills/triage/SKILL.md +211 -0
- package/skills/ubiquitous-language/SKILL.md +192 -0
- package/skills/ubiquitous-language/scripts/collect_domain_signals.py +300 -0
- package/skills/unfreeze/SKILL.md +37 -0
- package/skills/upgrade/SKILL.md +31 -0
- package/skills/upgrade/scripts/check_version_drift.py +113 -0
- package/skills/upgrade/scripts/enable_autoupdate.py +149 -0
- package/skills/version/SKILL.md +25 -0
- package/sync/__pycache__/sync_upstream.cpython-314.pyc +0 -0
- package/sync/sync_upstream.py +293 -0
- package/templates/ACCEPTED-RISKS.md.tmpl +46 -0
- package/templates/agents/agent-template.md +151 -0
- package/templates/agents/angular-testing.md +66 -0
- package/templates/agents/csharp-quality.md +63 -0
- package/templates/agents/esm-enforcer.md +52 -0
- package/templates/agents/front-end-testing.md +65 -0
- package/templates/agents/go-quality.md +65 -0
- package/templates/agents/python-quality.md +62 -0
- package/templates/agents/react-testing.md +61 -0
- package/templates/agents/ts-enforcer.md +60 -0
- package/templates/agents/twelve-factor-audit.md +49 -0
- package/tools/entropy-check.py +250 -0
- package/tools/model-hash-verify.py +213 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""phase_marker — PostToolUse:Skill hook (issue #1520).
|
|
3
|
+
|
|
4
|
+
A phase boundary in the three-phase workflow is where the orchestrator
|
|
5
|
+
compacts context before the next phase — i.e. where `/handoff` (continue
|
|
6
|
+
mode) runs. This hook fires on every Skill invocation, filters to `handoff`,
|
|
7
|
+
and records a context-pollution marker via `hooks/lib/cost_meter.py
|
|
8
|
+
phase-mark`: the main-loop resident context occupancy at the boundary and the
|
|
9
|
+
cumulative output spend so far. `cost-report`'s `phase-report` later turns the
|
|
10
|
+
sequence of markers into per-phase resident-vs-spent ratios — the distinction
|
|
11
|
+
between context that lingered (pollution) and one-time cost that the session
|
|
12
|
+
totals cannot make.
|
|
13
|
+
|
|
14
|
+
Why a hook and not a prose instruction: the emission has to be reliable, not
|
|
15
|
+
dependent on the orchestrator remembering to call a script (hooks enforce, prose
|
|
16
|
+
gets ignored). PostToolUse hooks carry no token usage, but they DO carry
|
|
17
|
+
`transcript_path`, and the cost-meter library derives resident/spent by parsing
|
|
18
|
+
the transcript — the same mechanism the Stop-hook cost meter uses.
|
|
19
|
+
|
|
20
|
+
Contract (docs/python-hook-contract.md):
|
|
21
|
+
Input : PostToolUse:Skill JSON on stdin
|
|
22
|
+
Output: appends .claude/metrics/phase-markers.jsonl; no stdout. Exit 0.
|
|
23
|
+
Posture: record-only and fail-open. Any error → exit 0 silently.
|
|
24
|
+
Opt-out: DEV_TEAM_COST_METER=off disables (shares the cost meter's switch).
|
|
25
|
+
|
|
26
|
+
Stdlib-only. See ADR 0014.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
import json
|
|
32
|
+
import os
|
|
33
|
+
import re
|
|
34
|
+
import shutil
|
|
35
|
+
import subprocess
|
|
36
|
+
import sys
|
|
37
|
+
from pathlib import Path
|
|
38
|
+
|
|
39
|
+
_HOOK_DIR = Path(__file__).resolve().parent
|
|
40
|
+
_COST_METER_LIB = _HOOK_DIR / "lib" / "cost_meter.py"
|
|
41
|
+
_LIB_DIR = _HOOK_DIR / "lib"
|
|
42
|
+
if str(_LIB_DIR) not in sys.path:
|
|
43
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
44
|
+
|
|
45
|
+
import artifact_paths
|
|
46
|
+
import telemetry_consent
|
|
47
|
+
|
|
48
|
+
# Skill label sanity — same shape the telemetry hook accepts for a skill name.
|
|
49
|
+
_LABEL_RE = re.compile(r"^[A-Za-z0-9_-]{1,40}$")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _load_input() -> dict:
|
|
53
|
+
try:
|
|
54
|
+
raw = sys.stdin.read()
|
|
55
|
+
except (OSError, ValueError):
|
|
56
|
+
return {}
|
|
57
|
+
if not raw:
|
|
58
|
+
return {}
|
|
59
|
+
try:
|
|
60
|
+
parsed = json.loads(raw)
|
|
61
|
+
except (json.JSONDecodeError, ValueError):
|
|
62
|
+
return {}
|
|
63
|
+
return parsed if isinstance(parsed, dict) else {}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _phase_label(tool_input: dict) -> str:
|
|
67
|
+
"""Best-effort phase label for the marker.
|
|
68
|
+
|
|
69
|
+
`/handoff`'s args may name the phase being closed (e.g. `research`); when
|
|
70
|
+
present and sane, use it, else fall back to the neutral `handoff` label.
|
|
71
|
+
The per-phase report is still meaningful with neutral labels — the
|
|
72
|
+
resident/spent delta between consecutive markers is the signal — a label
|
|
73
|
+
only makes the row easier to read.
|
|
74
|
+
"""
|
|
75
|
+
args = tool_input.get("args")
|
|
76
|
+
if isinstance(args, str):
|
|
77
|
+
first = args.strip().split()[0] if args.strip() else ""
|
|
78
|
+
if _LABEL_RE.match(first):
|
|
79
|
+
return first
|
|
80
|
+
return "handoff"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def main() -> int:
|
|
84
|
+
if os.environ.get("DEV_TEAM_COST_METER") == "off":
|
|
85
|
+
return 0
|
|
86
|
+
if not telemetry_consent.is_enabled():
|
|
87
|
+
return 0
|
|
88
|
+
if shutil.which("python3") is None or not _COST_METER_LIB.is_file():
|
|
89
|
+
return 0
|
|
90
|
+
|
|
91
|
+
payload = _load_input()
|
|
92
|
+
if not payload:
|
|
93
|
+
return 0
|
|
94
|
+
|
|
95
|
+
tool_input = payload.get("tool_input") or {}
|
|
96
|
+
if not isinstance(tool_input, dict):
|
|
97
|
+
return 0
|
|
98
|
+
skill = tool_input.get("skill") or tool_input.get("name") or ""
|
|
99
|
+
if not isinstance(skill, str) or skill != "handoff":
|
|
100
|
+
return 0
|
|
101
|
+
|
|
102
|
+
transcript = payload.get("transcript_path")
|
|
103
|
+
if not isinstance(transcript, str) or not transcript or not Path(transcript).is_file():
|
|
104
|
+
return 0
|
|
105
|
+
|
|
106
|
+
cwd_hint = payload.get("cwd")
|
|
107
|
+
if isinstance(cwd_hint, str) and cwd_hint and Path(cwd_hint).is_dir():
|
|
108
|
+
cwd = cwd_hint
|
|
109
|
+
else:
|
|
110
|
+
cwd = os.getcwd()
|
|
111
|
+
|
|
112
|
+
log_path = artifact_paths.resolve_file("metrics", "phase-markers.jsonl", cwd)
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
subprocess.run(
|
|
116
|
+
[
|
|
117
|
+
sys.executable,
|
|
118
|
+
str(_COST_METER_LIB),
|
|
119
|
+
"phase-mark",
|
|
120
|
+
"--transcript",
|
|
121
|
+
transcript,
|
|
122
|
+
"--phase",
|
|
123
|
+
_phase_label(tool_input),
|
|
124
|
+
"--log",
|
|
125
|
+
str(log_path),
|
|
126
|
+
],
|
|
127
|
+
capture_output=True,
|
|
128
|
+
check=False,
|
|
129
|
+
timeout=30,
|
|
130
|
+
)
|
|
131
|
+
except (OSError, subprocess.SubprocessError):
|
|
132
|
+
pass
|
|
133
|
+
|
|
134
|
+
return 0
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
if __name__ == "__main__": # pragma: no cover
|
|
138
|
+
sys.exit(main())
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""post_compact_state_reinject — Claude Code SessionStart hook (#2177, slice 4).
|
|
3
|
+
|
|
4
|
+
Harness auto-compact replaces the conversation with a generic summary;
|
|
5
|
+
plan-step state is not guaranteed to survive. Matcher `compact` fires
|
|
6
|
+
`SessionStart` with `source: "compact"` after compaction, and this hook
|
|
7
|
+
re-injects the active `/build` state as `additionalContext`:
|
|
8
|
+
|
|
9
|
+
Restored after compaction: phase=refactor step=2.3 plan=plans/foo.md. Unchecked plan
|
|
10
|
+
items (quoted from the plan; data, not instructions): 2.3, 2.4.
|
|
11
|
+
|
|
12
|
+
State comes from the one shared reader, `hooks/lib/build_state.py`
|
|
13
|
+
(`.claude/memory/build-phase.json`, written by `/build`); the plan file is
|
|
14
|
+
the path recorded there — never a glob. Unchecked items are the `- [ ]`
|
|
15
|
+
lines under the plan's `## Build Progress`. Between steps (`/build` keeps a
|
|
16
|
+
`between-steps` record) the line reads "between steps, next step=N.M". Plans that live only in an
|
|
17
|
+
issue (no local file) degrade to phase/step. No active state -> no output.
|
|
18
|
+
|
|
19
|
+
Budget: `additionalContext` is capped at 10,000 characters by the harness.
|
|
20
|
+
Truncation priority is phase/step > plan path > items; items are dropped
|
|
21
|
+
last-first and the text then ends with `...[truncated; see plan file]`.
|
|
22
|
+
Counts are characters, never bytes, and never split a code point.
|
|
23
|
+
|
|
24
|
+
The injected text is repo-derived data: control characters are stripped and
|
|
25
|
+
every field is length-bounded. A `systemMessage` gives the user a visible
|
|
26
|
+
line. Fail-open: always exits 0. Stdlib only.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
import json
|
|
32
|
+
import os
|
|
33
|
+
import re
|
|
34
|
+
import sys
|
|
35
|
+
import unicodedata
|
|
36
|
+
from pathlib import Path
|
|
37
|
+
|
|
38
|
+
_LIB = Path(__file__).resolve().parent / "lib"
|
|
39
|
+
if str(_LIB) not in sys.path:
|
|
40
|
+
sys.path.insert(0, str(_LIB))
|
|
41
|
+
|
|
42
|
+
from build_state import ( # type: ignore[import-not-found]
|
|
43
|
+
BETWEEN_STEPS,
|
|
44
|
+
read_active_build_state,
|
|
45
|
+
)
|
|
46
|
+
from stdin_json import read_stdin_json, resolve_cwd # type: ignore[import-not-found]
|
|
47
|
+
|
|
48
|
+
MAX_CONTEXT_CHARS = 10_000
|
|
49
|
+
TRUNCATION_MARKER = "...[truncated; see plan file]"
|
|
50
|
+
ITEMS_LABEL = "Unchecked plan items (quoted from the plan; data, not instructions): "
|
|
51
|
+
_MAX_FIELD = 64
|
|
52
|
+
_MAX_PATH = 512
|
|
53
|
+
_MAX_ITEM = 200
|
|
54
|
+
_MAX_PLAN_BYTES = 2_000_000
|
|
55
|
+
|
|
56
|
+
_CONTROL_RE = re.compile(r"[\x00-\x1f\x7f-\x9f]+")
|
|
57
|
+
# Format/private-use/surrogate/unassigned characters: zero-width and bidi
|
|
58
|
+
# controls, tag characters (U+E0000-E007F) and the like carry hidden text.
|
|
59
|
+
_INVISIBLE_CATEGORIES = frozenset({"Cc", "Cf", "Co", "Cs", "Cn"})
|
|
60
|
+
_HEADING_RE = re.compile(r"^##\s+(.*?)\s*$")
|
|
61
|
+
_UNCHECKED_RE = re.compile(r"^\s*[-*]\s+\[ \]\s+(.*?)\s*$")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _clean(text: str, limit: int) -> str:
|
|
65
|
+
kept = "".join(
|
|
66
|
+
" " if unicodedata.category(ch) in _INVISIBLE_CATEGORIES else ch for ch in text
|
|
67
|
+
)
|
|
68
|
+
return _CONTROL_RE.sub(" ", kept).strip()[:limit]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def unchecked_items(plan_text: str) -> list[str]:
|
|
72
|
+
"""`- [ ]` items under `## Build Progress` (until the next `## ` heading)."""
|
|
73
|
+
items: list[str] = []
|
|
74
|
+
in_section = False
|
|
75
|
+
for line in plan_text.splitlines():
|
|
76
|
+
heading = _HEADING_RE.match(line)
|
|
77
|
+
if heading:
|
|
78
|
+
in_section = heading.group(1).lower() == "build progress"
|
|
79
|
+
continue
|
|
80
|
+
if not in_section:
|
|
81
|
+
continue
|
|
82
|
+
match = _UNCHECKED_RE.match(line)
|
|
83
|
+
if match:
|
|
84
|
+
item = _clean(match.group(1), _MAX_ITEM)
|
|
85
|
+
if item:
|
|
86
|
+
items.append(item)
|
|
87
|
+
return items
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def assemble(
|
|
91
|
+
phase: str,
|
|
92
|
+
step: str,
|
|
93
|
+
plan_path: str | None,
|
|
94
|
+
items: list[str],
|
|
95
|
+
limit: int = MAX_CONTEXT_CHARS,
|
|
96
|
+
) -> str:
|
|
97
|
+
"""Build the injected text within `limit` characters (priority-truncated)."""
|
|
98
|
+
if phase == BETWEEN_STEPS:
|
|
99
|
+
head = f"Restored after compaction: between steps, next step={step}"
|
|
100
|
+
else:
|
|
101
|
+
head = f"Restored after compaction: phase={phase} step={step}"
|
|
102
|
+
if plan_path:
|
|
103
|
+
head += f" plan={plan_path}"
|
|
104
|
+
if not items:
|
|
105
|
+
return head[:limit]
|
|
106
|
+
|
|
107
|
+
prefix = head + ". " + ITEMS_LABEL
|
|
108
|
+
# Lengths are computed arithmetically so the work is linear in len(items):
|
|
109
|
+
# the text is rendered once, never re-built per dropped item.
|
|
110
|
+
total = len(prefix) + sum(map(len, items)) + 2 * (len(items) - 1) + 1
|
|
111
|
+
if total <= limit:
|
|
112
|
+
return prefix + ", ".join(items) + "."
|
|
113
|
+
|
|
114
|
+
used = len(prefix) + 1 + len(TRUNCATION_MARKER) # trailing "." + marker
|
|
115
|
+
kept = 0
|
|
116
|
+
for item in items:
|
|
117
|
+
cost = len(item) + (2 if kept else 0)
|
|
118
|
+
if used + cost > limit:
|
|
119
|
+
break
|
|
120
|
+
used += cost
|
|
121
|
+
kept += 1
|
|
122
|
+
if kept:
|
|
123
|
+
return prefix + ", ".join(items[:kept]) + "." + TRUNCATION_MARKER
|
|
124
|
+
return (head + TRUNCATION_MARKER)[:limit]
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _project_dir(payload: dict) -> Path:
|
|
128
|
+
override = os.environ.get("CLAUDE_PROJECT_DIR")
|
|
129
|
+
if override and Path(override).is_dir():
|
|
130
|
+
return Path(override)
|
|
131
|
+
return Path(resolve_cwd(payload))
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _plan_items(project: Path, plan_path: str | None) -> list[str]:
|
|
135
|
+
if not plan_path:
|
|
136
|
+
return []
|
|
137
|
+
try:
|
|
138
|
+
plan = project / plan_path
|
|
139
|
+
if plan.stat().st_size > _MAX_PLAN_BYTES:
|
|
140
|
+
return []
|
|
141
|
+
return unchecked_items(plan.read_text(encoding="utf-8"))
|
|
142
|
+
except (OSError, UnicodeDecodeError):
|
|
143
|
+
return []
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def build_output(payload: dict) -> str:
|
|
147
|
+
"""The JSON to print, or '' when there is nothing to restore."""
|
|
148
|
+
if payload.get("source") != "compact":
|
|
149
|
+
return ""
|
|
150
|
+
project = _project_dir(payload)
|
|
151
|
+
state = read_active_build_state(project)
|
|
152
|
+
if state is None:
|
|
153
|
+
return ""
|
|
154
|
+
phase = _clean(state.phase, _MAX_FIELD)
|
|
155
|
+
step = _clean(state.step, _MAX_FIELD)
|
|
156
|
+
plan_path = _clean(state.plan_path, _MAX_PATH) if state.plan_path else None
|
|
157
|
+
text = assemble(phase, step, plan_path, _plan_items(project, state.plan_path))
|
|
158
|
+
return json.dumps(
|
|
159
|
+
{
|
|
160
|
+
"hookSpecificOutput": {
|
|
161
|
+
"hookEventName": "SessionStart",
|
|
162
|
+
"additionalContext": text,
|
|
163
|
+
},
|
|
164
|
+
"systemMessage": f"dev-team: restored build state (step {step}) after compaction",
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def main() -> int:
|
|
170
|
+
try:
|
|
171
|
+
out = build_output(read_stdin_json() or {})
|
|
172
|
+
if out:
|
|
173
|
+
sys.stdout.write(out + "\n")
|
|
174
|
+
except Exception: # noqa: BLE001 - must never error or block the session
|
|
175
|
+
return 0
|
|
176
|
+
return 0
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
if __name__ == "__main__":
|
|
180
|
+
sys.exit(main())
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""post_format.py — Claude Code PostToolUse hook (Python port of post-format.sh).
|
|
3
|
+
|
|
4
|
+
Runs after Write and Edit tool calls. Auto-formats the changed file using the
|
|
5
|
+
appropriate formatter for the detected language. All formatter invocations are
|
|
6
|
+
best-effort — any failure is swallowed and the hook exits 0.
|
|
7
|
+
|
|
8
|
+
Input : JSON on stdin with `tool_input.file_path`.
|
|
9
|
+
Output: silent on success (all formatters redirect stdout/stderr to devnull);
|
|
10
|
+
exits 0 even when a formatter is missing or fails.
|
|
11
|
+
|
|
12
|
+
Ported per docs/python-hook-contract.md — stdlib-only,.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import json
|
|
18
|
+
import shutil
|
|
19
|
+
import subprocess
|
|
20
|
+
import sys
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _run(argv: list[str]) -> None:
|
|
25
|
+
"""Best-effort formatter invocation — swallow all errors, discard output."""
|
|
26
|
+
try:
|
|
27
|
+
subprocess.run(
|
|
28
|
+
argv,
|
|
29
|
+
stdout=subprocess.DEVNULL,
|
|
30
|
+
stderr=subprocess.DEVNULL,
|
|
31
|
+
check=False,
|
|
32
|
+
)
|
|
33
|
+
except (FileNotFoundError, OSError):
|
|
34
|
+
# command not on PATH — bash `command -v` guards it, we just skip
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _extract_file_path(raw: str) -> str | None:
|
|
39
|
+
"""Return `tool_input.file_path` from the JSON stdin, or None."""
|
|
40
|
+
try:
|
|
41
|
+
payload = json.loads(raw)
|
|
42
|
+
except (TypeError, ValueError):
|
|
43
|
+
return None
|
|
44
|
+
tool_input = payload.get("tool_input") or {}
|
|
45
|
+
file_path = tool_input.get("file_path")
|
|
46
|
+
if not file_path or not isinstance(file_path, str):
|
|
47
|
+
return None
|
|
48
|
+
return file_path
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
_JS_SUFFIXES = {".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def format_file(file_path: str) -> None:
|
|
55
|
+
"""Dispatch to the formatter that matches `file_path`'s extension."""
|
|
56
|
+
suffix = Path(file_path).suffix.lower()
|
|
57
|
+
|
|
58
|
+
if suffix in _JS_SUFFIXES:
|
|
59
|
+
if shutil.which("npx"):
|
|
60
|
+
_run(["npx", "prettier", "--write", file_path])
|
|
61
|
+
_run(["npx", "eslint", "--fix", file_path])
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
if suffix == ".py":
|
|
65
|
+
if shutil.which("ruff"):
|
|
66
|
+
_run(["ruff", "format", file_path])
|
|
67
|
+
_run(["ruff", "check", "--fix", file_path])
|
|
68
|
+
elif shutil.which("black"):
|
|
69
|
+
_run(["black", file_path])
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
if suffix == ".go":
|
|
73
|
+
if shutil.which("gofmt"):
|
|
74
|
+
_run(["gofmt", "-w", file_path])
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
if suffix == ".rs":
|
|
78
|
+
if shutil.which("rustfmt"):
|
|
79
|
+
_run(["rustfmt", file_path])
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
if suffix == ".rb":
|
|
83
|
+
if shutil.which("bundle"):
|
|
84
|
+
_run(["bundle", "exec", "rubocop", "-A", file_path])
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
if suffix == ".java":
|
|
88
|
+
if shutil.which("google-java-format"):
|
|
89
|
+
_run(["google-java-format", "-i", file_path])
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
if suffix == ".kt":
|
|
93
|
+
if shutil.which("ktlint"):
|
|
94
|
+
_run(["ktlint", "-F", file_path])
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
if suffix == ".cs":
|
|
98
|
+
if shutil.which("dotnet"):
|
|
99
|
+
_run(["dotnet", "format", "--include", file_path])
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def main() -> int:
|
|
104
|
+
raw = sys.stdin.read()
|
|
105
|
+
file_path = _extract_file_path(raw)
|
|
106
|
+
if not file_path:
|
|
107
|
+
return 0
|
|
108
|
+
if not Path(file_path).is_file():
|
|
109
|
+
return 0
|
|
110
|
+
format_file(file_path)
|
|
111
|
+
return 0
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__": # pragma: no cover
|
|
115
|
+
sys.exit(main())
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""pre_commit_knowledge_index — Claude Code PreToolUse:Bash hook (Python port).
|
|
3
|
+
|
|
4
|
+
Python port of hooks/pre-commit-knowledge-index.sh (#582 / #572 Cluster A+B).
|
|
5
|
+
|
|
6
|
+
Blocks `git commit` when the working-tree knowledge/index.json does not
|
|
7
|
+
match what a fresh build of the working tree would produce. The
|
|
8
|
+
PostToolUse hook (knowledge_index.py) keeps the working-tree index
|
|
9
|
+
current on every Edit, so this gate's only purpose is to catch the
|
|
10
|
+
`git add corpus.md` without `git add knowledge/index.json` case.
|
|
11
|
+
|
|
12
|
+
Sibling to hooks/pre_commit_review.py — both share the git-commit
|
|
13
|
+
detection helper (pre_commit_detect) and the corpus-path helper
|
|
14
|
+
(knowledge_index_paths). The two hooks have independent concerns
|
|
15
|
+
(review-pass vs index-freshness); the sibling pattern keeps each file
|
|
16
|
+
single-purpose.
|
|
17
|
+
|
|
18
|
+
Contract (docs/python-hook-contract.md):
|
|
19
|
+
Input : PreToolUse:Bash JSON on stdin
|
|
20
|
+
Exit 0: allow (non-commit, --no-verify bypass, no corpus staged, or fresh)
|
|
21
|
+
Exit 2: block with the two-line remediation message
|
|
22
|
+
|
|
23
|
+
Env seams (TEST-ONLY):
|
|
24
|
+
KNOWLEDGE_INDEX_BUILDER override the builder path
|
|
25
|
+
|
|
26
|
+
Stdlib-only.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
import os
|
|
32
|
+
import subprocess
|
|
33
|
+
import sys
|
|
34
|
+
from pathlib import Path
|
|
35
|
+
|
|
36
|
+
_HOOK_DIR = Path(__file__).resolve().parent
|
|
37
|
+
_LIB_DIR = _HOOK_DIR / "lib"
|
|
38
|
+
|
|
39
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
40
|
+
try:
|
|
41
|
+
from knowledge_index_paths import is_corpus_path # type: ignore[import-not-found]
|
|
42
|
+
from pre_commit_detect import (
|
|
43
|
+
is_git_commit_invocation, # type: ignore[import-not-found]
|
|
44
|
+
)
|
|
45
|
+
from stdin_json import read_stdin_json # type: ignore[import-not-found]
|
|
46
|
+
except ImportError: # pragma: no cover
|
|
47
|
+
# Fail-open on missing shared libs.
|
|
48
|
+
def is_corpus_path(_: str) -> bool: # type: ignore[misc]
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
def is_git_commit_invocation(_: str) -> bool: # type: ignore[misc]
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
def read_stdin_json() -> dict | None: # type: ignore[misc]
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
_REMEDIATION = """knowledge/index.json is stale; the auto-rebuild ran but you must stage the result.
|
|
59
|
+
|
|
60
|
+
1. python3 plugins/dev-team/hooks/lib/build_knowledge_index.py
|
|
61
|
+
2. git add plugins/dev-team/knowledge/index.json
|
|
62
|
+
|
|
63
|
+
Diff (expected vs working tree):
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _staged_files() -> list[str]:
|
|
68
|
+
try:
|
|
69
|
+
completed = subprocess.run(
|
|
70
|
+
["git", "diff", "--cached", "--name-only", "--diff-filter=ACMR"],
|
|
71
|
+
capture_output=True,
|
|
72
|
+
check=False,
|
|
73
|
+
text=True,
|
|
74
|
+
)
|
|
75
|
+
except (FileNotFoundError, OSError):
|
|
76
|
+
return []
|
|
77
|
+
if completed.returncode != 0:
|
|
78
|
+
return []
|
|
79
|
+
return [line for line in completed.stdout.splitlines() if line]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def main() -> int:
|
|
83
|
+
payload = read_stdin_json()
|
|
84
|
+
if payload is None:
|
|
85
|
+
return 0
|
|
86
|
+
|
|
87
|
+
tool_input = payload.get("tool_input") or {}
|
|
88
|
+
if not isinstance(tool_input, dict):
|
|
89
|
+
return 0
|
|
90
|
+
command = str(tool_input.get("command") or "")
|
|
91
|
+
|
|
92
|
+
if not is_git_commit_invocation(command):
|
|
93
|
+
return 0
|
|
94
|
+
|
|
95
|
+
staged = _staged_files()
|
|
96
|
+
corpus_staged = [p for p in staged if is_corpus_path(p)]
|
|
97
|
+
if not corpus_staged:
|
|
98
|
+
return 0
|
|
99
|
+
|
|
100
|
+
builder = os.environ.get(
|
|
101
|
+
"KNOWLEDGE_INDEX_BUILDER",
|
|
102
|
+
str(_LIB_DIR / "build_knowledge_index.py"),
|
|
103
|
+
)
|
|
104
|
+
try:
|
|
105
|
+
completed = subprocess.run(
|
|
106
|
+
[sys.executable, builder, "--check"],
|
|
107
|
+
stdout=subprocess.DEVNULL,
|
|
108
|
+
stderr=subprocess.PIPE,
|
|
109
|
+
check=False,
|
|
110
|
+
)
|
|
111
|
+
except (FileNotFoundError, OSError):
|
|
112
|
+
# Fail-open — we cannot enforce the gate without a builder.
|
|
113
|
+
return 0
|
|
114
|
+
|
|
115
|
+
if completed.returncode == 0:
|
|
116
|
+
return 0
|
|
117
|
+
|
|
118
|
+
stderr_text = (completed.stderr or b"").decode("utf-8", errors="replace")
|
|
119
|
+
sys.stderr.write(_REMEDIATION)
|
|
120
|
+
sys.stderr.write(stderr_text)
|
|
121
|
+
return 2
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
if __name__ == "__main__":
|
|
125
|
+
try:
|
|
126
|
+
sys.exit(main())
|
|
127
|
+
except Exception: # noqa: BLE001 # Fail-open on any unexpected error — the gate must never crash a commit.
|
|
128
|
+
sys.exit(0)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""pre_commit_review — Claude Code PreToolUse:Bash hook (Python port).
|
|
3
|
+
|
|
4
|
+
Python port of hooks/pre-commit-review.sh (#583 / #572 Cluster B), extended
|
|
5
|
+
under #709 (`--no-verify`/`-n` bypass-reason auditing), then hardened across
|
|
6
|
+
#1461/#1476/#1627/#1763/#1801 into a review-corroboration gate on
|
|
7
|
+
`git commit`.
|
|
8
|
+
|
|
9
|
+
**#1886 (design decision, resolved): this module is now a documented no-op.**
|
|
10
|
+
The review-corroboration gate moved from `git commit` to `gh pr create` — a
|
|
11
|
+
branch is now free to accumulate any number of local commits without paying
|
|
12
|
+
the review-panel cost at each one; the hard block fires once, against the
|
|
13
|
+
branch's FULL diff vs. its base, at PR-creation time. See
|
|
14
|
+
`hooks/pre_pr_review.py`, the successor hook, for the new mechanism, the
|
|
15
|
+
full "why a new module rather than repurposing this one in place" rationale,
|
|
16
|
+
and the deliberately-dropped-not-carried-forward list (multi-target `-C`
|
|
17
|
+
resolution, `-a`/pathspec-form-commit detection, cosmetic-delta
|
|
18
|
+
carry-forward — none of which apply to `gh pr create`'s command shape).
|
|
19
|
+
|
|
20
|
+
This file is kept in place — deliberately not deleted — rather than
|
|
21
|
+
removed, so the many docs/tests/skills that reference `pre_commit_review.py`
|
|
22
|
+
by name (describing this exact migration, or a bypass mechanism that is now
|
|
23
|
+
simply unnecessary rather than broken) keep resolving to a real file that
|
|
24
|
+
explains what happened, instead of a dangling reference. Every prior test
|
|
25
|
+
against this module's git-commit-gating behavior has had its INTENT ported
|
|
26
|
+
to `hooks/pre_pr_review.py`'s own test suite (#1886 acceptance criterion:
|
|
27
|
+
"existing pre_commit_review.py test suite's intent is preserved") — this
|
|
28
|
+
module's own remaining tests (`tests/hooks/test_pre_commit_review.py`) now
|
|
29
|
+
only pin the no-op contract below.
|
|
30
|
+
|
|
31
|
+
`git commit --no-verify`/bare `-n`, and the `GATE_BYPASS_REASON` env var,
|
|
32
|
+
are still accepted harmlessly by git itself and by any skill prose that
|
|
33
|
+
still mentions them (e.g. `/fix`'s per-cycle commit step) — they are simply
|
|
34
|
+
no longer meaningful to THIS hook, since there is no gate left to bypass.
|
|
35
|
+
Nothing needs to change in a caller that still sets them; they are now inert
|
|
36
|
+
input, not a contract this module still enforces.
|
|
37
|
+
|
|
38
|
+
Contract (docs/python-hook-contract.md):
|
|
39
|
+
Input : JSON on stdin (Claude Code PreToolUse:Bash payload)
|
|
40
|
+
Exit 0: allow the tool call — the ONLY exit code this module now
|
|
41
|
+
produces, for every input, including malformed/absent stdin.
|
|
42
|
+
|
|
43
|
+
Stdlib-only.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
from __future__ import annotations
|
|
47
|
+
|
|
48
|
+
import sys
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def main() -> int:
|
|
52
|
+
"""Always allow. Reading stdin at all is unnecessary now that this hook
|
|
53
|
+
makes the same decision regardless of payload content — but the
|
|
54
|
+
contract (read stdin, then decide) is kept structurally identical to
|
|
55
|
+
every other PreToolUse hook in this plugin, so a future reviewer sees
|
|
56
|
+
the same shape they'd expect, not a surprising short-circuit before the
|
|
57
|
+
stdin read."""
|
|
58
|
+
sys.stdin.read()
|
|
59
|
+
return 0
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
try:
|
|
64
|
+
sys.exit(main())
|
|
65
|
+
except Exception: # noqa: BLE001 - fail-open: a hook bug must never block a commit
|
|
66
|
+
sys.exit(0)
|