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,194 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Python port of hooks/token-efficiency-review.sh (#607 / #572 Phase 3).
|
|
3
|
+
|
|
4
|
+
PostToolUse hook for Write/Edit — checks file length, CLAUDE.md length,
|
|
5
|
+
and function length. Emits advisory warnings on stdout; never blocks.
|
|
6
|
+
|
|
7
|
+
Contract (docs/python-hook-contract.md):
|
|
8
|
+
Input : PostToolUse JSON on stdin
|
|
9
|
+
Output: Advisory warnings on stdout, or empty
|
|
10
|
+
Exit : Always 0
|
|
11
|
+
|
|
12
|
+
Stdlib-only. See docs/python-hook-contract.md.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import json
|
|
18
|
+
import re
|
|
19
|
+
import sys
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
_HOOK_DIR = Path(__file__).resolve().parent
|
|
23
|
+
_LIB_DIR = _HOOK_DIR / "lib"
|
|
24
|
+
if str(_LIB_DIR) not in sys.path:
|
|
25
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
from token_efficiency_limits import ( # type: ignore[import-not-found]
|
|
29
|
+
CLAUDE_MD_CHAR_LIMIT,
|
|
30
|
+
FILE_LINE_LIMIT,
|
|
31
|
+
)
|
|
32
|
+
from token_efficiency_limits import char_count as _char_count
|
|
33
|
+
from token_efficiency_limits import is_claude_md_file as _is_claude_md_file
|
|
34
|
+
except ImportError:
|
|
35
|
+
# Fail-open per the hook contract: never let a missing sibling module
|
|
36
|
+
# break advisory output. Mirror the shared defaults and logic.
|
|
37
|
+
CLAUDE_MD_CHAR_LIMIT = 5000
|
|
38
|
+
FILE_LINE_LIMIT = 500
|
|
39
|
+
|
|
40
|
+
def _is_claude_md_file(path: Path) -> bool:
|
|
41
|
+
return path.name.lower() == "claude.md"
|
|
42
|
+
|
|
43
|
+
def _char_count(path: Path) -> int:
|
|
44
|
+
return len(path.read_text(encoding="utf-8", errors="replace"))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# The .sh's awk pattern: function-declaration heuristics for common
|
|
48
|
+
# languages. Three alternatives (top-level function keyword; const/let/var =
|
|
49
|
+
# fn; indented method opening) — the same set the .sh emits.
|
|
50
|
+
_FUNC_START_RE = re.compile(
|
|
51
|
+
r"^\s*(async\s+)?function\s+[a-zA-Z_]"
|
|
52
|
+
r"|"
|
|
53
|
+
r"^\s*(const|let|var)\s+[a-zA-Z_]+\s*=\s*(async\s+)?\("
|
|
54
|
+
r"|"
|
|
55
|
+
r"^\s+[a-zA-Z_]+\s*\([^)]*\)\s*\{"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
_SOURCE_EXTS = (
|
|
60
|
+
".js",
|
|
61
|
+
".ts",
|
|
62
|
+
".jsx",
|
|
63
|
+
".tsx",
|
|
64
|
+
".py",
|
|
65
|
+
".rb",
|
|
66
|
+
".go",
|
|
67
|
+
".rs",
|
|
68
|
+
".java",
|
|
69
|
+
".cs",
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _extract_path(payload: dict) -> str:
|
|
74
|
+
"""Mirror `.tool_input.file_path // .tool_input.path // .file_path // .path`."""
|
|
75
|
+
tool_input = payload.get("tool_input") or {}
|
|
76
|
+
return (
|
|
77
|
+
tool_input.get("file_path")
|
|
78
|
+
or tool_input.get("path")
|
|
79
|
+
or payload.get("file_path")
|
|
80
|
+
or payload.get("path")
|
|
81
|
+
or ""
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _read_json(raw: bytes) -> dict:
|
|
86
|
+
try:
|
|
87
|
+
return json.loads(raw or b"{}")
|
|
88
|
+
except json.JSONDecodeError:
|
|
89
|
+
return {}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _check_claude_md(path: Path) -> str | None:
|
|
93
|
+
"""Character-count check for CLAUDE.md files."""
|
|
94
|
+
if not _is_claude_md_file(path):
|
|
95
|
+
return None
|
|
96
|
+
try:
|
|
97
|
+
count = _char_count(path)
|
|
98
|
+
except OSError:
|
|
99
|
+
return None
|
|
100
|
+
if count > CLAUDE_MD_CHAR_LIMIT:
|
|
101
|
+
return (
|
|
102
|
+
f"Token: CLAUDE.md is {count} chars (limit: {CLAUDE_MD_CHAR_LIMIT}). "
|
|
103
|
+
"Move detailed examples to docs/ or skills."
|
|
104
|
+
)
|
|
105
|
+
return None
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _line_count_from_lines(lines: list[str]) -> int:
|
|
109
|
+
return len(lines)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _long_functions_from_lines(lines: list[str], limit: int = 50) -> list[str]:
|
|
113
|
+
"""Return a list of ` Line N: <name> (<len> lines)` for functions
|
|
114
|
+
longer than `limit`. Mirrors the .sh's awk block."""
|
|
115
|
+
findings: list[str] = []
|
|
116
|
+
func_start = 0
|
|
117
|
+
func_name = ""
|
|
118
|
+
lineno = 0
|
|
119
|
+
for line in lines:
|
|
120
|
+
lineno += 1
|
|
121
|
+
if _FUNC_START_RE.search(line):
|
|
122
|
+
if func_start > 0 and lineno - func_start > limit:
|
|
123
|
+
findings.append(
|
|
124
|
+
f" Line {func_start}: {func_name} ({lineno - func_start} lines)"
|
|
125
|
+
)
|
|
126
|
+
func_start = lineno
|
|
127
|
+
name = line.lstrip()
|
|
128
|
+
# Strip anything after `(` or `{` — matches bash sub()s.
|
|
129
|
+
name = re.sub(r"[({].*", "", name)
|
|
130
|
+
func_name = name
|
|
131
|
+
if func_start > 0 and lineno - func_start > limit:
|
|
132
|
+
findings.append(
|
|
133
|
+
f" Line {func_start}: {func_name} ({lineno - func_start} lines)"
|
|
134
|
+
)
|
|
135
|
+
return findings
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _check_source_file(path: Path) -> list[str]:
|
|
139
|
+
"""Return warning lines for source-file length + long functions.
|
|
140
|
+
|
|
141
|
+
Reads the file's content exactly once and reuses the resulting lines for
|
|
142
|
+
both checks (line-count, long-function scan)."""
|
|
143
|
+
warnings: list[str] = []
|
|
144
|
+
if path.suffix.lower() not in _SOURCE_EXTS:
|
|
145
|
+
return warnings
|
|
146
|
+
try:
|
|
147
|
+
lines = path.read_text(errors="replace").splitlines()
|
|
148
|
+
except OSError:
|
|
149
|
+
return warnings
|
|
150
|
+
lc = _line_count_from_lines(lines)
|
|
151
|
+
if lc > FILE_LINE_LIMIT:
|
|
152
|
+
warnings.append(
|
|
153
|
+
f"Token: File is {lc} lines (limit: {FILE_LINE_LIMIT}). Large files "
|
|
154
|
+
"require more context tokens — consider splitting."
|
|
155
|
+
)
|
|
156
|
+
long_funcs = _long_functions_from_lines(lines)
|
|
157
|
+
if long_funcs:
|
|
158
|
+
warnings.append(
|
|
159
|
+
"Token: Long functions detected (limit: 50 lines). "
|
|
160
|
+
"Split into smaller units:\n" + "\n".join(long_funcs)
|
|
161
|
+
)
|
|
162
|
+
return warnings
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def main() -> int:
|
|
166
|
+
try:
|
|
167
|
+
raw = sys.stdin.buffer.read()
|
|
168
|
+
except (OSError, ValueError):
|
|
169
|
+
raw = b""
|
|
170
|
+
payload = _read_json(raw)
|
|
171
|
+
file_path_str = _extract_path(payload)
|
|
172
|
+
if not file_path_str:
|
|
173
|
+
return 0
|
|
174
|
+
file_path = Path(file_path_str)
|
|
175
|
+
if not file_path.is_file():
|
|
176
|
+
return 0
|
|
177
|
+
|
|
178
|
+
warnings: list[str] = []
|
|
179
|
+
claude_md_warning = _check_claude_md(file_path)
|
|
180
|
+
if claude_md_warning:
|
|
181
|
+
warnings.append(claude_md_warning)
|
|
182
|
+
warnings.extend(_check_source_file(file_path))
|
|
183
|
+
|
|
184
|
+
if warnings:
|
|
185
|
+
# The .sh formats WARNINGS by concatenating each warning with a
|
|
186
|
+
# leading newline, then echoing $WARNINGS. That produces a leading
|
|
187
|
+
# newline before the first warning. Reproduce for byte-parity.
|
|
188
|
+
print()
|
|
189
|
+
print("\n".join(warnings))
|
|
190
|
+
return 0
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
if __name__ == "__main__":
|
|
194
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Python port of hooks/verify-guard.sh (#608 / #572 Phase 3), escalated to a
|
|
3
|
+
hard stop for stuck loops (#708).
|
|
4
|
+
|
|
5
|
+
PreToolUse Bash hook — detects repeated identical verify invocations
|
|
6
|
+
within a session. Once the same normalized command has run THRESHOLD
|
|
7
|
+
consecutive times with **zero** intervening Edit/Write/NotebookEdit calls
|
|
8
|
+
(tracked via verify_guard_edit_marker.py, its PreToolUse sibling on the
|
|
9
|
+
Write|Edit|NotebookEdit matcher), it BLOCKS the command instead of merely
|
|
10
|
+
warning — that combination is a genuinely stuck loop, not the ordinary
|
|
11
|
+
RED/GREEN/REFACTOR pattern of re-running the same command after each real
|
|
12
|
+
edit. Any edit observed since the previous verify run resets the counter,
|
|
13
|
+
same as a different command does, so legitimate TDD repeats are never
|
|
14
|
+
blocked.
|
|
15
|
+
|
|
16
|
+
Contract (docs/python-hook-contract.md):
|
|
17
|
+
Input : PreToolUse JSON on stdin (hook_event_name, session_id,
|
|
18
|
+
tool_input.command, cwd)
|
|
19
|
+
Output: Warning on stdout below threshold; `[BLOCK]`-prefixed message
|
|
20
|
+
at/above threshold (unless DEV_TEAM_VERIFY_THRESHOLD=0)
|
|
21
|
+
Exit : 0 below threshold, or when DEV_TEAM_VERIFY_THRESHOLD=0;
|
|
22
|
+
2 (block) at/above threshold with threshold > 0
|
|
23
|
+
Env : DEV_TEAM_VERIFY_THRESHOLD (default 3), TMPDIR
|
|
24
|
+
|
|
25
|
+
Stdlib-only. See docs/python-hook-contract.md.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import json
|
|
31
|
+
import os
|
|
32
|
+
import re
|
|
33
|
+
import sys
|
|
34
|
+
from pathlib import Path
|
|
35
|
+
|
|
36
|
+
_HOOK_DIR = Path(__file__).resolve().parent
|
|
37
|
+
_LIB_DIR = _HOOK_DIR / "lib"
|
|
38
|
+
if str(_LIB_DIR) not in sys.path:
|
|
39
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
40
|
+
|
|
41
|
+
from boundary_events import emit_boundary_event as _emit_boundary_event
|
|
42
|
+
from verify_guard_state import (
|
|
43
|
+
cksum,
|
|
44
|
+
read_state,
|
|
45
|
+
state_file,
|
|
46
|
+
state_key,
|
|
47
|
+
write_state,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def emit_boundary_event(*args, **kwargs) -> None:
|
|
52
|
+
"""Local safety net (#859): even a misbehaving helper must never affect
|
|
53
|
+
this hook's exit code, stdout, or stderr."""
|
|
54
|
+
try:
|
|
55
|
+
_emit_boundary_event(*args, **kwargs)
|
|
56
|
+
except Exception: # noqa: BLE001, S110 - fail-open by design
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# Verify-class command detector — mirrors
|
|
61
|
+
# `session_log.classify.VERIFY_RE`, which
|
|
62
|
+
# plugins/dev-team/scripts/session_report.py's `--profile maintainer`
|
|
63
|
+
# aliases.
|
|
64
|
+
_VERIFY_RE = re.compile(
|
|
65
|
+
r"\b("
|
|
66
|
+
r"npm (run )?(test|lint|build)"
|
|
67
|
+
r"|pytest|bats|eslint|tsc|go test|cargo (test|build)|mvn"
|
|
68
|
+
r"|gradle|make( |$)|vitest|jest|ruff|mypy|shellcheck"
|
|
69
|
+
r")\b"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _read_payload() -> dict:
|
|
74
|
+
try:
|
|
75
|
+
raw = sys.stdin.buffer.read()
|
|
76
|
+
except (OSError, ValueError):
|
|
77
|
+
return {}
|
|
78
|
+
try:
|
|
79
|
+
return json.loads(raw or b"{}")
|
|
80
|
+
except json.JSONDecodeError:
|
|
81
|
+
return {}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def main() -> int:
|
|
85
|
+
payload = _read_payload()
|
|
86
|
+
cmd = str(payload.get("tool_input", {}).get("command") or "")
|
|
87
|
+
if not cmd:
|
|
88
|
+
return 0
|
|
89
|
+
|
|
90
|
+
# Only fire on verify-class commands.
|
|
91
|
+
if not _VERIFY_RE.search(cmd):
|
|
92
|
+
return 0
|
|
93
|
+
|
|
94
|
+
session_id = str(payload.get("session_id") or "")
|
|
95
|
+
cwd = str(payload.get("cwd") or "")
|
|
96
|
+
key = state_key(session_id, cwd)
|
|
97
|
+
path = state_file(key)
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
101
|
+
except OSError:
|
|
102
|
+
return 0
|
|
103
|
+
|
|
104
|
+
# Normalize the command (collapse whitespace) for comparison.
|
|
105
|
+
norm_cmd = " ".join(cmd.split())
|
|
106
|
+
norm_hash = cksum(norm_cmd)
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
threshold = int(os.environ.get("DEV_TEAM_VERIFY_THRESHOLD", "3"))
|
|
110
|
+
except ValueError:
|
|
111
|
+
threshold = 3
|
|
112
|
+
|
|
113
|
+
prev = read_state(path)
|
|
114
|
+
prev_hash = str(prev.get("hash") or "")
|
|
115
|
+
prev_count = int(prev.get("count") or 0)
|
|
116
|
+
edited_since_prev = bool(prev.get("edited"))
|
|
117
|
+
|
|
118
|
+
# Consecutive count increments only when the exact same normalized
|
|
119
|
+
# command runs again with NO edit in between — an edit resets the
|
|
120
|
+
# counter exactly like a different command does (existing behavior).
|
|
121
|
+
if norm_hash == prev_hash and not edited_since_prev:
|
|
122
|
+
count = prev_count + 1
|
|
123
|
+
else:
|
|
124
|
+
count = 1
|
|
125
|
+
|
|
126
|
+
# Persist state. This run has "consumed" any pending edit signal, so
|
|
127
|
+
# the flag is cleared here; verify_guard_edit_marker.py sets it again
|
|
128
|
+
# the next time an Edit/Write/NotebookEdit call is observed.
|
|
129
|
+
write_state(path, {"hash": norm_hash, "count": count, "edited": False})
|
|
130
|
+
|
|
131
|
+
# Match the historical `[ "$count" -ge "$THRESHOLD" ]` semantics —
|
|
132
|
+
# threshold=0 always fires on the first run too. The "set to 0 to
|
|
133
|
+
# suppress" message is technically misleading for the advisory (byte
|
|
134
|
+
# parity with the original .sh is the contract there), but threshold=0
|
|
135
|
+
# DOES fully suppress the new block below: escalating a hook whose own
|
|
136
|
+
# docs claim to be a full opt-out would violate that opt-out.
|
|
137
|
+
if count < threshold:
|
|
138
|
+
return 0
|
|
139
|
+
|
|
140
|
+
if threshold <= 0:
|
|
141
|
+
print(
|
|
142
|
+
f"verify-guard: This verify command has run {count} consecutive "
|
|
143
|
+
"times without a code change."
|
|
144
|
+
)
|
|
145
|
+
print(
|
|
146
|
+
" If the tests are still failing, change the code rather than "
|
|
147
|
+
"re-running the same command."
|
|
148
|
+
)
|
|
149
|
+
print(" To suppress this warning, set DEV_TEAM_VERIFY_THRESHOLD=0.")
|
|
150
|
+
emit_boundary_event(
|
|
151
|
+
cwd, "verify_guard", "Bash", "warn", "verify-repeat-threshold", session_id
|
|
152
|
+
)
|
|
153
|
+
return 0
|
|
154
|
+
|
|
155
|
+
print(
|
|
156
|
+
f"[BLOCK] verify-guard: This verify command has run {count} "
|
|
157
|
+
"consecutive times without a code change."
|
|
158
|
+
)
|
|
159
|
+
print()
|
|
160
|
+
print(
|
|
161
|
+
" No Edit/Write/NotebookEdit happened between these runs — that's a "
|
|
162
|
+
"stuck loop, not TDD's RED/GREEN/REFACTOR pattern (which always has "
|
|
163
|
+
"a real edit between repeats of the same command)."
|
|
164
|
+
)
|
|
165
|
+
print(
|
|
166
|
+
" Run a systematic-debugging pass (see the systematic-debugging "
|
|
167
|
+
"skill) to find the root cause, then make the code change the "
|
|
168
|
+
"tests are waiting for before re-running this command."
|
|
169
|
+
)
|
|
170
|
+
print(
|
|
171
|
+
" If the root cause is understood but unresolvable in scope, stop "
|
|
172
|
+
"and escalate per /build's Escalation step instead of retrying "
|
|
173
|
+
"again."
|
|
174
|
+
)
|
|
175
|
+
print(" To suppress this block, set DEV_TEAM_VERIFY_THRESHOLD=0.")
|
|
176
|
+
emit_boundary_event(
|
|
177
|
+
cwd, "verify_guard", "Bash", "block", "verify-repeat-threshold", session_id
|
|
178
|
+
)
|
|
179
|
+
return 2
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
if __name__ == "__main__":
|
|
183
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""verify_guard_edit_marker.py — PreToolUse hook (#708), sibling of
|
|
3
|
+
verify_guard.py.
|
|
4
|
+
|
|
5
|
+
Matcher: `Write|Edit|NotebookEdit`. Stamps verify_guard.py's per-session
|
|
6
|
+
state file to record that a real code edit happened since the last
|
|
7
|
+
verify-class Bash command. verify_guard.py reads this flag to tell a
|
|
8
|
+
genuinely stuck loop (same verify command, zero intervening edits) apart
|
|
9
|
+
from ordinary TDD re-verification (RED, GREEN, REFACTOR each legitimately
|
|
10
|
+
re-run the same command, but each preceded by an edit) before escalating
|
|
11
|
+
to a hard block.
|
|
12
|
+
|
|
13
|
+
This hook itself never warns or blocks — it only records a fact for its
|
|
14
|
+
sibling to read.
|
|
15
|
+
|
|
16
|
+
Contract (docs/python-hook-contract.md):
|
|
17
|
+
Input : PreToolUse JSON on stdin (session_id, cwd)
|
|
18
|
+
Output: none
|
|
19
|
+
Exit : always 0 (silent-pass)
|
|
20
|
+
Env : TMPDIR
|
|
21
|
+
|
|
22
|
+
Stdlib-only. See docs/python-hook-contract.md.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import json
|
|
28
|
+
import sys
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
|
|
31
|
+
_HOOK_DIR = Path(__file__).resolve().parent
|
|
32
|
+
_LIB_DIR = _HOOK_DIR / "lib"
|
|
33
|
+
if str(_LIB_DIR) not in sys.path:
|
|
34
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
35
|
+
|
|
36
|
+
from verify_guard_state import (
|
|
37
|
+
read_state,
|
|
38
|
+
state_file,
|
|
39
|
+
state_key,
|
|
40
|
+
write_state,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _read_payload() -> dict:
|
|
45
|
+
try:
|
|
46
|
+
raw = sys.stdin.buffer.read()
|
|
47
|
+
except (OSError, ValueError):
|
|
48
|
+
return {}
|
|
49
|
+
try:
|
|
50
|
+
return json.loads(raw or b"{}")
|
|
51
|
+
except json.JSONDecodeError:
|
|
52
|
+
return {}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def main() -> int:
|
|
56
|
+
payload = _read_payload()
|
|
57
|
+
session_id = str(payload.get("session_id") or "")
|
|
58
|
+
cwd = str(payload.get("cwd") or "")
|
|
59
|
+
key = state_key(session_id, cwd)
|
|
60
|
+
path = state_file(key)
|
|
61
|
+
|
|
62
|
+
data = read_state(path)
|
|
63
|
+
data["edited"] = True
|
|
64
|
+
# Preserve existing hash/count if present; a session with no verify
|
|
65
|
+
# run yet simply gets an "edited" marker no verify_guard.py call will
|
|
66
|
+
# ever compare against (a differing/absent hash already resets its
|
|
67
|
+
# counter), so no need to seed hash/count here.
|
|
68
|
+
write_state(path, data)
|
|
69
|
+
return 0
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Python port of hooks/version-check.sh (#609 / #572 Phase 3).
|
|
3
|
+
|
|
4
|
+
Claude Code PostToolUse hook — checks once per day whether the plugin repo
|
|
5
|
+
has upstream updates. If updates are available, prints a notice suggesting
|
|
6
|
+
`/upgrade`.
|
|
7
|
+
|
|
8
|
+
Contract (docs/python-hook-contract.md):
|
|
9
|
+
Input : PostToolUse JSON on stdin (ignored)
|
|
10
|
+
Output: Update notice on stdout, or nothing if up-to-date
|
|
11
|
+
Cache : /tmp/adt-version-check-<date> — daily cache prevents repeated
|
|
12
|
+
checks; replays cached message if any
|
|
13
|
+
Exit : Always 0 (advisory, never blocks)
|
|
14
|
+
|
|
15
|
+
Stdlib-only. See docs/python-hook-contract.md.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import os
|
|
21
|
+
import subprocess
|
|
22
|
+
import sys
|
|
23
|
+
from datetime import datetime
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _cache_dir() -> Path:
|
|
28
|
+
"""Mirror the .sh's hard-coded `/tmp` for the daily cache path.
|
|
29
|
+
|
|
30
|
+
The bash script writes to `/tmp/adt-version-check-<date>` unconditionally
|
|
31
|
+
— no `${TMPDIR:-/tmp}` fallback. Windows Git Bash treats `/tmp` as the
|
|
32
|
+
MSYS-mounted temp directory, so the same literal is portable across the
|
|
33
|
+
three platforms this port targets. Byte-parity with the .sh requires
|
|
34
|
+
the same literal here.
|
|
35
|
+
|
|
36
|
+
``DEV_TEAM_VERSION_CHECK_CACHE_DIR``, when set, overrides this — a
|
|
37
|
+
test-only escape hatch (#1574) so pytest can give each worker/run its
|
|
38
|
+
own cache path instead of racing on the one real, shared `/tmp` file.
|
|
39
|
+
Production callers never set it, so real behavior is unchanged.
|
|
40
|
+
"""
|
|
41
|
+
override = os.environ.get("DEV_TEAM_VERSION_CHECK_CACHE_DIR")
|
|
42
|
+
return Path(override) if override else Path("/tmp")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _today_cache_file() -> Path:
|
|
46
|
+
# Local wall-clock date for a daily cache filename, not a comparison —
|
|
47
|
+
# mirrors the ported .sh's `date +%Y-%m-%d`, which also uses local time.
|
|
48
|
+
today = datetime.now().strftime("%Y-%m-%d") # noqa: DTZ005
|
|
49
|
+
return _cache_dir() / f"adt-version-check-{today}"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _plugin_dir() -> Path:
|
|
53
|
+
"""The plugin's repo root — one level up from hooks/."""
|
|
54
|
+
return Path(__file__).resolve().parent.parent
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _git(args, cwd: Path, timeout: float = 5.0):
|
|
58
|
+
"""Run git with the given args and cwd, capturing output. Returns the
|
|
59
|
+
CompletedProcess; caller inspects returncode. Any FileNotFoundError
|
|
60
|
+
(git absent) or timeout returns None."""
|
|
61
|
+
try:
|
|
62
|
+
return subprocess.run(
|
|
63
|
+
["git", "-C", str(cwd), *args],
|
|
64
|
+
capture_output=True,
|
|
65
|
+
text=True,
|
|
66
|
+
timeout=timeout,
|
|
67
|
+
check=False,
|
|
68
|
+
)
|
|
69
|
+
except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _is_git_repo(plugin_dir: Path) -> bool:
|
|
74
|
+
r = _git(["rev-parse", "--is-inside-work-tree"], plugin_dir, timeout=2.0)
|
|
75
|
+
return r is not None and r.returncode == 0
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _default_branch(plugin_dir: Path) -> str:
|
|
79
|
+
r = _git(["symbolic-ref", "refs/remotes/origin/HEAD"], plugin_dir, timeout=2.0)
|
|
80
|
+
if r is None or r.returncode != 0:
|
|
81
|
+
return "main"
|
|
82
|
+
ref = r.stdout.strip()
|
|
83
|
+
# Strip the `refs/remotes/origin/` prefix if present.
|
|
84
|
+
prefix = "refs/remotes/origin/"
|
|
85
|
+
if ref.startswith(prefix):
|
|
86
|
+
return ref[len(prefix) :]
|
|
87
|
+
return ref or "main"
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _fetch(plugin_dir: Path, timeout: float = 5.0) -> bool:
|
|
91
|
+
"""Fetch quietly with a short timeout. Returns True on success."""
|
|
92
|
+
r = _git(["fetch", "origin", "--quiet"], plugin_dir, timeout=timeout)
|
|
93
|
+
return r is not None and r.returncode == 0
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _commits_behind(plugin_dir: Path, branch: str) -> int:
|
|
97
|
+
r = _git(
|
|
98
|
+
["rev-list", "--count", f"HEAD..origin/{branch}"],
|
|
99
|
+
plugin_dir,
|
|
100
|
+
timeout=2.0,
|
|
101
|
+
)
|
|
102
|
+
if r is None or r.returncode != 0:
|
|
103
|
+
return 0
|
|
104
|
+
try:
|
|
105
|
+
return int(r.stdout.strip())
|
|
106
|
+
except ValueError:
|
|
107
|
+
return 0
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def main() -> int:
|
|
111
|
+
# Consume stdin (required by the hook protocol).
|
|
112
|
+
try:
|
|
113
|
+
sys.stdin.read()
|
|
114
|
+
except (OSError, ValueError):
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
cache_file = _today_cache_file()
|
|
118
|
+
if cache_file.is_file():
|
|
119
|
+
# Already checked today — replay cached message if any.
|
|
120
|
+
try:
|
|
121
|
+
cached = cache_file.read_text()
|
|
122
|
+
except OSError:
|
|
123
|
+
cached = ""
|
|
124
|
+
# Bash: `CACHED=$(cat "$CACHE_FILE")` strips trailing newlines the
|
|
125
|
+
# same way command substitution does. Then `[ -n "$CACHED" ] &&
|
|
126
|
+
# echo "$CACHED"` prints only when non-empty and re-adds one LF.
|
|
127
|
+
# Match both: rstrip newlines, print with a single trailing LF iff
|
|
128
|
+
# anything remains.
|
|
129
|
+
stripped = cached.rstrip("\n")
|
|
130
|
+
if stripped:
|
|
131
|
+
print(stripped)
|
|
132
|
+
return 0
|
|
133
|
+
|
|
134
|
+
plugin_dir = _plugin_dir()
|
|
135
|
+
|
|
136
|
+
if not _is_git_repo(plugin_dir):
|
|
137
|
+
# Not a git repo (vendored copy) — skip silently but cache.
|
|
138
|
+
try:
|
|
139
|
+
cache_file.touch()
|
|
140
|
+
except OSError:
|
|
141
|
+
pass
|
|
142
|
+
return 0
|
|
143
|
+
|
|
144
|
+
if not _fetch(plugin_dir):
|
|
145
|
+
# Network too slow / fetch failed — skip silently, don't cache so it
|
|
146
|
+
# retries later.
|
|
147
|
+
return 0
|
|
148
|
+
|
|
149
|
+
branch = _default_branch(plugin_dir)
|
|
150
|
+
behind = _commits_behind(plugin_dir, branch)
|
|
151
|
+
|
|
152
|
+
if behind > 0:
|
|
153
|
+
msg = (
|
|
154
|
+
f"📦 dev-team@bfinster: {behind} update(s) available. "
|
|
155
|
+
"Run /upgrade to update."
|
|
156
|
+
)
|
|
157
|
+
try:
|
|
158
|
+
cache_file.write_text(msg + "\n")
|
|
159
|
+
except OSError:
|
|
160
|
+
pass
|
|
161
|
+
print(msg)
|
|
162
|
+
else:
|
|
163
|
+
# Up to date — cache empty result so subsequent same-day fires skip.
|
|
164
|
+
try:
|
|
165
|
+
cache_file.touch()
|
|
166
|
+
except OSError:
|
|
167
|
+
pass
|
|
168
|
+
|
|
169
|
+
return 0
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
if __name__ == "__main__":
|
|
173
|
+
raise SystemExit(main())
|