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,262 @@
|
|
|
1
|
+
"""session_report_shared.py — building blocks common to both
|
|
2
|
+
session_report.py profiles (maintainer and downstream).
|
|
3
|
+
|
|
4
|
+
Split out of session_report.py (issue #2098) so the unified CLI has clear
|
|
5
|
+
domain layering: this module holds only what BOTH profiles need — the
|
|
6
|
+
session_log vocabulary aliases, schema constants, plugin-version resolution,
|
|
7
|
+
correction-cause classification, and skill/agent registry loading —
|
|
8
|
+
so session_report_maintainer.py and session_report_downstream.py each
|
|
9
|
+
import from here instead of each carrying their own copy.
|
|
10
|
+
|
|
11
|
+
PATH RESOLUTION (ADR 0032): this module lives at
|
|
12
|
+
plugins/dev-team/scripts/lib/, one level deeper than session_report.py
|
|
13
|
+
itself, so its own __file__-relative path resolution needs one more
|
|
14
|
+
`.parent` than the top-level CLI's did before the split.
|
|
15
|
+
|
|
16
|
+
Stdlib only (Python 3.10+ floor, ADR 0031).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import json
|
|
22
|
+
import re
|
|
23
|
+
import sys
|
|
24
|
+
from collections import Counter
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
_LIB_DIR = Path(__file__).resolve().parent
|
|
28
|
+
if str(_LIB_DIR) not in sys.path:
|
|
29
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
30
|
+
from session_log import classify, corrections, discovery, records, redact, signals
|
|
31
|
+
|
|
32
|
+
_redact = redact.redact
|
|
33
|
+
|
|
34
|
+
# --------------------------------------------------------------------------
|
|
35
|
+
# Shared classification/signal vocabulary (session_log.classify/.signals,
|
|
36
|
+
# issues #2042-#2044). Identical aliases in both predecessor scripts;
|
|
37
|
+
# defined once here and used, unmodified, by both profiles' extract logic.
|
|
38
|
+
# --------------------------------------------------------------------------
|
|
39
|
+
_VERIFY_RE = classify.VERIFY_RE
|
|
40
|
+
_CORRECTION_RE = classify.CORRECTION_RE
|
|
41
|
+
_PERMISSION_RE = classify.PERMISSION_RE
|
|
42
|
+
_OLDSTRING_RE = classify.OLDSTRING_RE
|
|
43
|
+
_EDIT_TOOLS = signals.EDIT_TOOLS
|
|
44
|
+
_GIT_GLOBAL_OPTS_WITH_ARG = classify.GIT_GLOBAL_OPTS_WITH_ARG
|
|
45
|
+
_COMMIT_BYPASS_TOKENS = classify.COMMIT_BYPASS_TOKENS
|
|
46
|
+
_statement_break_newlines = classify.statement_break_newlines
|
|
47
|
+
_bash_segments = classify.bash_segments
|
|
48
|
+
_is_git_commit_argv = classify.is_git_commit_argv
|
|
49
|
+
_SAFE_NAME_RE = classify.SAFE_NAME_RE
|
|
50
|
+
_UNSAFE_NAME = classify.UNSAFE_NAME
|
|
51
|
+
_HARNESS_ATTRIBUTIONS = classify.HARNESS_ATTRIBUTIONS
|
|
52
|
+
_MAIN_LABEL = "main"
|
|
53
|
+
_UNATTRIBUTED_LABEL = "unattributed"
|
|
54
|
+
_strip_ns = classify.strip_ns
|
|
55
|
+
_text_of = classify.text_of
|
|
56
|
+
|
|
57
|
+
_is_transcript_path = discovery.is_transcript_path
|
|
58
|
+
_is_subagent_transcript = discovery.is_subagent_transcript
|
|
59
|
+
# Two alias names for the same function (discovery.all_transcripts),
|
|
60
|
+
# matching each predecessor's own naming so each profile's body is
|
|
61
|
+
# otherwise unmodified.
|
|
62
|
+
_all_transcripts_under = discovery.all_transcripts
|
|
63
|
+
_all_transcripts = discovery.all_transcripts
|
|
64
|
+
_sorted_paths = discovery.sorted_paths
|
|
65
|
+
_relative_parts = discovery.relative_parts
|
|
66
|
+
|
|
67
|
+
_track_tool_call = signals.track_tool_call
|
|
68
|
+
_classify_tool_result = signals.classify_tool_result
|
|
69
|
+
_track_edit = signals.track_edit
|
|
70
|
+
_track_bash = signals.track_bash
|
|
71
|
+
_new_thread = signals.new_thread
|
|
72
|
+
_detect_correction_turn = signals.detect_correction_turn
|
|
73
|
+
_new_agent_bucket = signals.new_agent_bucket
|
|
74
|
+
_merge_agent_buckets = signals.merge_agent_buckets
|
|
75
|
+
_finalize_agent_buckets = signals.finalize_agent_buckets
|
|
76
|
+
_CONTEXT_TOKEN_FIELDS = signals.CONTEXT_TOKEN_FIELDS
|
|
77
|
+
_AGENT_BUCKET_FIELDS = signals.AGENT_BUCKET_FIELDS
|
|
78
|
+
_accumulate_skill_agent_signals = signals.accumulate_skill_agent_signals
|
|
79
|
+
_slim = records.slim_by_name
|
|
80
|
+
_iter_file_records = records.iter_file_records
|
|
81
|
+
|
|
82
|
+
# --------------------------------------------------------------------------
|
|
83
|
+
# Correction cause-data classification (session_log.corrections, #2013).
|
|
84
|
+
# --------------------------------------------------------------------------
|
|
85
|
+
_new_correction_context = corrections.new_context
|
|
86
|
+
_observe_assistant_turn = corrections.observe_assistant_turn
|
|
87
|
+
_classify_correction = corrections.classify_correction
|
|
88
|
+
|
|
89
|
+
_VERSION_RE = re.compile(r"^[0-9A-Za-z._+-]{1,32}$")
|
|
90
|
+
|
|
91
|
+
# --------------------------------------------------------------------------
|
|
92
|
+
# Schema versioning. See session_report.py's module docstring: both profiles
|
|
93
|
+
# bump to v3; the still-present predecessor scripts kept emitting v2
|
|
94
|
+
# unchanged (both predecessors were later retired in #2048).
|
|
95
|
+
# --------------------------------------------------------------------------
|
|
96
|
+
_DIGEST_SCHEMA = "session-digest/v4"
|
|
97
|
+
_SYNC_SCHEMA = "session-sync/v4"
|
|
98
|
+
#: Sync-record schemas a reader accepts, oldest first. Exported so
|
|
99
|
+
#: scripts/eval_rawlog.py (and any other reader) imports this constant
|
|
100
|
+
#: instead of literal-matching a schema string — the ADR 0036 failure mode
|
|
101
|
+
#: this guards against is a writer bumping the stamped schema while a
|
|
102
|
+
#: reader still exact-matches the old one, which silently drops every
|
|
103
|
+
#: record instead of erroring.
|
|
104
|
+
SYNC_SCHEMAS = (
|
|
105
|
+
"session-sync/v1",
|
|
106
|
+
"session-sync/v2",
|
|
107
|
+
"session-sync/v3",
|
|
108
|
+
"session-sync/v4",
|
|
109
|
+
)
|
|
110
|
+
_DOWNSTREAM_SCHEMA = "downstream-session-report/v4"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _load_plugin_version(plugin_root: Path | None = None) -> str:
|
|
114
|
+
"""Read `.claude-plugin/plugin.json`'s version. `plugin_root` defaults
|
|
115
|
+
to the dev-team plugin root (`plugins/dev-team/`) since both profiles
|
|
116
|
+
now resolve it the same way."""
|
|
117
|
+
if plugin_root is None:
|
|
118
|
+
plugin_root = Path(__file__).resolve().parent.parent.parent
|
|
119
|
+
manifest = Path(plugin_root) / ".claude-plugin" / "plugin.json"
|
|
120
|
+
try:
|
|
121
|
+
if manifest.stat().st_size > 64_000:
|
|
122
|
+
return "unknown"
|
|
123
|
+
data = json.loads(manifest.read_text(encoding="utf-8"))
|
|
124
|
+
version = data.get("version")
|
|
125
|
+
if isinstance(version, str) and _VERSION_RE.match(version):
|
|
126
|
+
return version
|
|
127
|
+
except (OSError, ValueError):
|
|
128
|
+
pass
|
|
129
|
+
return "unknown"
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _new_correction_causes_state() -> dict:
|
|
133
|
+
"""Fresh accumulator for correction cause-data (#2013): three label
|
|
134
|
+
Counters plus the ambiguous-shape tally, scoped to one `extract_*()`
|
|
135
|
+
call (across every transcript file it processes) -- NOT reset per
|
|
136
|
+
file, unlike `turn_context`/`active`/`thread` in each profile's loop."""
|
|
137
|
+
return {"by_what": Counter(), "by_component": Counter(), "by_shape": Counter(), "ambiguous": 0}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _record_correction_cause(state: dict, turn_context: dict, dispatch, text: str) -> None:
|
|
141
|
+
"""Classify one detected correction turn and fold it into `state`."""
|
|
142
|
+
cause = _classify_correction(turn_context, dispatch, text)
|
|
143
|
+
state["by_what"][cause["what"]] += 1
|
|
144
|
+
state["by_component"][cause["component"]] += 1
|
|
145
|
+
state["by_shape"][cause["shape"]] += 1
|
|
146
|
+
if cause["confidence"] == "low":
|
|
147
|
+
state["ambiguous"] += 1
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _finalize_correction_causes(state: dict, correction_turns: int) -> dict:
|
|
151
|
+
"""The `accuracy.correction_causes` object: three sorted label
|
|
152
|
+
breakdowns plus the honest inference-share statistic (issue #2013
|
|
153
|
+
acceptance: "the inference share reported rather than hidden")."""
|
|
154
|
+
return {
|
|
155
|
+
"by_what": dict(sorted(state["by_what"].items())),
|
|
156
|
+
"by_component": dict(sorted(state["by_component"].items())),
|
|
157
|
+
"by_shape": dict(sorted(state["by_shape"].items())),
|
|
158
|
+
"ambiguous_share": round(state["ambiguous"] / correction_turns, 4)
|
|
159
|
+
if correction_turns
|
|
160
|
+
else 0.0,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _correction_rate_map(numerator: Counter, denominator: Counter) -> dict:
|
|
165
|
+
"""Correction RATE per dispatch/invocation (issue #2013 acceptance:
|
|
166
|
+
"correction rate per dispatch is queryable by agent and by skill"),
|
|
167
|
+
mirroring `signals.finalize_agent_buckets`'s `context_per_dispatch`
|
|
168
|
+
pattern: a name with zero dispatches contributes no entry at all
|
|
169
|
+
(never a 0.0 that would misrank an uninvoked skill/agent as
|
|
170
|
+
"corrected 0% of the time")."""
|
|
171
|
+
return {
|
|
172
|
+
name: round(numerator.get(name, 0) / n, 4)
|
|
173
|
+
for name, n in sorted(denominator.items())
|
|
174
|
+
if n
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _first_cwd(jsonl: Path) -> str | None:
|
|
179
|
+
try:
|
|
180
|
+
with jsonl.open(encoding="utf-8") as fh:
|
|
181
|
+
for _ in range(20):
|
|
182
|
+
line = fh.readline()
|
|
183
|
+
if not line:
|
|
184
|
+
break
|
|
185
|
+
try:
|
|
186
|
+
rec = json.loads(line)
|
|
187
|
+
except json.JSONDecodeError:
|
|
188
|
+
continue
|
|
189
|
+
rec_cwd = rec.get("cwd")
|
|
190
|
+
if isinstance(rec_cwd, str) and rec_cwd:
|
|
191
|
+
return rec_cwd
|
|
192
|
+
except OSError:
|
|
193
|
+
pass
|
|
194
|
+
return None
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def resolve_session_plugin_version(session_id: str, boundary_events_path: Path) -> str:
|
|
198
|
+
"""Per-session plugin_version resolver (#2018).
|
|
199
|
+
|
|
200
|
+
Correlates `session_id` against its own `boundary-events.jsonl` records
|
|
201
|
+
— a stream `hooks/lib/boundary_events.py::emit_boundary_event` stamps
|
|
202
|
+
LIVE, at hook-dispatch time, with the plugin version actually checked
|
|
203
|
+
out at that moment (`boundary_events._load_plugin_version`, ~line 79 of
|
|
204
|
+
that module). This is the one place a session's OWN version is
|
|
205
|
+
recoverable at all — transcripts themselves carry no version tag.
|
|
206
|
+
|
|
207
|
+
Choice — EARLIEST matching event by `ts` wins: a session's plugin
|
|
208
|
+
version is ordinarily constant for its whole duration (the checked-out
|
|
209
|
+
plugin doesn't change mid-session in the common case), so any matching
|
|
210
|
+
event would agree: earliest is picked because it is the version active
|
|
211
|
+
at the point the session first did dispatched work, the most
|
|
212
|
+
defensible single answer for "which release produced this session's
|
|
213
|
+
signals" when the session's activity happens to span more than one
|
|
214
|
+
event. Documented limitation, deliberately not solved here: a session
|
|
215
|
+
that runs `/dev-team:upgrade` (or otherwise changes the checked-out
|
|
216
|
+
plugin) mid-session will have GENUINELY DIFFERENT versions among its
|
|
217
|
+
own boundary-events, and this resolver reports only the first — there
|
|
218
|
+
is no single correct answer for a session that spans two releases, and
|
|
219
|
+
picking one is a documented trade-off, not an oversight.
|
|
220
|
+
|
|
221
|
+
Falls back to the explicit string `"unknown"` — NEVER a live
|
|
222
|
+
`plugin.json` read — when the file is missing, unreadable, has no
|
|
223
|
+
record for this `session_id`, or every matching record's own
|
|
224
|
+
`plugin_version` fails validation (`_VERSION_RE`, the same bound this
|
|
225
|
+
module applies to every other externally-supplied version string).
|
|
226
|
+
|
|
227
|
+
Shared by both profiles: the maintainer profile's `cmd_sync` uses it to
|
|
228
|
+
stamp per-session sync records with the version that actually produced
|
|
229
|
+
them (#2018); the downstream profile's own version-filter machinery
|
|
230
|
+
(`sessions_matching_plugin_version`/`_sessions_with_known_plugin_version`)
|
|
231
|
+
solves a related but different question and lives in
|
|
232
|
+
session_report_downstream.py."""
|
|
233
|
+
best_ts: str | None = None
|
|
234
|
+
best_version: str | None = None
|
|
235
|
+
for rec in _iter_file_records(boundary_events_path):
|
|
236
|
+
if str(rec.get("session_id") or "") != session_id:
|
|
237
|
+
continue
|
|
238
|
+
version = rec.get("plugin_version")
|
|
239
|
+
if not (isinstance(version, str) and _VERSION_RE.match(version)):
|
|
240
|
+
continue
|
|
241
|
+
ts = rec.get("ts")
|
|
242
|
+
if not isinstance(ts, str):
|
|
243
|
+
continue
|
|
244
|
+
if best_ts is None or ts < best_ts:
|
|
245
|
+
best_ts = ts
|
|
246
|
+
best_version = version
|
|
247
|
+
return best_version or "unknown"
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def load_registry(plugin_root: Path | None = None) -> dict:
|
|
251
|
+
"""Enumerate shipped skills/agents so a digest/report can name
|
|
252
|
+
never-observed ones. `plugin_root` defaults the same way as
|
|
253
|
+
`_load_plugin_version` above."""
|
|
254
|
+
if plugin_root is None:
|
|
255
|
+
plugin_root = Path(__file__).resolve().parent.parent.parent
|
|
256
|
+
skills_dir = Path(plugin_root) / "skills"
|
|
257
|
+
agents_dir = Path(plugin_root) / "agents"
|
|
258
|
+
skills = sorted(p.name for p in skills_dir.iterdir()) if skills_dir.is_dir() else []
|
|
259
|
+
agents = (
|
|
260
|
+
sorted(p.stem for p in agents_dir.glob("*.md")) if agents_dir.is_dir() else []
|
|
261
|
+
)
|
|
262
|
+
return {"skills": skills, "agents": agents}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""Guard against machine-specific paths from graphify's Claude hook (#1367).
|
|
2
|
+
|
|
3
|
+
`graphify install --project` (via its `claude install` step) appends
|
|
4
|
+
PreToolUse hook entries to the target repo's shared, git-tracked
|
|
5
|
+
`.claude/settings.json`, using the absolute path to the graphify binary on
|
|
6
|
+
the installing machine (e.g. `/Users/alice/.local/bin/graphify`). If that
|
|
7
|
+
file is committed, it bakes one developer's home-directory path into the
|
|
8
|
+
repo and silently breaks for every other clone/teammate whose graphify
|
|
9
|
+
binary lives somewhere else (different username, different install method —
|
|
10
|
+
`uv tool`, `pipx`, `--user pip`, ... all resolve to different paths).
|
|
11
|
+
|
|
12
|
+
This module scans `.claude/settings.json` for any `PreToolUse` hook entry
|
|
13
|
+
that invokes graphify via an absolute filesystem path — instead of relying
|
|
14
|
+
on PATH — and relocates it into `.claude/settings.local.json` (already
|
|
15
|
+
gitignored, personal-machine scope). The scan is unconditional: it fixes a
|
|
16
|
+
repo that already carries the pollution from a past install just as well as
|
|
17
|
+
one guarding a fresh install, so `/project-init`/`/setup` can run it as a
|
|
18
|
+
standing check rather than only wrapping a live installer call.
|
|
19
|
+
|
|
20
|
+
No upstream flag exists to make `graphify` emit a bare, PATH-resolved
|
|
21
|
+
command instead of an absolute path (checked against installed graphify
|
|
22
|
+
0.9.8's `_resolve_graphify_exe`): it is a deliberate design choice, to keep
|
|
23
|
+
the hook working in environments where the venv Scripts/ directory isn't on
|
|
24
|
+
PATH (e.g. the VS Code Codex extension on Windows). Relocation, not an
|
|
25
|
+
upstream flag, is therefore the fix.
|
|
26
|
+
|
|
27
|
+
Stdlib-only, per ADR 0014/0015 (Python for cross-OS scripts).
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from __future__ import annotations
|
|
31
|
+
|
|
32
|
+
import json
|
|
33
|
+
import re
|
|
34
|
+
import traceback
|
|
35
|
+
from collections.abc import Callable
|
|
36
|
+
from pathlib import Path
|
|
37
|
+
|
|
38
|
+
_WINDOWS_ABSOLUTE = re.compile(r"^[A-Za-z]:[\\/]|^\\\\")
|
|
39
|
+
_PRE_TOOL_USE_KEY = "PreToolUse"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _pre_tool_use(settings: dict) -> list[dict]:
|
|
43
|
+
return settings.get("hooks", {}).get(_PRE_TOOL_USE_KEY, [])
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _load_json(path: Path) -> dict:
|
|
47
|
+
if not path.is_file():
|
|
48
|
+
return {}
|
|
49
|
+
text = path.read_text(encoding="utf-8").strip()
|
|
50
|
+
return json.loads(text) if text else {}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _dump_json(path: Path, data: dict) -> None:
|
|
54
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
55
|
+
path.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _command_is_absolute_graphify(command: str) -> bool:
|
|
59
|
+
token = command.strip().split(" ", 1)[0] if command.strip() else ""
|
|
60
|
+
if not token:
|
|
61
|
+
return False
|
|
62
|
+
is_absolute = token.startswith("/") or bool(_WINDOWS_ABSOLUTE.match(token))
|
|
63
|
+
if not is_absolute:
|
|
64
|
+
return False
|
|
65
|
+
basename = re.split(r"[\\/]", token)[-1]
|
|
66
|
+
if basename.lower().endswith(".exe"):
|
|
67
|
+
basename = basename[: -len(".exe")]
|
|
68
|
+
return basename.lower() == "graphify"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def find_absolute_graphify_entries(settings: dict) -> list[dict]:
|
|
72
|
+
"""Return `PreToolUse` entries whose command invokes graphify via an
|
|
73
|
+
absolute filesystem path rather than a bare, PATH-resolved `graphify`.
|
|
74
|
+
"""
|
|
75
|
+
polluting = []
|
|
76
|
+
for entry in _pre_tool_use(settings):
|
|
77
|
+
commands = (h.get("command", "") for h in entry.get("hooks", []))
|
|
78
|
+
if any(_command_is_absolute_graphify(c) for c in commands):
|
|
79
|
+
polluting.append(entry)
|
|
80
|
+
return polluting
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def fix_settings(settings_path: Path, local_settings_path: Path) -> bool:
|
|
84
|
+
"""Scan `settings_path` for absolute-path graphify hook entries and
|
|
85
|
+
relocate them into `local_settings_path`.
|
|
86
|
+
|
|
87
|
+
Returns True if anything was relocated, False if `settings_path` was
|
|
88
|
+
already clean (including when it doesn't exist).
|
|
89
|
+
"""
|
|
90
|
+
settings = _load_json(settings_path)
|
|
91
|
+
polluting = find_absolute_graphify_entries(settings)
|
|
92
|
+
if not polluting:
|
|
93
|
+
return False
|
|
94
|
+
|
|
95
|
+
remaining = [e for e in _pre_tool_use(settings) if e not in polluting]
|
|
96
|
+
if remaining:
|
|
97
|
+
settings.setdefault("hooks", {})[_PRE_TOOL_USE_KEY] = remaining
|
|
98
|
+
else:
|
|
99
|
+
settings.get("hooks", {}).pop(_PRE_TOOL_USE_KEY, None)
|
|
100
|
+
_dump_json(settings_path, settings)
|
|
101
|
+
|
|
102
|
+
local_settings = _load_json(local_settings_path)
|
|
103
|
+
local_pre_tool_use = local_settings.setdefault("hooks", {}).setdefault(
|
|
104
|
+
_PRE_TOOL_USE_KEY, []
|
|
105
|
+
)
|
|
106
|
+
for entry in polluting:
|
|
107
|
+
if entry not in local_pre_tool_use:
|
|
108
|
+
local_pre_tool_use.append(entry)
|
|
109
|
+
_dump_json(local_settings_path, local_settings)
|
|
110
|
+
|
|
111
|
+
return True
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def run_install_with_guard(
|
|
115
|
+
settings_path: Path,
|
|
116
|
+
local_settings_path: Path,
|
|
117
|
+
installer: Callable[[], None],
|
|
118
|
+
) -> bool:
|
|
119
|
+
"""Run `installer()` against `settings_path`, then apply `fix_settings`.
|
|
120
|
+
|
|
121
|
+
Returns True if a machine-specific hook entry was detected and relocated
|
|
122
|
+
to `local_settings_path`, False if the installer's output was left as-is.
|
|
123
|
+
|
|
124
|
+
`fix_settings` runs even if `installer()` itself raises partway through a
|
|
125
|
+
write (e.g. it appends the polluting hook entry and then fails later in
|
|
126
|
+
the same run) — it happens in a `finally` block, and the original
|
|
127
|
+
exception still propagates once the relocation completes. No separate
|
|
128
|
+
`_read_or_none`-style helper is needed here: `fix_settings` already reads
|
|
129
|
+
`settings_path` through `_load_json`, which returns `{}` rather than
|
|
130
|
+
raising when the file doesn't exist, so it never assumes the file is
|
|
131
|
+
present.
|
|
132
|
+
"""
|
|
133
|
+
was_relocated = False
|
|
134
|
+
installer_raised = False
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
installer()
|
|
138
|
+
except BaseException:
|
|
139
|
+
# Bound to THIS call, not read from ambient `sys.exc_info()` inside
|
|
140
|
+
# `finally` below — see the identical pattern (and rationale) in
|
|
141
|
+
# claude_md_guard.py's run_install_with_guard.
|
|
142
|
+
installer_raised = True
|
|
143
|
+
raise
|
|
144
|
+
finally:
|
|
145
|
+
try:
|
|
146
|
+
was_relocated = fix_settings(settings_path, local_settings_path)
|
|
147
|
+
except Exception:
|
|
148
|
+
# A secondary failure while relocating must never displace
|
|
149
|
+
# installer()'s own in-flight exception — see the identical
|
|
150
|
+
# pattern (and rationale) in claude_md_guard.py's
|
|
151
|
+
# run_install_with_guard.
|
|
152
|
+
if installer_raised:
|
|
153
|
+
traceback.print_exc()
|
|
154
|
+
else:
|
|
155
|
+
raise
|
|
156
|
+
|
|
157
|
+
return was_relocated
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""slug — shared repo-root slug derivation.
|
|
2
|
+
|
|
3
|
+
Single source of truth for the kebab-safe, lowercase slug both
|
|
4
|
+
`codebase_recon.py` (its `.claude/memory/recon-<slug>.json` artifact naming)
|
|
5
|
+
and `orchestrator.py` (its `_recon_artifact_path` lookup of that same
|
|
6
|
+
artifact) must agree on byte-for-byte — a drifted copy in either script
|
|
7
|
+
would silently compute the wrong artifact path. Promoted from two
|
|
8
|
+
hand-duplicated private copies (`codebase_recon.py::_derive_slug`,
|
|
9
|
+
`orchestrator.py::_derive_recon_slug`) per issue #2068, following this
|
|
10
|
+
directory's existing `from lib import ...` convention
|
|
11
|
+
(`codebase_recon.py` already imports `deterministic_recon` this way).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
_NON_SLUG_CHARS = re.compile(r"[^a-z0-9._-]")
|
|
20
|
+
_REPEATED_DASHES = re.compile(r"-{2,}")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def derive_slug(root: Path) -> str:
|
|
24
|
+
"""Derive a kebab-safe, lowercase slug from `root`'s resolved directory name.
|
|
25
|
+
|
|
26
|
+
Falls back to `"repo"` when the name has no slug-safe characters left
|
|
27
|
+
after stripping (e.g. an all-punctuation directory name).
|
|
28
|
+
"""
|
|
29
|
+
name = root.resolve().name.lower()
|
|
30
|
+
name = _NON_SLUG_CHARS.sub("-", name)
|
|
31
|
+
name = _REPEATED_DASHES.sub("-", name)
|
|
32
|
+
name = name.strip("-")
|
|
33
|
+
return name or "repo"
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""stub_extractors — per-language step-definition binding extractors for
|
|
2
|
+
`gherkin_stub_merge.py` (issue #1421).
|
|
3
|
+
|
|
4
|
+
A step-definition file is arbitrary general-purpose source code, unlike a
|
|
5
|
+
`.feature` file's fixed, line-anchored Gherkin grammar — so "next marker line
|
|
6
|
+
is the boundary" (the approach `gherkin_feature_merge.py` can safely use) is
|
|
7
|
+
not safe here. Each binding's body must instead be bounded by an actual
|
|
8
|
+
lexical scan of the source: brace/paren balance for JS/TS, Java, and C#
|
|
9
|
+
(`jsts.py`/`java.py`/`csharp.py`), or — for Go, which registers a step via a
|
|
10
|
+
single `sc.Step(pattern, funcName)` call referencing a separately-declared
|
|
11
|
+
top-level function — a lookup of that referenced function's own
|
|
12
|
+
brace-bounded body (`go.py`).
|
|
13
|
+
|
|
14
|
+
The brace/paren balance count is **lexically aware**, not a naive character
|
|
15
|
+
count: a `(`/`)`/`{`/`}` occurring inside a string/char literal or a
|
|
16
|
+
line/block comment is skipped, not counted (`_common.py`), so a step body
|
|
17
|
+
containing `const s = "}";` (or the C#/Go string-literal equivalents) can
|
|
18
|
+
never be mistaken for a boundary. When a file's brackets genuinely don't
|
|
19
|
+
balance, or a marker (a call, annotation, or attribute) has no attached,
|
|
20
|
+
boundable body, `parse_existing_steps` returns a structural-error sentinel
|
|
21
|
+
(`unbalanced-braces` / `dangling-annotation`) rather than guessing a span —
|
|
22
|
+
refusing the write is the safety property this package exists to provide.
|
|
23
|
+
|
|
24
|
+
Started as a single flat `_stub_extractors.py` module; split into this
|
|
25
|
+
sub-package once the single-file draft passed the ~300-line size ceiling
|
|
26
|
+
(plan-review structure finding) — one file per language plus one shared
|
|
27
|
+
lexer module keeps each file's responsibility narrow, rather than
|
|
28
|
+
reproducing `gherkin_feature_merge.py`'s five-plus-responsibility sprawl one
|
|
29
|
+
import hop down.
|
|
30
|
+
|
|
31
|
+
Reuses `lib._bdd_markers.MARKERS_BY_EXT` for the per-language pending-marker
|
|
32
|
+
table (extension -> (language label, marker substrings)) rather than
|
|
33
|
+
re-deriving it — a lib-level sibling import, not a reach into the parent
|
|
34
|
+
`scripts/` entry-point layer (issue #1421 bug 5: this package used to import
|
|
35
|
+
`gherkin_stub_gate`'s module-private `_MARKERS_BY_EXT` via a `sys.path`
|
|
36
|
+
insertion reaching up to `scripts/`, the only module under `scripts/lib/` in
|
|
37
|
+
the repo that imported from that parent layer).
|
|
38
|
+
|
|
39
|
+
Stdlib-only. (ADR 0014/0015).
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
from __future__ import annotations
|
|
43
|
+
|
|
44
|
+
from _bdd_markers import MARKERS_BY_EXT as _PENDING_MARKERS_BY_EXT
|
|
45
|
+
|
|
46
|
+
from . import csharp, go, java, jsts
|
|
47
|
+
from ._common import (
|
|
48
|
+
ERROR_DANGLING_ANNOTATION,
|
|
49
|
+
ERROR_UNBALANCED_BRACES,
|
|
50
|
+
ParseResult,
|
|
51
|
+
StepBinding,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
__all__ = [
|
|
55
|
+
"ERROR_DANGLING_ANNOTATION",
|
|
56
|
+
"ERROR_UNBALANCED_BRACES",
|
|
57
|
+
"ParseResult",
|
|
58
|
+
"StepBinding",
|
|
59
|
+
"parse_existing_steps",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
_PARSERS_BY_LANGUAGE = {
|
|
63
|
+
"JS/TS": jsts.parse,
|
|
64
|
+
"Java": java.parse,
|
|
65
|
+
"C#": csharp.parse,
|
|
66
|
+
"Go": go.parse,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def parse_existing_steps(text: str, ext: str) -> ParseResult:
|
|
71
|
+
"""Parse every step-definition binding in `text` for the language
|
|
72
|
+
implied by `ext` (matched case-insensitively, reusing
|
|
73
|
+
`lib._bdd_markers.MARKERS_BY_EXT`). Returns `ParseResult(bindings=[...],
|
|
74
|
+
error=None)` on success, or `ParseResult(bindings=None, error=<sentinel>)`
|
|
75
|
+
on the first structural problem encountered — never a partial, possibly-
|
|
76
|
+
wrong result."""
|
|
77
|
+
entry = _PENDING_MARKERS_BY_EXT.get(ext.lower())
|
|
78
|
+
if entry is None:
|
|
79
|
+
raise ValueError(f"unsupported step-definition extension: {ext!r}")
|
|
80
|
+
language, markers = entry
|
|
81
|
+
parser = _PARSERS_BY_LANGUAGE[language]
|
|
82
|
+
return parser(text, markers)
|