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.
Files changed (780) hide show
  1. package/LICENSE +21 -0
  2. package/PORTING.md +134 -0
  3. package/README.md +207 -0
  4. package/UPSTREAM.json +64 -0
  5. package/agents/Explore.md +15 -0
  6. package/agents/a11y-review.md +118 -0
  7. package/agents/adr-author.md +70 -0
  8. package/agents/ai-provenance-review.md +120 -0
  9. package/agents/angular-reactivity-review.md +95 -0
  10. package/agents/arch-review.md +135 -0
  11. package/agents/architect.md +78 -0
  12. package/agents/autoship-batch-proposer.md +69 -0
  13. package/agents/claude-setup-review.md +136 -0
  14. package/agents/codebase-recon.md +184 -0
  15. package/agents/component-architecture-review.md +119 -0
  16. package/agents/concurrency-review.md +109 -0
  17. package/agents/correctness-review.md +290 -0
  18. package/agents/data-flow-tracer.md +120 -0
  19. package/agents/doc-review.md +165 -0
  20. package/agents/domain-review.md +136 -0
  21. package/agents/general-purpose.md +10 -0
  22. package/agents/gherkin-quality-critic.md +113 -0
  23. package/agents/js-fp-review.md +114 -0
  24. package/agents/mutation-kill.md +684 -0
  25. package/agents/naming-review.md +142 -0
  26. package/agents/orchestrator.md +339 -0
  27. package/agents/performance-review.md +105 -0
  28. package/agents/plan-review-acceptance.md +115 -0
  29. package/agents/plan-review-design.md +90 -0
  30. package/agents/plan-review-parallelization.md +84 -0
  31. package/agents/plan-review-strategic.md +96 -0
  32. package/agents/plan-review-ux.md +110 -0
  33. package/agents/platform-engineer.md +64 -0
  34. package/agents/product-manager.md +68 -0
  35. package/agents/progress-guardian.md +79 -0
  36. package/agents/qa-engineer.md +289 -0
  37. package/agents/quality-reviewer.md +132 -0
  38. package/agents/react-reactivity-review.md +102 -0
  39. package/agents/refactor-opportunity-review.md +128 -0
  40. package/agents/security-engineer.md +60 -0
  41. package/agents/security-review.md +218 -0
  42. package/agents/session-analysis.md +95 -0
  43. package/agents/software-engineer.md +105 -0
  44. package/agents/spec-compliance-review.md +100 -0
  45. package/agents/spec-reviewer.md +114 -0
  46. package/agents/structure-review.md +146 -0
  47. package/agents/tech-writer.md +84 -0
  48. package/agents/test-review.md +246 -0
  49. package/agents/test-smell-review.md +188 -0
  50. package/agents/token-efficiency-review.md +139 -0
  51. package/agents/ui-ux-designer.md +54 -0
  52. package/agents/vue-reactivity-review.md +95 -0
  53. package/bin/__pycache__/claudecpython-314.pyc +0 -0
  54. package/bin/claude +258 -0
  55. package/docs/upstream/.pages +1 -0
  56. package/docs/upstream/CHANGELOG.md +2586 -0
  57. package/docs/upstream/README.md +155 -0
  58. package/docs/upstream/agent-architecture.md +214 -0
  59. package/docs/upstream/agent_info.md +187 -0
  60. package/docs/upstream/artifact-migration.md +124 -0
  61. package/docs/upstream/code-intelligence-nudge.md +149 -0
  62. package/docs/upstream/code-review-process.md +294 -0
  63. package/docs/upstream/concurrent-use.md +73 -0
  64. package/docs/upstream/context-management.md +111 -0
  65. package/docs/upstream/developer-notes.md +280 -0
  66. package/docs/upstream/diagrams/architecture-overview.svg +101 -0
  67. package/docs/upstream/diagrams/review-dispatch.svg +139 -0
  68. package/docs/upstream/diagrams/team-agents.svg +128 -0
  69. package/docs/upstream/diagrams/test-improve-flow.svg +166 -0
  70. package/docs/upstream/diagrams/workflow-linear.svg +66 -0
  71. package/docs/upstream/diagrams/workflow-three-phase.svg +200 -0
  72. package/docs/upstream/eval-maintenance.md +95 -0
  73. package/docs/upstream/eval-running-guide.md +147 -0
  74. package/docs/upstream/eval-system.md +291 -0
  75. package/docs/upstream/session-review-oss-complements.md +75 -0
  76. package/docs/upstream/session-review.md +212 -0
  77. package/docs/upstream/skills.md +188 -0
  78. package/docs/upstream/team-structure.md +21 -0
  79. package/docs/upstream/telemetry-ci-access.md +129 -0
  80. package/docs/upstream/telemetry-repo-security.md +120 -0
  81. package/docs/upstream/test-evaluation.md +277 -0
  82. package/docs/upstream/test-improve.md +154 -0
  83. package/docs/upstream/triage-workflow.md +282 -0
  84. package/docs/upstream/workflows.md +289 -0
  85. package/extensions/dev-team/index.ts +539 -0
  86. package/extensions/dev-team/lib/agents.ts +272 -0
  87. package/extensions/dev-team/lib/ai-credits.ts +92 -0
  88. package/extensions/dev-team/lib/autocompact.ts +81 -0
  89. package/extensions/dev-team/lib/child-run.ts +102 -0
  90. package/extensions/dev-team/lib/config.ts +236 -0
  91. package/extensions/dev-team/lib/gh-command.ts +103 -0
  92. package/extensions/dev-team/lib/github-style.ts +307 -0
  93. package/extensions/dev-team/lib/hooks.ts +350 -0
  94. package/extensions/dev-team/lib/metrics.ts +115 -0
  95. package/extensions/dev-team/lib/safe-read.ts +49 -0
  96. package/extensions/dev-team/lib/session-files.ts +57 -0
  97. package/extensions/dev-team/lib/session-spend.ts +123 -0
  98. package/extensions/dev-team/lib/shell-scan.ts +205 -0
  99. package/extensions/dev-team/lib/skills.ts +213 -0
  100. package/extensions/dev-team/lib/subagent-render.ts +245 -0
  101. package/extensions/dev-team/lib/subagent-types.ts +164 -0
  102. package/extensions/dev-team/lib/subagent.ts +596 -0
  103. package/extensions/dev-team/lib/terminal-text.ts +54 -0
  104. package/extensions/dev-team/lib/tools-misc.ts +152 -0
  105. package/extensions/dev-team/lib/transcript.ts +110 -0
  106. package/extensions/dev-team/lib/trust.ts +52 -0
  107. package/extensions/dev-team/lib/usage-breakdown.ts +176 -0
  108. package/extensions/dev-team/lib/usage-chart.ts +153 -0
  109. package/extensions/dev-team/lib/usage-command.ts +107 -0
  110. package/extensions/dev-team/lib/usage-history.ts +203 -0
  111. package/extensions/dev-team/lib/usage-render.ts +225 -0
  112. package/extensions/dev-team/lib/usage-split-bar.ts +127 -0
  113. package/extensions/dev-team/lib/usage-state.ts +116 -0
  114. package/extensions/dev-team/lib/usage-text.ts +159 -0
  115. package/extensions/dev-team/lib/usage-view.ts +109 -0
  116. package/hooks/__pycache__/refactor_test_freeze_guard.cpython-314.pyc +0 -0
  117. package/hooks/agent_dispatch_ledger.py +190 -0
  118. package/hooks/autocompact_setup_nudge.py +99 -0
  119. package/hooks/bash_retry_guard.py +228 -0
  120. package/hooks/boundary_events_write_guard.py +352 -0
  121. package/hooks/code_intelligence_nudge.py +293 -0
  122. package/hooks/code_intelligence_turn_mark.py +317 -0
  123. package/hooks/codegraph_bootstrap.py +139 -0
  124. package/hooks/contract_version_guard.py +362 -0
  125. package/hooks/cost_meter.py +106 -0
  126. package/hooks/destructive-commands.json +62 -0
  127. package/hooks/destructive_guard.py +477 -0
  128. package/hooks/eval_compliance_check.py +440 -0
  129. package/hooks/guards.json +17 -0
  130. package/hooks/hooks.json +323 -0
  131. package/hooks/internal_double_gate.py +296 -0
  132. package/hooks/js_fp_review.py +212 -0
  133. package/hooks/knowledge_index.py +119 -0
  134. package/hooks/lib/__pycache__/artifact_paths.cpython-314.pyc +0 -0
  135. package/hooks/lib/__pycache__/atomic_state.cpython-314.pyc +0 -0
  136. package/hooks/lib/__pycache__/autocompact_config.cpython-314.pyc +0 -0
  137. package/hooks/lib/__pycache__/boundary_events.cpython-314.pyc +0 -0
  138. package/hooks/lib/__pycache__/doc_classification.cpython-314.pyc +0 -0
  139. package/hooks/lib/__pycache__/gh_pr_create_detect.cpython-314.pyc +0 -0
  140. package/hooks/lib/__pycache__/git_safe_diff.cpython-314.pyc +0 -0
  141. package/hooks/lib/__pycache__/instrument_log.cpython-314.pyc +0 -0
  142. package/hooks/lib/__pycache__/metrics_query.cpython-314.pyc +0 -0
  143. package/hooks/lib/__pycache__/plugin_version.cpython-314.pyc +0 -0
  144. package/hooks/lib/__pycache__/pre_commit_doc_classifier.cpython-314.pyc +0 -0
  145. package/hooks/lib/__pycache__/review_agent_registry.cpython-314.pyc +0 -0
  146. package/hooks/lib/__pycache__/review_gate_corroboration.cpython-314.pyc +0 -0
  147. package/hooks/lib/__pycache__/review_gate_hash.cpython-314.pyc +0 -0
  148. package/hooks/lib/__pycache__/review_verdicts.cpython-314.pyc +0 -0
  149. package/hooks/lib/__pycache__/stdin_json.cpython-314.pyc +0 -0
  150. package/hooks/lib/__pycache__/stryker_invocation.cpython-314.pyc +0 -0
  151. package/hooks/lib/__pycache__/telemetry_consent.cpython-314.pyc +0 -0
  152. package/hooks/lib/__pycache__/test_file_classify.cpython-314.pyc +0 -0
  153. package/hooks/lib/__pycache__/token_efficiency_limits.cpython-314.pyc +0 -0
  154. package/hooks/lib/__pycache__/verify_guard_state.cpython-314.pyc +0 -0
  155. package/hooks/lib/__pycache__/xunit_v3_operator_gate.cpython-314.pyc +0 -0
  156. package/hooks/lib/agent_skill_hints.py +74 -0
  157. package/hooks/lib/artifact_paths.py +263 -0
  158. package/hooks/lib/atomic_state.py +557 -0
  159. package/hooks/lib/autocompact_config.py +103 -0
  160. package/hooks/lib/autoship_log.py +106 -0
  161. package/hooks/lib/banned_scripts_policy.py +51 -0
  162. package/hooks/lib/boundary_events.py +436 -0
  163. package/hooks/lib/build_knowledge_index.py +504 -0
  164. package/hooks/lib/build_skills_index.py +361 -0
  165. package/hooks/lib/build_state.py +116 -0
  166. package/hooks/lib/classify_ship_outcome.py +126 -0
  167. package/hooks/lib/config_changelog_schema.py +115 -0
  168. package/hooks/lib/cost_meter.py +955 -0
  169. package/hooks/lib/doc_classification.py +116 -0
  170. package/hooks/lib/gh_pr_create_detect.py +136 -0
  171. package/hooks/lib/git_safe_diff.py +123 -0
  172. package/hooks/lib/instrument_log.py +66 -0
  173. package/hooks/lib/iteration_journal_gate.py +197 -0
  174. package/hooks/lib/knowledge_index_paths.py +88 -0
  175. package/hooks/lib/mcp_json_repowise.py +177 -0
  176. package/hooks/lib/metrics_query.py +202 -0
  177. package/hooks/lib/minimal_yaml.py +434 -0
  178. package/hooks/lib/plugin_version.py +142 -0
  179. package/hooks/lib/pre_commit_detect.py +537 -0
  180. package/hooks/lib/pre_commit_doc_classifier.py +126 -0
  181. package/hooks/lib/pricing.py +118 -0
  182. package/hooks/lib/report_pdf.py +371 -0
  183. package/hooks/lib/review_agent_registry.py +142 -0
  184. package/hooks/lib/review_dispatch_ledger.py +101 -0
  185. package/hooks/lib/review_gate_corroboration.py +521 -0
  186. package/hooks/lib/review_gate_hash.py +252 -0
  187. package/hooks/lib/review_gate_normalized_hash.py +1115 -0
  188. package/hooks/lib/review_verdicts.py +301 -0
  189. package/hooks/lib/run_report.py +160 -0
  190. package/hooks/lib/skill_categories.yaml +125 -0
  191. package/hooks/lib/stdin_json.py +57 -0
  192. package/hooks/lib/stryker_invocation.py +102 -0
  193. package/hooks/lib/telemetry_consent.py +41 -0
  194. package/hooks/lib/telemetry_report.py +108 -0
  195. package/hooks/lib/test_file_classify.py +160 -0
  196. package/hooks/lib/token_efficiency_limits.py +51 -0
  197. package/hooks/lib/turn_identity.py +77 -0
  198. package/hooks/lib/verify_guard_state.py +110 -0
  199. package/hooks/lib/workflow_state.py +206 -0
  200. package/hooks/lib/xunit_v3_operator_gate.py +596 -0
  201. package/hooks/mcp_json_repowise_nudge.py +74 -0
  202. package/hooks/mutation_adapters/__init__.py +7 -0
  203. package/hooks/mutation_adapters/__pycache__/__init__.cpython-314.pyc +0 -0
  204. package/hooks/mutation_adapters/__pycache__/lib.cpython-314.pyc +0 -0
  205. package/hooks/mutation_adapters/__pycache__/mutmut.cpython-314.pyc +0 -0
  206. package/hooks/mutation_adapters/__pycache__/pitest.cpython-314.pyc +0 -0
  207. package/hooks/mutation_adapters/__pycache__/stryker.cpython-314.pyc +0 -0
  208. package/hooks/mutation_adapters/__pycache__/stryker_net.cpython-314.pyc +0 -0
  209. package/hooks/mutation_adapters/lib.py +478 -0
  210. package/hooks/mutation_adapters/mutmut.py +188 -0
  211. package/hooks/mutation_adapters/pitest.py +266 -0
  212. package/hooks/mutation_adapters/stryker.py +157 -0
  213. package/hooks/mutation_adapters/stryker_net.py +264 -0
  214. package/hooks/mutation_gate.py +193 -0
  215. package/hooks/mutation_testing_smoke_gate.py +371 -0
  216. package/hooks/pending_review_notify.py +121 -0
  217. package/hooks/phase_marker.py +138 -0
  218. package/hooks/post_compact_state_reinject.py +180 -0
  219. package/hooks/post_format.py +115 -0
  220. package/hooks/pre_commit_knowledge_index.py +128 -0
  221. package/hooks/pre_commit_review.py +66 -0
  222. package/hooks/pre_pr_review.py +694 -0
  223. package/hooks/pre_tool_guard.py +405 -0
  224. package/hooks/py.sh +73 -0
  225. package/hooks/refactor-bash-write-patterns.json +29 -0
  226. package/hooks/refactor_test_bash_guard.py +253 -0
  227. package/hooks/refactor_test_freeze_guard.py +139 -0
  228. package/hooks/refactor_test_revert_guard.py +186 -0
  229. package/hooks/repo_review_nudge.py +287 -0
  230. package/hooks/review_verdict_recorder.py +464 -0
  231. package/hooks/scan_bash_command_for_banned_scripts.py +428 -0
  232. package/hooks/scan_worktree_for_banned_scripts.py +238 -0
  233. package/hooks/session_learning_trigger.py +248 -0
  234. package/hooks/skills_index.py +126 -0
  235. package/hooks/stryker_xunit_shim_guard.py +571 -0
  236. package/hooks/subagent_completion_guard.py +309 -0
  237. package/hooks/subagent_skill_context.py +139 -0
  238. package/hooks/task_completion_metrics.py +216 -0
  239. package/hooks/tdd_guard.py +229 -0
  240. package/hooks/telemetry.py +341 -0
  241. package/hooks/token_efficiency_review.py +194 -0
  242. package/hooks/verify_guard.py +183 -0
  243. package/hooks/verify_guard_edit_marker.py +73 -0
  244. package/hooks/version_check.py +173 -0
  245. package/knowledge/accepted-risks-schema.md +98 -0
  246. package/knowledge/adr-decision-criteria.md +64 -0
  247. package/knowledge/adversarial-review-protocol.md +139 -0
  248. package/knowledge/agent-registry.md +228 -0
  249. package/knowledge/agent-review-methodology.md +80 -0
  250. package/knowledge/ai-friendly-repo-guidelines.md +67 -0
  251. package/knowledge/architecture-assessment.md +96 -0
  252. package/knowledge/artifact-lifecycle.md +57 -0
  253. package/knowledge/cd-maturity-model.md +82 -0
  254. package/knowledge/cd-test-architecture.md +190 -0
  255. package/knowledge/ci-cd-file-scope.md +24 -0
  256. package/knowledge/codegraph-vs-graphify.md +192 -0
  257. package/knowledge/component-test-patterns.md +139 -0
  258. package/knowledge/database-change-management.md +80 -0
  259. package/knowledge/database-test-patterns.md +79 -0
  260. package/knowledge/decision-defaults.md +88 -0
  261. package/knowledge/dependency-breaking-techniques.md +116 -0
  262. package/knowledge/deployment-pipeline.md +86 -0
  263. package/knowledge/design-smells.md +122 -0
  264. package/knowledge/directory-enumeration.md +38 -0
  265. package/knowledge/domain-modeling.md +123 -0
  266. package/knowledge/evidence-bundle.md +90 -0
  267. package/knowledge/exploratory-testing-field-guide.md +122 -0
  268. package/knowledge/failure-routing.md +28 -0
  269. package/knowledge/fixture-construction.md +56 -0
  270. package/knowledge/frontend-component-architecture.md +139 -0
  271. package/knowledge/gherkin-quality-review-dispatch.md +135 -0
  272. package/knowledge/index.json +6766 -0
  273. package/knowledge/internal-collaborator-doubling.md +101 -0
  274. package/knowledge/legacy-test-strategy.md +71 -0
  275. package/knowledge/long-run-waiting.md +66 -0
  276. package/knowledge/microservice-testing.md +71 -0
  277. package/knowledge/model-pricing.json +23 -0
  278. package/knowledge/mutation-score-formulas.md +60 -0
  279. package/knowledge/object-calisthenics.md +147 -0
  280. package/knowledge/oracle-provenance.md +94 -0
  281. package/knowledge/orchestrator-script-implementation.md +185 -0
  282. package/knowledge/owasp-detection.md +148 -0
  283. package/knowledge/plan-review-rubric.md +56 -0
  284. package/knowledge/proxy-connectivity.md +62 -0
  285. package/knowledge/reactive-effect-patterns.md +73 -0
  286. package/knowledge/recon-inventory-excludes.txt +32 -0
  287. package/knowledge/references/bdd-value-guide.md +61 -0
  288. package/knowledge/references/csharp-http-client-testing.md +264 -0
  289. package/knowledge/release-strategies.md +74 -0
  290. package/knowledge/report-output-location.md +117 -0
  291. package/knowledge/report-pdf-integration.md +63 -0
  292. package/knowledge/report-print.css +129 -0
  293. package/knowledge/report-template.md +114 -0
  294. package/knowledge/report-to-pdf.md +69 -0
  295. package/knowledge/request-processing-flow.md +63 -0
  296. package/knowledge/result-verification.md +52 -0
  297. package/knowledge/review-agent-output-contract.md +121 -0
  298. package/knowledge/review-lens-classification.md +113 -0
  299. package/knowledge/review-rubric.md +62 -0
  300. package/knowledge/review-template.md +104 -0
  301. package/knowledge/rule-fixtures/A02.insecure-random-js/negative.js +1 -0
  302. package/knowledge/rule-fixtures/A02.insecure-random-js/positive.js +1 -0
  303. package/knowledge/rule-fixtures/A02.weak-hashing-md5/negative.py +1 -0
  304. package/knowledge/rule-fixtures/A02.weak-hashing-md5/positive.py +1 -0
  305. package/knowledge/rule-fixtures/A03.command-injection/negative.js +1 -0
  306. package/knowledge/rule-fixtures/A03.command-injection/positive.js +1 -0
  307. package/knowledge/rule-fixtures/A03.sql-injection/negative.js +1 -0
  308. package/knowledge/rule-fixtures/A03.sql-injection/positive.js +1 -0
  309. package/knowledge/rule-fixtures/A03.xss-innerhtml/negative.js +1 -0
  310. package/knowledge/rule-fixtures/A03.xss-innerhtml/positive.js +1 -0
  311. package/knowledge/rule-fixtures/A05.cors-wildcard/negative.js +1 -0
  312. package/knowledge/rule-fixtures/A05.cors-wildcard/positive.js +1 -0
  313. package/knowledge/rule-fixtures/A05.default-credentials/negative.js +1 -0
  314. package/knowledge/rule-fixtures/A05.default-credentials/positive.js +1 -0
  315. package/knowledge/rule-fixtures/A07.jwt-alg-none/negative.js +1 -0
  316. package/knowledge/rule-fixtures/A07.jwt-alg-none/positive.js +1 -0
  317. package/knowledge/rule-fixtures/A08.binary-formatter/negative.cs +1 -0
  318. package/knowledge/rule-fixtures/A08.binary-formatter/positive.cs +1 -0
  319. package/knowledge/rule-fixtures/A08.js-eval/negative.js +1 -0
  320. package/knowledge/rule-fixtures/A08.js-eval/positive.js +1 -0
  321. package/knowledge/rule-fixtures/A08.object-input-stream/negative.java +1 -0
  322. package/knowledge/rule-fixtures/A08.object-input-stream/positive.java +1 -0
  323. package/knowledge/schemas/disposition-register-v1.json +65 -0
  324. package/knowledge/schemas/recon-envelope-v1.json +198 -0
  325. package/knowledge/schemas/unified-finding-v1.json +72 -0
  326. package/knowledge/security-primitives-contract.md +301 -0
  327. package/knowledge/security-review-rule-map.yaml +107 -0
  328. package/knowledge/skills-registry.md +72 -0
  329. package/knowledge/task-size-classifier.md +103 -0
  330. package/knowledge/telemetry-schema.md +881 -0
  331. package/knowledge/test-automation-maturity.md +56 -0
  332. package/knowledge/test-automation-principles.md +71 -0
  333. package/knowledge/test-cadence-tradeoffs.md +68 -0
  334. package/knowledge/test-doubles.md +105 -0
  335. package/knowledge/test-file-indicators.md +22 -0
  336. package/knowledge/test-layer-gates.md +35 -0
  337. package/knowledge/test-matrix-examples/django-batch.md +24 -0
  338. package/knowledge/test-matrix-examples/dotnet-grpc-fronting-api.md +90 -0
  339. package/knowledge/test-matrix-examples/dotnet-http-consumer.md +131 -0
  340. package/knowledge/test-matrix-examples/react-node-spa.md +24 -0
  341. package/knowledge/test-matrix-examples/spring-boot-service.md +25 -0
  342. package/knowledge/test-matrix-examples/ssr-htmx.md +24 -0
  343. package/knowledge/test-organization.md +70 -0
  344. package/knowledge/test-pyramid.md +84 -0
  345. package/knowledge/test-refactoring.md +67 -0
  346. package/knowledge/test-review-division-of-labor.md +85 -0
  347. package/knowledge/test-smells.md +80 -0
  348. package/knowledge/test-stack-profiles/bdd-frameworks.md +235 -0
  349. package/knowledge/test-stack-profiles/django.md +13 -0
  350. package/knowledge/test-stack-profiles/dotnet.md +18 -0
  351. package/knowledge/test-stack-profiles/go.md +16 -0
  352. package/knowledge/test-stack-profiles/node.md +16 -0
  353. package/knowledge/test-stack-profiles/react.md +12 -0
  354. package/knowledge/test-stack-profiles/spring-boot.md +16 -0
  355. package/knowledge/test-stack-profiles/ssr-htmx.md +14 -0
  356. package/knowledge/test-stack-profiles/vue.md +12 -0
  357. package/knowledge/test-strategy.md +70 -0
  358. package/knowledge/testability-patterns.md +240 -0
  359. package/knowledge/testing-quadrants.md +44 -0
  360. package/knowledge/testing-techniques/approval.md +15 -0
  361. package/knowledge/testing-techniques/chaos.md +17 -0
  362. package/knowledge/testing-techniques/fuzz.md +15 -0
  363. package/knowledge/testing-techniques/property-based.md +15 -0
  364. package/knowledge/testing-techniques/schema-validation.md +15 -0
  365. package/knowledge/testing-techniques/screenshot.md +15 -0
  366. package/knowledge/three-phase-workflow.md +198 -0
  367. package/knowledge/value-patterns.md +55 -0
  368. package/knowledge/verification-mode.md +116 -0
  369. package/knowledge/virtual-service-libraries.md +75 -0
  370. package/knowledge/wave-consolidation-guidance.md +21 -0
  371. package/overrides/agents/Explore.md +15 -0
  372. package/overrides/agents/general-purpose.md +10 -0
  373. package/overrides/notes/autoship.md +6 -0
  374. package/overrides/notes/issues-from-assessment.md +3 -0
  375. package/overrides/notes/issues-from-plan.md +3 -0
  376. package/overrides/notes/mutation-night-watch.md +3 -0
  377. package/overrides/notes/mutation-testing.md +3 -0
  378. package/overrides/notes/pr.md +7 -0
  379. package/overrides/notes/project-init.md +6 -0
  380. package/overrides/notes/setup.md +13 -0
  381. package/overrides/notes/specs.md +3 -0
  382. package/overrides/skills/headless-run/SKILL.md +45 -0
  383. package/overrides/skills/upgrade/SKILL.md +30 -0
  384. package/overrides/skills/version/SKILL.md +25 -0
  385. package/package.json +36 -0
  386. package/scripts/authoring_digest.py +93 -0
  387. package/scripts/autoship_discover.py +121 -0
  388. package/scripts/autoship_group.py +409 -0
  389. package/scripts/autoship_proposals.py +494 -0
  390. package/scripts/autoship_queue.py +291 -0
  391. package/scripts/autoship_reclaim.py +495 -0
  392. package/scripts/build_jobs.py +108 -0
  393. package/scripts/build_rollback_point.py +240 -0
  394. package/scripts/build_slice_scope.py +157 -0
  395. package/scripts/build_wave.py +109 -0
  396. package/scripts/build_wave_reconcile.py +252 -0
  397. package/scripts/build_worktree_baseref.py +113 -0
  398. package/scripts/check_agent_scope.py +117 -0
  399. package/scripts/check_agent_tool_mapping.py +213 -0
  400. package/scripts/check_review_agent_mcp_tools.py +317 -0
  401. package/scripts/check_security_assessment_mcp_tools.py +165 -0
  402. package/scripts/checkpoint_abort.py +502 -0
  403. package/scripts/claude_setup_review.py +438 -0
  404. package/scripts/codebase_recon.py +556 -0
  405. package/scripts/coverage_config.py +623 -0
  406. package/scripts/coverage_delta_steering.py +330 -0
  407. package/scripts/coverage_discovery_dotnet.py +315 -0
  408. package/scripts/coverage_discovery_java.py +742 -0
  409. package/scripts/coverage_discovery_js.py +546 -0
  410. package/scripts/coverage_gap_ranking.py +556 -0
  411. package/scripts/coverage_readiness.py +455 -0
  412. package/scripts/coverage_report_parse.py +521 -0
  413. package/scripts/detect_bdd_convention.py +252 -0
  414. package/scripts/eval_ablation.py +376 -0
  415. package/scripts/gherkin_analysis_coverage_gate.py +306 -0
  416. package/scripts/gherkin_cross_feature_duplicate_titles_gate.py +173 -0
  417. package/scripts/gherkin_effectiveness_rollup.py +238 -0
  418. package/scripts/gherkin_failure_path_gate.py +206 -0
  419. package/scripts/gherkin_feature_merge.py +720 -0
  420. package/scripts/gherkin_stub_gate.py +163 -0
  421. package/scripts/gherkin_stub_merge.py +479 -0
  422. package/scripts/git_origin_host.py +88 -0
  423. package/scripts/install-java-static-analysis.py +110 -0
  424. package/scripts/issue_deps.py +74 -0
  425. package/scripts/lib/_bdd_markers.py +28 -0
  426. package/scripts/lib/_gherkin_text.py +93 -0
  427. package/scripts/lib/_vendored_tree.py +70 -0
  428. package/scripts/lib/autoship_state.py +397 -0
  429. package/scripts/lib/claude_md_guard.py +226 -0
  430. package/scripts/lib/deterministic_recon.py +446 -0
  431. package/scripts/lib/mcp_tool_grants.py +211 -0
  432. package/scripts/lib/plan_parse.py +386 -0
  433. package/scripts/lib/review_result.py +84 -0
  434. package/scripts/lib/review_roster.py +86 -0
  435. package/scripts/lib/session_log/__init__.py +34 -0
  436. package/scripts/lib/session_log/__pycache__/__init__.cpython-314.pyc +0 -0
  437. package/scripts/lib/session_log/__pycache__/records.cpython-314.pyc +0 -0
  438. package/scripts/lib/session_log/classify.py +231 -0
  439. package/scripts/lib/session_log/corrections.py +194 -0
  440. package/scripts/lib/session_log/discovery.py +108 -0
  441. package/scripts/lib/session_log/records.py +218 -0
  442. package/scripts/lib/session_log/redact.py +76 -0
  443. package/scripts/lib/session_log/signals.py +373 -0
  444. package/scripts/lib/session_report_downstream.py +614 -0
  445. package/scripts/lib/session_report_maintainer.py +1273 -0
  446. package/scripts/lib/session_report_shared.py +262 -0
  447. package/scripts/lib/settings_hook_guard.py +157 -0
  448. package/scripts/lib/slug.py +33 -0
  449. package/scripts/lib/stub_extractors/__init__.py +82 -0
  450. package/scripts/lib/stub_extractors/_common.py +328 -0
  451. package/scripts/lib/stub_extractors/csharp.py +19 -0
  452. package/scripts/lib/stub_extractors/go.py +173 -0
  453. package/scripts/lib/stub_extractors/java.py +18 -0
  454. package/scripts/lib/stub_extractors/jsts.py +126 -0
  455. package/scripts/mutation_stack_sections.py +149 -0
  456. package/scripts/mutation_yield_steering.py +345 -0
  457. package/scripts/orchestrator.py +895 -0
  458. package/scripts/plan_gherkin_export.py +227 -0
  459. package/scripts/plan_waves.py +208 -0
  460. package/scripts/pr_close_keyword_lint.py +108 -0
  461. package/scripts/progress_guardian.py +888 -0
  462. package/scripts/recon_inventory.py +273 -0
  463. package/scripts/review_findings_log.py +93 -0
  464. package/scripts/run_invariants.py +124 -0
  465. package/scripts/select_lenses.py +640 -0
  466. package/scripts/session_report.py +486 -0
  467. package/scripts/set_autocompact_env.py +221 -0
  468. package/scripts/ship_resume_guard.py +135 -0
  469. package/scripts/ship_review_gate.py +63 -0
  470. package/scripts/specs_convention_marker.py +103 -0
  471. package/scripts/test_improve_resume.py +277 -0
  472. package/scripts/test_review_mechanics.py +958 -0
  473. package/scripts/token_efficiency_review.py +322 -0
  474. package/scripts/verdict_scope.py +285 -0
  475. package/scripts/verify_gherkin_quality_critic_isolation.py +296 -0
  476. package/scripts/verify_tier.py +157 -0
  477. package/skills/adr-tools/SKILL.md +118 -0
  478. package/skills/agent-readiness/SKILL.md +105 -0
  479. package/skills/agent-readiness/ai_friendly_analyzers.py +326 -0
  480. package/skills/agent-readiness/scanner.py +441 -0
  481. package/skills/agent-readiness/scorecard.yaml +88 -0
  482. package/skills/api-design/SKILL.md +115 -0
  483. package/skills/apply-fixes/SKILL.md +171 -0
  484. package/skills/apply-test-doubles/SKILL.md +321 -0
  485. package/skills/artifact-lifecycle/SKILL.md +127 -0
  486. package/skills/autoship/SKILL.md +1124 -0
  487. package/skills/benchmark/SKILL.md +105 -0
  488. package/skills/branch-workflow/SKILL.md +89 -0
  489. package/skills/browse/SKILL.md +184 -0
  490. package/skills/browser-testing/SKILL.md +62 -0
  491. package/skills/browser-testing/references/playwright-patterns.md +216 -0
  492. package/skills/build/SKILL.md +422 -0
  493. package/skills/build/references/static-self-heal.md +245 -0
  494. package/skills/careful/SKILL.md +72 -0
  495. package/skills/cd-test-architecture/SKILL.md +371 -0
  496. package/skills/ci-debugging/SKILL.md +105 -0
  497. package/skills/co-evolution-audit/SKILL.md +269 -0
  498. package/skills/code-review/SKILL.md +1015 -0
  499. package/skills/code-review/examples/aggregated-sample.json +56 -0
  500. package/skills/code-review/examples/sample-report.md +41 -0
  501. package/skills/code-review/output-format.md +478 -0
  502. package/skills/code-review/scripts/activation.py +86 -0
  503. package/skills/code-review/scripts/change_impact.py +357 -0
  504. package/skills/code-review/scripts/change_shape.py +372 -0
  505. package/skills/code-review/scripts/change_size.py +212 -0
  506. package/skills/code-review/scripts/changed_file_list.py +141 -0
  507. package/skills/code-review/scripts/closing_pass.py +187 -0
  508. package/skills/code-review/scripts/consolidate.py +277 -0
  509. package/skills/code-review/scripts/contract_failure_report.py +185 -0
  510. package/skills/code-review/scripts/dispatch_reconcile.py +66 -0
  511. package/skills/code-review/scripts/dispatch_waves.py +164 -0
  512. package/skills/code-review/scripts/finding_signature.py +446 -0
  513. package/skills/code-review/scripts/ledger.py +283 -0
  514. package/skills/code-review/scripts/partition.py +169 -0
  515. package/skills/code-review/scripts/render_tiered_findings.py +274 -0
  516. package/skills/code-review/scripts/repo_invariants.py +1066 -0
  517. package/skills/code-review/scripts/review_context_pack.py +306 -0
  518. package/skills/code-review/scripts/review_round_log.py +345 -0
  519. package/skills/code-review/scripts/review_value_coverage.py +297 -0
  520. package/skills/code-review/scripts/validate_review_output.py +467 -0
  521. package/skills/code-review/sliced-mode.md +205 -0
  522. package/skills/competitive-analysis/SKILL.md +191 -0
  523. package/skills/context-loading-protocol/SKILL.md +157 -0
  524. package/skills/continue/SKILL.md +90 -0
  525. package/skills/cost-report/SKILL.md +178 -0
  526. package/skills/coverage-baseline/SKILL.md +335 -0
  527. package/skills/coverage-baseline/references/multi-project-discovery.md +202 -0
  528. package/skills/coverage-delta/SKILL.md +181 -0
  529. package/skills/coverage-delta/references/mutation-gate.md +70 -0
  530. package/skills/design-doc/SKILL.md +95 -0
  531. package/skills/design-interrogation/SKILL.md +89 -0
  532. package/skills/design-it-twice/SKILL.md +91 -0
  533. package/skills/docker-image-audit/SKILL.md +108 -0
  534. package/skills/docker-image-audit/references/install-guide.md +64 -0
  535. package/skills/docker-image-audit/references/report-template.md +73 -0
  536. package/skills/docker-image-create/SKILL.md +185 -0
  537. package/skills/domain-analysis/SKILL.md +183 -0
  538. package/skills/domain-driven-design/SKILL.md +194 -0
  539. package/skills/exploratory-testing/SKILL.md +108 -0
  540. package/skills/explore/SKILL.md +51 -0
  541. package/skills/farley-score/SKILL.md +165 -0
  542. package/skills/feature-file-validation/SKILL.md +78 -0
  543. package/skills/feature-file-validation/references/validation-rules.md +115 -0
  544. package/skills/feedback-learning/SKILL.md +414 -0
  545. package/skills/fix/SKILL.md +450 -0
  546. package/skills/freeze/SKILL.md +68 -0
  547. package/skills/frontend-architecture/SKILL.md +113 -0
  548. package/skills/gherkin-derive/SKILL.md +630 -0
  549. package/skills/gherkin-public/SKILL.md +266 -0
  550. package/skills/governance-compliance/SKILL.md +150 -0
  551. package/skills/guard/SKILL.md +75 -0
  552. package/skills/handoff/SKILL.md +139 -0
  553. package/skills/handoff/references/summary-templates.md +242 -0
  554. package/skills/harness-audit/SKILL.md +751 -0
  555. package/skills/harness-audit/scripts/lesson_validate.py +386 -0
  556. package/skills/harness-audit/scripts/redundancy_criterion.py +188 -0
  557. package/skills/headless-run/SKILL.md +45 -0
  558. package/skills/headless-run/scripts/isolated_dispatch.py +381 -0
  559. package/skills/help/SKILL.md +72 -0
  560. package/skills/hexagonal-architecture/SKILL.md +85 -0
  561. package/skills/human-oversight-protocol/SKILL.md +224 -0
  562. package/skills/issues-from-assessment/SKILL.md +223 -0
  563. package/skills/issues-from-plan/SKILL.md +133 -0
  564. package/skills/legacy-code/SKILL.md +132 -0
  565. package/skills/mermaid-diagramming/SKILL.md +120 -0
  566. package/skills/mutation-night-watch/SKILL.md +154 -0
  567. package/skills/mutation-night-watch/references/scheduling.md +135 -0
  568. package/skills/mutation-testing/SKILL.md +396 -0
  569. package/skills/mutation-testing/references/languages/csharp-stryker-net.md +676 -0
  570. package/skills/mutation-testing/references/languages/go-go-mutesting.md +95 -0
  571. package/skills/mutation-testing/references/languages/java-pitest.md +77 -0
  572. package/skills/mutation-testing/references/languages/javascript-stryker.md +188 -0
  573. package/skills/mutation-testing/references/languages/python-mutmut.md +97 -0
  574. package/skills/mutation-testing/references/time-estimation.md +34 -0
  575. package/skills/mutation-testing/references/tool-detection.md +15 -0
  576. package/skills/mutation-testing/references/workflow-callers.md +23 -0
  577. package/skills/mutation-testing/scripts/__pycache__/xunit_v3_feature_detector.cpython-314.pyc +0 -0
  578. package/skills/mutation-testing/scripts/csharp_stryker_net_slice_runner.py +635 -0
  579. package/skills/mutation-testing/scripts/csharp_stryker_net_status_loop.py +525 -0
  580. package/skills/mutation-testing/scripts/csharp_stryker_net_wrapper.py +681 -0
  581. package/skills/mutation-testing/scripts/mutation_baseline_reuse.py +292 -0
  582. package/skills/mutation-testing/scripts/mutation_exclude_policy.py +268 -0
  583. package/skills/mutation-testing/scripts/mutation_feasibility_gate.py +463 -0
  584. package/skills/mutation-testing/scripts/mutation_kill_headless.py +331 -0
  585. package/skills/mutation-testing/scripts/mutation_kill_insert.py +199 -0
  586. package/skills/mutation-testing/scripts/mutation_kill_insert_python.py +150 -0
  587. package/skills/mutation-testing/scripts/mutation_kill_loop.py +869 -0
  588. package/skills/mutation-testing/scripts/mutation_kill_loop_python.py +949 -0
  589. package/skills/mutation-testing/scripts/mutation_kill_retry.py +592 -0
  590. package/skills/mutation-testing/scripts/mutation_kill_shared.py +620 -0
  591. package/skills/mutation-testing/scripts/mutation_nightwatch.py +462 -0
  592. package/skills/mutation-testing/scripts/mutation_nightwatch_stacks.py +425 -0
  593. package/skills/mutation-testing/scripts/mutation_report.py +743 -0
  594. package/skills/mutation-testing/scripts/mutation_report_cli.py +175 -0
  595. package/skills/mutation-testing/scripts/mutation_safety_gate.py +69 -0
  596. package/skills/mutation-testing/scripts/stryker_shard_pipeline.py +847 -0
  597. package/skills/mutation-testing/scripts/stryker_shard_setup.py +440 -0
  598. package/skills/mutation-testing/scripts/stryker_timeout_retry.py +142 -0
  599. package/skills/mutation-testing/scripts/xunit_v3_feature_detector.py +341 -0
  600. package/skills/performance-benchmark/SKILL.md +174 -0
  601. package/skills/performance-benchmark/examples/report-format.md +43 -0
  602. package/skills/performance-benchmark/references/benchmark-script.md +169 -0
  603. package/skills/performance-metrics/SKILL.md +265 -0
  604. package/skills/plan/SKILL.md +199 -0
  605. package/skills/plan/references/gherkin-persistence.md +43 -0
  606. package/skills/plan/references/plan-template.md +182 -0
  607. package/skills/pr/SKILL.md +289 -0
  608. package/skills/pr/scripts/gate_retry_state.py +368 -0
  609. package/skills/project-init/README.md +141 -0
  610. package/skills/project-init/SKILL.md +1197 -0
  611. package/skills/project-init/evals/evals.json +200 -0
  612. package/skills/project-init/references/capability-tools.md +55 -0
  613. package/skills/project-init/references/configs.md +221 -0
  614. package/skills/property-based-testing/SKILL.md +121 -0
  615. package/skills/property-based-testing/fixtures/invariant_fixture.py +15 -0
  616. package/skills/property-based-testing/fixtures/js-roundtrip/README.md +42 -0
  617. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/LICENSE +21 -0
  618. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/README.md +263 -0
  619. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/fast-check.d.ts +5165 -0
  620. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/fast-check.js +12147 -0
  621. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/package.json +3 -0
  622. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/types57/fast-check.d.ts +5165 -0
  623. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/fast-check.d.ts +5165 -0
  624. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/fast-check.js +12011 -0
  625. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/rolldown-runtime-D7D4PA-g.js +13 -0
  626. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/types57/fast-check.d.ts +5165 -0
  627. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/package.json +94 -0
  628. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/LICENSE +21 -0
  629. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/README.md +168 -0
  630. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/RandomGenerator-DcXj09Ch.d.ts +14 -0
  631. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformBigInt.d.ts +15 -0
  632. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformBigInt.js +38 -0
  633. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat32.d.ts +15 -0
  634. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat32.js +18 -0
  635. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat64.d.ts +15 -0
  636. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat64.js +22 -0
  637. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformInt.d.ts +15 -0
  638. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformInt.js +134 -0
  639. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/RandomGenerator-DcXj09Ch.d.ts +14 -0
  640. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformBigInt.d.ts +15 -0
  641. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformBigInt.js +37 -0
  642. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat32.d.ts +15 -0
  643. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat32.js +17 -0
  644. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat64.d.ts +15 -0
  645. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat64.js +21 -0
  646. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformInt.d.ts +15 -0
  647. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformInt.js +133 -0
  648. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/congruential32.d.ts +7 -0
  649. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/congruential32.js +44 -0
  650. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/mersenne.d.ts +7 -0
  651. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/mersenne.js +90 -0
  652. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xoroshiro128plus.d.ts +7 -0
  653. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xoroshiro128plus.js +80 -0
  654. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xorshift128plus.d.ts +7 -0
  655. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xorshift128plus.js +78 -0
  656. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/package.json +3 -0
  657. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/JumpableRandomGenerator.d.ts +16 -0
  658. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/JumpableRandomGenerator.js +0 -0
  659. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/RandomGenerator.d.ts +2 -0
  660. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/RandomGenerator.js +0 -0
  661. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/generateN.d.ts +6 -0
  662. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/generateN.js +8 -0
  663. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/purify.d.ts +12 -0
  664. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/purify.js +9 -0
  665. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/skipN.d.ts +6 -0
  666. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/skipN.js +6 -0
  667. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/congruential32.d.ts +7 -0
  668. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/congruential32.js +46 -0
  669. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/mersenne.d.ts +7 -0
  670. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/mersenne.js +92 -0
  671. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xoroshiro128plus.d.ts +7 -0
  672. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xoroshiro128plus.js +82 -0
  673. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xorshift128plus.d.ts +7 -0
  674. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xorshift128plus.js +80 -0
  675. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/JumpableRandomGenerator.d.ts +16 -0
  676. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/JumpableRandomGenerator.js +0 -0
  677. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/RandomGenerator.d.ts +2 -0
  678. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/RandomGenerator.js +0 -0
  679. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/generateN.d.ts +6 -0
  680. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/generateN.js +9 -0
  681. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/purify.d.ts +12 -0
  682. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/purify.js +10 -0
  683. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/skipN.d.ts +6 -0
  684. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/skipN.js +7 -0
  685. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/package.json +133 -0
  686. package/skills/property-based-testing/fixtures/js-roundtrip/package-lock.json +1179 -0
  687. package/skills/property-based-testing/fixtures/js-roundtrip/package.json +14 -0
  688. package/skills/property-based-testing/fixtures/js-roundtrip/roundtrip.js +29 -0
  689. package/skills/property-based-testing/fixtures/js-roundtrip/roundtrip.properties.test.js +16 -0
  690. package/skills/property-based-testing/fixtures/no_property_fixture.py +10 -0
  691. package/skills/property-based-testing/fixtures/roundtrip_fixture.py +16 -0
  692. package/skills/property-based-testing/references/languages/javascript.md +54 -0
  693. package/skills/property-based-testing/scripts/detect_and_dispatch.py +80 -0
  694. package/skills/property-based-testing/scripts/hypothesis_scaffold.py +276 -0
  695. package/skills/proxy-resilience/SKILL.md +84 -0
  696. package/skills/quality-gate-pipeline/SKILL.md +184 -0
  697. package/skills/quality-targets-converge/SKILL.md +254 -0
  698. package/skills/repo-review/SKILL.md +159 -0
  699. package/skills/report-pdf/SKILL.md +66 -0
  700. package/skills/review/SKILL.md +47 -0
  701. package/skills/review-agent/SKILL.md +152 -0
  702. package/skills/review-summary/SKILL.md +73 -0
  703. package/skills/run-report/SKILL.md +70 -0
  704. package/skills/semantic-duplication-scan/SKILL.md +337 -0
  705. package/skills/semantic-scan/SKILL.md +53 -0
  706. package/skills/semgrep-analyze/SKILL.md +139 -0
  707. package/skills/setup/SKILL.md +1122 -0
  708. package/skills/ship/SKILL.md +240 -0
  709. package/skills/source-verification/SKILL.md +210 -0
  710. package/skills/source-verification/scripts/claim_extractor.py +155 -0
  711. package/skills/specs/.size-baseline.json +4 -0
  712. package/skills/specs/SKILL.md +243 -0
  713. package/skills/specs/references/completeness-checklist.md +83 -0
  714. package/skills/specs/references/extraction.md +58 -0
  715. package/skills/specs/references/glossary.md +59 -0
  716. package/skills/specs/references/persistence.md +115 -0
  717. package/skills/specs/references/predictability-check.md +77 -0
  718. package/skills/static-analysis-integration/SKILL.md +235 -0
  719. package/skills/static-analysis-integration/adapters/_envelope.py +26 -0
  720. package/skills/static-analysis-integration/adapters/jscpd-adapter.py +66 -0
  721. package/skills/static-analysis-integration/adapters/lizard-adapter.py +81 -0
  722. package/skills/static-analysis-integration/adapters/mypy-adapter.py +50 -0
  723. package/skills/static-analysis-integration/adapters/mypy-src-layout.py +93 -0
  724. package/skills/static-analysis-integration/adapters/security-review-adapter.py +212 -0
  725. package/skills/static-analysis-integration/maintenance.md +23 -0
  726. package/skills/static-analysis-integration/references/language-setup.md +228 -0
  727. package/skills/static-analysis-integration/references/sarif-parser.md +124 -0
  728. package/skills/static-analysis-integration/references/security-review-adapter.md +118 -0
  729. package/skills/static-analysis-integration/references/tool-configs.md +617 -0
  730. package/skills/static-analysis-integration/rulesets/pmd-quickstart.xml +24 -0
  731. package/skills/stryker-xunit-v2-shim/SKILL.md +274 -0
  732. package/skills/stryker-xunit-v2-shim/references/shim-howto.md +256 -0
  733. package/skills/stryker-xunit-v2-shim/scripts/generate_shim.py +143 -0
  734. package/skills/systematic-debugging/SKILL.md +130 -0
  735. package/skills/telemetry/SKILL.md +75 -0
  736. package/skills/test-audit-disable/SKILL.md +129 -0
  737. package/skills/test-design/SKILL.md +177 -0
  738. package/skills/test-design/scripts/__pycache__/internal_double_detector.cpython-314.pyc +0 -0
  739. package/skills/test-design/scripts/internal_double_detector.py +631 -0
  740. package/skills/test-design-advisor/SKILL.md +166 -0
  741. package/skills/test-driven-development/SKILL.md +169 -0
  742. package/skills/test-health/SKILL.md +262 -0
  743. package/skills/test-improve/SKILL.md +239 -0
  744. package/skills/test-improve/references/phase-0-approach-contract.md +228 -0
  745. package/skills/test-improve/references/phase-1-analyze.md +131 -0
  746. package/skills/test-improve/references/phase-2-baseline.md +121 -0
  747. package/skills/test-improve/references/phase-3-derive-gherkin.md +53 -0
  748. package/skills/test-improve/references/phase-4-plan-fixes.md +34 -0
  749. package/skills/test-improve/references/phase-5-improve.md +215 -0
  750. package/skills/test-improve/references/phase-6-refactor-decision.md +45 -0
  751. package/skills/test-improve/references/phase-7-refactor.md +44 -0
  752. package/skills/test-improve/references/phase-8-validate.md +66 -0
  753. package/skills/test-improve/references/phase-9-close-out-prompt.md +11 -0
  754. package/skills/test-improve/references/phase-9-report.md +62 -0
  755. package/skills/test-improve/references/review-loop.md +92 -0
  756. package/skills/test-improve/templates/executive-summary.md +123 -0
  757. package/skills/threat-modeling/SKILL.md +108 -0
  758. package/skills/triage/SKILL.md +211 -0
  759. package/skills/ubiquitous-language/SKILL.md +192 -0
  760. package/skills/ubiquitous-language/scripts/collect_domain_signals.py +300 -0
  761. package/skills/unfreeze/SKILL.md +37 -0
  762. package/skills/upgrade/SKILL.md +31 -0
  763. package/skills/upgrade/scripts/check_version_drift.py +113 -0
  764. package/skills/upgrade/scripts/enable_autoupdate.py +149 -0
  765. package/skills/version/SKILL.md +25 -0
  766. package/sync/__pycache__/sync_upstream.cpython-314.pyc +0 -0
  767. package/sync/sync_upstream.py +293 -0
  768. package/templates/ACCEPTED-RISKS.md.tmpl +46 -0
  769. package/templates/agents/agent-template.md +151 -0
  770. package/templates/agents/angular-testing.md +66 -0
  771. package/templates/agents/csharp-quality.md +63 -0
  772. package/templates/agents/esm-enforcer.md +52 -0
  773. package/templates/agents/front-end-testing.md +65 -0
  774. package/templates/agents/go-quality.md +65 -0
  775. package/templates/agents/python-quality.md +62 -0
  776. package/templates/agents/react-testing.md +61 -0
  777. package/templates/agents/ts-enforcer.md +60 -0
  778. package/templates/agents/twelve-factor-audit.md +49 -0
  779. package/tools/entropy-check.py +250 -0
  780. package/tools/model-hash-verify.py +213 -0
@@ -0,0 +1,116 @@
1
+ /**
2
+ * The state machine behind the /dev-team usage overlay: which scope and view are shown and how the
3
+ * this-month load is going. Pure: `reduce` maps a state and an action (a key, or news from the load)
4
+ * to the next state plus the effects the view must carry out (start or cancel the load, close), so
5
+ * every rule is testable without pi or a terminal. Mapping raw terminal input to a UsageKey lives
6
+ * here too, as it is the machine's other input.
7
+ */
8
+ import { Key, type KeyId, matchesKey } from "@earendil-works/pi-tui";
9
+
10
+ export type Scope = "session" | "month";
11
+ export type View = "model" | "provider" | "agent";
12
+
13
+ /**
14
+ * The this-month history load. It outlives the scope: "ready" is kept when the user goes back to this
15
+ * session, so pressing `s` again shows the loaded month at once. A cancelled or failed load is "idle"
16
+ * again, so `s` restarts it. In this-session scope the load is therefore only ever idle or ready.
17
+ */
18
+ export type LoadState =
19
+ | { kind: "idle" }
20
+ | { kind: "loading"; progress?: { done: number; total: number } }
21
+ | { kind: "ready" }
22
+ | { kind: "error"; reason: string };
23
+
24
+ export interface UsageState {
25
+ scope: Scope;
26
+ view: View;
27
+ load: LoadState;
28
+ }
29
+
30
+ /** What a key press means, independent of which key produced it. */
31
+ export type UsageKey = "next-view" | "previous-view" | "toggle-scope" | "close";
32
+
33
+ export type UsageAction =
34
+ | { type: "key"; key: UsageKey }
35
+ | { type: "progress"; done: number; total: number }
36
+ | { type: "loaded" }
37
+ | { type: "failed"; reason: string };
38
+
39
+ /** What the view must do besides re-render. */
40
+ export type UsageEffect = "start-load" | "cancel-load" | "close";
41
+
42
+ export interface Transition {
43
+ state: UsageState;
44
+ effects: UsageEffect[];
45
+ }
46
+
47
+ /** Left to right as Tab walks them. */
48
+ const VIEWS: readonly View[] = ["model", "provider", "agent"];
49
+
50
+ const LOADING: LoadState = { kind: "loading" };
51
+ const IDLE: LoadState = { kind: "idle" };
52
+
53
+ /** The state a freshly opened overlay starts in: By model, with the month's load started when it opens on the month. */
54
+ export function openUsage(scope: Scope): Transition {
55
+ if (scope === "month") return { state: { scope, view: "model", load: LOADING }, effects: ["start-load"] };
56
+ return { state: { scope, view: "model", load: IDLE }, effects: [] };
57
+ }
58
+
59
+ function stepView(state: UsageState, step: number): Transition {
60
+ const next = VIEWS[(VIEWS.indexOf(state.view) + step + VIEWS.length) % VIEWS.length];
61
+ return { state: { ...state, view: next }, effects: [] };
62
+ }
63
+
64
+ /** `s`: this session to this month (loading it unless already loaded), and back (cancelling a load still running). */
65
+ function toggleScope(state: UsageState): Transition {
66
+ if (state.scope === "session") {
67
+ if (state.load.kind === "ready") return { state: { ...state, scope: "month" }, effects: [] };
68
+ return { state: { ...state, scope: "month", load: LOADING }, effects: ["start-load"] };
69
+ }
70
+ const cancelling = state.load.kind === "loading";
71
+ const load = state.load.kind === "ready" ? state.load : IDLE;
72
+ return { state: { ...state, scope: "session", load }, effects: cancelling ? ["cancel-load"] : [] };
73
+ }
74
+
75
+ function pressKey(state: UsageState, key: UsageKey): Transition {
76
+ switch (key) {
77
+ case "next-view":
78
+ return stepView(state, 1);
79
+ case "previous-view":
80
+ return stepView(state, -1);
81
+ case "toggle-scope":
82
+ return toggleScope(state);
83
+ case "close":
84
+ return { state, effects: state.load.kind === "loading" ? ["cancel-load", "close"] : ["close"] };
85
+ }
86
+ }
87
+
88
+ /** News about the load only counts while one is running: a late event from a cancelled load is dropped. */
89
+ function loadEvent(state: UsageState, action: Exclude<UsageAction, { type: "key" }>): Transition {
90
+ if (state.load.kind !== "loading") return { state, effects: [] };
91
+ switch (action.type) {
92
+ case "progress":
93
+ return { state: { ...state, load: { kind: "loading", progress: { done: action.done, total: action.total } } }, effects: [] };
94
+ case "loaded":
95
+ return { state: { ...state, load: { kind: "ready" } }, effects: [] };
96
+ case "failed":
97
+ return { state: { ...state, load: { kind: "error", reason: action.reason } }, effects: [] };
98
+ }
99
+ }
100
+
101
+ export function reduce(state: UsageState, action: UsageAction): Transition {
102
+ return action.type === "key" ? pressKey(state, action.key) : loadEvent(state, action);
103
+ }
104
+
105
+ /** Letters match in either case (`s` and `S`); Shift+Tab is its own key, so it steps back. */
106
+ const KEY_TABLE: readonly { key: UsageKey; ids: readonly KeyId[] }[] = [
107
+ { key: "next-view", ids: [Key.tab] },
108
+ { key: "previous-view", ids: [Key.shift("tab")] },
109
+ { key: "toggle-scope", ids: ["s", Key.shift("s")] },
110
+ { key: "close", ids: [Key.escape, "q", Key.shift("q"), Key.ctrl("c")] },
111
+ ];
112
+
113
+ /** The action a chunk of terminal input stands for, or undefined for any other key. */
114
+ export function usageKeyFor(data: string): UsageKey | undefined {
115
+ return KEY_TABLE.find(({ ids }) => ids.some((id) => matchesKey(data, id)))?.key;
116
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * The plain-text usage summary for /dev-team usage when no overlay can be shown (print mode, RPC),
3
+ * and the wording both it and the overlay (usage-render.ts) use: scope names, view titles, header
4
+ * pieces, empty-state, failure and footnote sentences. Keeping the sentences here is what keeps the
5
+ * two presentations saying the same thing.
6
+ */
7
+ import { formatAiCredits, formatCredits, hasVisibleCredits, usageMonthStart } from "./ai-credits.ts";
8
+ import {
9
+ formatShare,
10
+ formatTokens,
11
+ formatUsd,
12
+ hasUsage,
13
+ type MonthSnapshot,
14
+ type SpendAmounts,
15
+ THREAD_ORDER,
16
+ type UsageBreakdown,
17
+ type UsageRow,
18
+ } from "./usage-breakdown.ts";
19
+ import type { BarChartOptions, ChartFormat } from "./usage-chart.ts";
20
+ import { toSpacedSingleLine, toSingleLine } from "./terminal-text.ts";
21
+ import type { Scope, View } from "./usage-state.ts";
22
+
23
+ export const SEPARATOR = " · ";
24
+ export const SCOPE_TITLE: Record<Scope, string> = { session: "This session", month: "This month" };
25
+ export const SCOPE_NOUN: Record<Scope, string> = { session: "this session", month: "this month" };
26
+ export const VIEW_TITLE: Record<View, string> = { model: "By model", provider: "By provider", agent: "By agent" };
27
+ /** Joins an agent and its provider in an agent row's label. */
28
+ export const AGENT_PROVIDER_SEPARATOR = " · ";
29
+ /** The chart area's text while this month's files are read; the overlay appends the progress. */
30
+ export const READING_SESSIONS = "Reading sessions…";
31
+
32
+ /** "in this session", "this month": how a sentence refers to the scope. */
33
+ export const scopePhrase = (scope: Scope) => (scope === "session" ? "in this session" : "this month");
34
+
35
+ const monthDay = (date: Date) => date.toLocaleDateString("en-US", { month: "short", day: "numeric", timeZone: "UTC" });
36
+
37
+ /** "This session", or "This month (Oct 1 – Oct 4)": the month's UTC dates, 1st to `now`. */
38
+ export function scopeHeading(scope: Scope, now: Date): string {
39
+ if (scope === "session") return SCOPE_TITLE.session;
40
+ return `${SCOPE_TITLE.month} (${monthDay(usageMonthStart(now))} – ${monthDay(now)})`;
41
+ }
42
+
43
+ /** "as of 14:05": local time, so it reads against the user's own clock. */
44
+ export const asOfLabel = (date: Date) => `as of ${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
45
+
46
+ /** A row's AI credits in a column: "210 cr", or "" when Copilot served none of it. */
47
+ export const formatCreditsCell = (credits: number) => (hasVisibleCredits(credits) ? `${formatCredits(credits)} cr` : "");
48
+
49
+ /** How the chart and the summary write each amount. */
50
+ export const CHART_FORMAT: ChartFormat = { usd: formatUsd, credits: formatCreditsCell, tokens: formatTokens, share: formatShare };
51
+
52
+ /**
53
+ * The optional columns a view's rows want, for the overlay's chart and the text summary alike: AI
54
+ * credits when any row has some, tokens when any row cost nothing (so a free model still says what it
55
+ * used). Judged over every row, before the chart folds any into "other".
56
+ */
57
+ export function wantedColumns(rows: readonly UsageRow[]): BarChartOptions["wantedColumns"] {
58
+ return { credits: rows.some((r) => hasVisibleCredits(r.credits)), tokens: rows.some((r) => !(r.usd > 0)) };
59
+ }
60
+
61
+ /** The total as header parts: "$4.20", then "312 AI credits" when Copilot served any of it. USD is always first. */
62
+ export function totalHeaderParts(total: SpendAmounts): string[] {
63
+ return [formatUsd(total.usd), ...(hasVisibleCredits(total.credits) ? [formatAiCredits(total.credits)] : [])];
64
+ }
65
+
66
+ /** The ranked rows of a view; an agent row is labelled "agent · provider". */
67
+ export function viewRows(view: View, breakdown: UsageBreakdown): UsageRow[] {
68
+ if (view === "model") return breakdown.byModel;
69
+ if (view === "provider") return breakdown.byProvider;
70
+ return breakdown.byAgent.map((row) => ({ ...row, label: `${row.label}${AGENT_PROVIDER_SEPARATOR}${row.provider}` }));
71
+ }
72
+
73
+ /** One split of the total: its parts in drawing order, each with its USD and share of the total. */
74
+ export interface SplitSection {
75
+ title: "Providers" | "Threads";
76
+ /** How the overlay's legend names a part's amount. */
77
+ legend: "share" | "usd";
78
+ parts: { label: string; usd: number; share: number }[];
79
+ }
80
+
81
+ /**
82
+ * The splits both presentations show. Providers: only when two or more have a cost, the paid ones in
83
+ * rank order. Threads: always main, subagents, overhead, in that order; a thread that spent nothing
84
+ * stays with 0 so it keeps its place and its glyph. None when nothing cost anything.
85
+ */
86
+ export function splitSections(breakdown: UsageBreakdown): SplitSection[] {
87
+ const total = breakdown.total.usd;
88
+ if (!(total > 0)) return [];
89
+ const part = (label: string, usd: number) => ({ label, usd, share: usd / total });
90
+ const paidProviders = breakdown.byProvider.filter((r) => r.usd > 0);
91
+ const providers: SplitSection[] = paidProviders.length > 1 ? [{ title: "Providers", legend: "share", parts: paidProviders.map((r) => part(r.label, r.usd)) }] : [];
92
+ const threadUsd = new Map(breakdown.byThread.map((r) => [r.label, r.usd]));
93
+ return [...providers, { title: "Threads", legend: "usd", parts: THREAD_ORDER.map((label) => part(label, threadUsd.get(label) ?? 0)) }];
94
+ }
95
+
96
+ export const emptyUsageMessage = (scope: Scope) => `No usage ${scopePhrase(scope)}`;
97
+ export const noSubagentUsageMessage = (scope: Scope) => `No subagent usage ${scopePhrase(scope)}`;
98
+
99
+ /** Appended to the empty session message: this month may have spend even when this session has none. */
100
+ export const pressSHint = (scope: Scope) => (scope === "session" ? " — press s for this month" : "");
101
+
102
+ /** The reason is an error's message and may carry escape sequences, control characters or newlines: sequences go, each run of controls becomes one space. */
103
+ export const loadFailedMessage = (reason: string) => `Could not load history: ${toSpacedSingleLine(reason)}`;
104
+
105
+ /** The text of whatever a load rejected with. */
106
+ export const errorReason = (err: unknown): string => (err instanceof Error ? err.message : String(err));
107
+
108
+ /** The footnote for session files that could not be read, or undefined when every file was. */
109
+ export function unreadableFilesNote(unreadable: number): string | undefined {
110
+ return unreadable > 0 ? `${unreadable} session ${unreadable === 1 ? "file" : "files"} could not be read` : undefined;
111
+ }
112
+
113
+ export interface UsageSummaryInput {
114
+ scope: Scope;
115
+ breakdown: UsageBreakdown;
116
+ now: Date;
117
+ /** Present for this month: how the load went. */
118
+ month?: Omit<MonthSnapshot, "breakdown">;
119
+ }
120
+
121
+ /** Rows as aligned " label usd credits tokens share" lines, with the columns wantedColumns() asks for. */
122
+ function rankedLines(rows: readonly UsageRow[]): string[] {
123
+ const columns = wantedColumns(rows);
124
+ const cells = rows.map((r) => [
125
+ toSingleLine(r.label),
126
+ CHART_FORMAT.usd(r.usd),
127
+ ...(columns.credits ? [CHART_FORMAT.credits(r.credits)] : []),
128
+ ...(columns.tokens ? [CHART_FORMAT.tokens(r.tokens)] : []),
129
+ CHART_FORMAT.share(r.share),
130
+ ]);
131
+ const widths = cells[0].map((_, column) => Math.max(...cells.map((row) => row[column].length)));
132
+ return cells.map((row) => ` ${row.map((cell, column) => (column === 0 ? cell.padEnd(widths[column]) : cell.padStart(widths[column]))).join(" ")}`);
133
+ }
134
+
135
+ /** "Providers github-copilot $3.12 74.3% · openai $1.08 25.7%": the parts that spent something. */
136
+ function splitLine({ title, parts }: SplitSection): string {
137
+ const spent = parts.filter((p) => p.usd > 0);
138
+ return `${title} ${spent.map((p) => `${toSingleLine(p.label)} ${formatUsd(p.usd)} ${formatShare(p.share)}`).join(SEPARATOR)}`;
139
+ }
140
+
141
+ /** Header, the provider and thread splits, then models, providers and agents ranked; or the empty-state sentence. Either way the unreadable-files note ends it, as in the overlay. */
142
+ export function usageSummary({ scope, breakdown, now, month }: UsageSummaryInput): string {
143
+ const note = unreadableFilesNote(month?.unreadable ?? 0);
144
+ const noteLines = note ? ["", note] : [];
145
+ if (!hasUsage(breakdown.total)) return [emptyUsageMessage(scope), ...noteLines].join("\n");
146
+ const header = [scopeHeading(scope, now), ...totalHeaderParts(breakdown.total), ...(month ? [asOfLabel(month.loadedAt)] : [])].join(SEPARATOR);
147
+ const section = (view: View) => {
148
+ const rows = viewRows(view, breakdown);
149
+ return ["", VIEW_TITLE[view], ...(rows.length ? rankedLines(rows) : [` ${noSubagentUsageMessage(scope)}`])];
150
+ };
151
+ return [
152
+ header,
153
+ ...splitSections(breakdown).map(splitLine),
154
+ ...section("model"),
155
+ ...section("provider"),
156
+ ...section("agent"),
157
+ ...noteLines,
158
+ ].join("\n");
159
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * The /dev-team usage overlay component. It holds the state machine's state (usage-state.ts), turns
3
+ * keys into transitions, runs this month's load and hands the model to renderUsage (usage-render.ts).
4
+ */
5
+ import type { Component } from "@earendil-works/pi-tui";
6
+ import type { SpendRun } from "./session-spend.ts";
7
+ import { type MonthSnapshot, monthSnapshot, type UsageBreakdown, usageBreakdown } from "./usage-breakdown.ts";
8
+ import type { LoadOptions, SpendHistory } from "./usage-history.ts";
9
+ import { usageMonthStart } from "./ai-credits.ts";
10
+ import { renderUsage, type UsageStyle } from "./usage-render.ts";
11
+ import { reduce, type Transition, type UsageAction, type UsageEffect, type UsageState, usageKeyFor } from "./usage-state.ts";
12
+ import { errorReason } from "./usage-text.ts";
13
+
14
+ /** The overlay may take this share of the terminal's height; the command passes the same to pi as `maxHeight`. */
15
+ export const OVERLAY_HEIGHT_PERCENT = 90;
16
+
17
+ export interface UsageViewDeps {
18
+ /** This session's runs; read again after `invalidate()`. */
19
+ sessionRuns(): readonly SpendRun[];
20
+ now(): Date;
21
+ /** The terminal's height in rows. */
22
+ terminalRows(): number;
23
+ style: UsageStyle;
24
+ requestRender(): void;
25
+ /** Closes the overlay. */
26
+ close(): void;
27
+ /** Reads this month's spend from the saved sessions; the view cancels it through `signal`. */
28
+ loadHistory(options: Required<Omit<LoadOptions, "root">>): Promise<SpendHistory>;
29
+ }
30
+
31
+ /** The overlay component: owns the state, turns keys into transitions, runs the month's load and renders the model. */
32
+ export class UsageView implements Component {
33
+ private readonly deps: UsageViewDeps;
34
+ private state: UsageState;
35
+ private session: UsageBreakdown | undefined;
36
+ private month: MonthSnapshot | undefined;
37
+ /** The load in flight. Whatever else holds a different controller (or none) is a stale load whose news is dropped. */
38
+ private activeLoad: AbortController | undefined;
39
+
40
+ constructor(deps: UsageViewDeps, initial: Transition) {
41
+ this.deps = deps;
42
+ this.state = initial.state;
43
+ this.runEffects(initial.effects);
44
+ }
45
+
46
+ render(width: number): string[] {
47
+ this.session ??= usageBreakdown(this.deps.sessionRuns());
48
+ const height = Math.max(1, Math.floor((this.deps.terminalRows() * OVERLAY_HEIGHT_PERCENT) / 100));
49
+ return renderUsage({ state: this.state, session: this.session, month: this.month, now: this.deps.now() }, { width, height, style: this.deps.style });
50
+ }
51
+
52
+ handleInput(data: string): void {
53
+ const key = usageKeyFor(data);
54
+ if (key) this.dispatch({ type: "key", key });
55
+ }
56
+
57
+ invalidate(): void {
58
+ this.session = undefined;
59
+ }
60
+
61
+ /** Called by pi when the overlay goes away; a load still running is of no use any more. */
62
+ dispose(): void {
63
+ this.cancelLoad();
64
+ }
65
+
66
+ private dispatch(action: UsageAction): void {
67
+ const { state, effects } = reduce(this.state, action);
68
+ this.state = state;
69
+ this.runEffects(effects);
70
+ this.deps.requestRender();
71
+ }
72
+
73
+ private runEffects(effects: readonly UsageEffect[]): void {
74
+ for (const effect of effects) {
75
+ if (effect === "start-load") this.startLoad();
76
+ else if (effect === "cancel-load") this.cancelLoad();
77
+ else this.deps.close();
78
+ }
79
+ }
80
+
81
+ private startLoad(): void {
82
+ const controller = new AbortController();
83
+ this.activeLoad = controller;
84
+ const isCurrentLoad = () => this.activeLoad === controller;
85
+ const since = usageMonthStart(this.deps.now());
86
+ const onProgress = (done: number, total: number) => {
87
+ if (isCurrentLoad()) this.dispatch({ type: "progress", done, total });
88
+ };
89
+ // The snapshot is built inside the async function, so anything it throws is a failed load too.
90
+ (async () => monthSnapshot(await this.deps.loadHistory({ since, signal: controller.signal, onProgress }), this.deps.now()))().then(
91
+ (snapshot) => {
92
+ if (!isCurrentLoad()) return;
93
+ this.activeLoad = undefined;
94
+ this.month = snapshot;
95
+ this.dispatch({ type: "loaded" });
96
+ },
97
+ (err: unknown) => {
98
+ if (!isCurrentLoad()) return;
99
+ this.activeLoad = undefined;
100
+ this.dispatch({ type: "failed", reason: errorReason(err) });
101
+ },
102
+ );
103
+ }
104
+
105
+ private cancelLoad(): void {
106
+ this.activeLoad?.abort();
107
+ this.activeLoad = undefined;
108
+ }
109
+ }
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env python3
2
+ """agent_dispatch_ledger.py — PreToolUse dispatch-ledger hook (#1461).
3
+
4
+ Registered in `settings.json`'s existing `PreToolUse` `"Agent|Task"` matcher
5
+ (alongside `subagent_skill_context.py`). Records a `boundary-events.jsonl`
6
+ `"record"` event whenever a genuine review-agent dispatch fires, so
7
+ `hooks/pre_commit_review.py`'s `.review-passed` gate can later corroborate
8
+ that a hash-matching write was backed by real, independent Agent-tool
9
+ dispatches — not just a self-computed hash (issue #1461's residual gap; see
10
+ `hooks/lib/review_gate_hash.py`'s own docstring for the full account).
11
+
12
+ On each Agent/Task dispatch, reads `tool_input.subagent_type`. If and only if
13
+ it is present in `hooks/lib/review_agent_registry`'s closed set of registered
14
+ `agents/*-review.md` stems, records one `"record"` boundary event carrying
15
+ that agent name as `matched_rule`, stamped with a `subject_hash` binding this
16
+ dispatch to whatever content is under review right now, so a review of one
17
+ changeset can't later corroborate an unrelated one (#1461 security review).
18
+ Anything not in the closed set — a typo, a non-review team agent, or a
19
+ fabricated name — is silently NOT recorded, never written as free text:
20
+ matching `boundary_events.py`'s own no-free-text constraint (rule IDs /
21
+ closed-vocabulary values only, never arbitrary strings). `"record"` is a new,
22
+ fifth-plus decision value: an observation, not a block/warn/bypass/
23
+ intervention/revert policy verdict — see `knowledge/telemetry-schema.md` for
24
+ its full documentation.
25
+
26
+ **`subject_hash` selection (#1904 Bug 2b, revised from the original
27
+ staged-diff-only stamp):** the staged patch (`review_gate_hash()`) is empty
28
+ by definition during a `--since <base>`-scoped `/code-review` run
29
+ (`skills/pr/SKILL.md`'s only path to `gh pr create` — its step 1 requires a
30
+ CLEAN working tree before that review runs, so nothing is ever staged during
31
+ it). Stamping the constant `EMPTY_DIGEST` in that case would be exactly the
32
+ Bug 1 hazard `review_gate_hash.py`'s own docstring warns against, AND it
33
+ would leave this hook's evidence unable to corroborate
34
+ `hooks/pre_pr_review.py`'s gate at all for that mode (that gate always
35
+ compares against `branch_diff_gate_hash()`, never the staged-diff hash).
36
+ So: when the staged diff is empty, fall back to
37
+ `branch_diff_gate_hash(default_base_ref(cwd), cwd)` — the SAME content
38
+ domain `hooks/pre_pr_review.py` checks and `skills/code-review/SKILL.md`
39
+ step 9 now writes for a `--since <base>`-scoped review — and refuse to stamp
40
+ (`None`) rather than fall back to the empty digest a second time. The
41
+ ordinary auto-scope path (something IS staged) is unchanged: it still stamps
42
+ `review_gate_hash()`, matching step 9's own disclosed "identical only in the
43
+ common single-commit-then-PR shape" limitation for that mode.
44
+
45
+ Fail-open, matching this codebase's own hook convention (and
46
+ `emit_boundary_event`'s own fail-open write side): any error here — a
47
+ missing/unreadable `agents/` directory, a malformed payload, an exception
48
+ from the shared helper — must never block a real Agent dispatch. This hook
49
+ always exits 0.
50
+
51
+ KNOWN RESIDUAL GAP (#1461 security re-review): this module is itself a
52
+ directly executable script that reads an attacker-/self-controlled stdin
53
+ payload. Anyone with Bash access to this repo can run
54
+ `echo '{"tool_name":"Task","tool_input":{"subagent_type":"security-review"},
55
+ "cwd":"."}' | python3 hooks/agent_dispatch_ledger.py` (repeated with a second
56
+ registered agent stem) and produce two byte-genuine "record" rows, correctly
57
+ subject-hash-bound, with NO actual Agent/Task dispatch ever occurring. Locking
58
+ down `boundary_events.py`'s CLI (this module's sibling forgery vector) does
59
+ not close this one — the forge just moves one file over. Registered agent
60
+ names are public filenames, so the registry re-validation in
61
+ `review_gate_corroboration.py` does not help either. This is not fixable at
62
+ this module's level: it requires the harness itself to supply something a
63
+ hand-run process cannot fabricate (a signed dispatch receipt, or a
64
+ session/turn-identity check against a live stream the harness — not this
65
+ script — controls). Until that exists, this control raises the bar against
66
+ an agent that takes an *accidental* self-certification shortcut under
67
+ ambiguity (this issue's original, observed failure mode); it is not effective
68
+ against a deliberate, adversarial bypass. See
69
+ `hooks/pre_commit_review.py`'s module docstring for the matching disclosure
70
+ on the read side.
71
+
72
+ Contract (docs/python-hook-contract.md):
73
+ Input : PreToolUse JSON on stdin (Agent/Task matcher)
74
+ Output: always exit 0 — fail-open, this hook never blocks a dispatch.
75
+
76
+ Stdlib only. See ADR 0014 / ADR 0015.
77
+ """
78
+
79
+ from __future__ import annotations
80
+
81
+ import sys
82
+ from pathlib import Path
83
+
84
+ _HOOK_DIR = Path(__file__).resolve().parent
85
+ _LIB_DIR = _HOOK_DIR / "lib"
86
+ if str(_LIB_DIR) not in sys.path:
87
+ sys.path.insert(0, str(_LIB_DIR))
88
+
89
+ from boundary_events import emit_boundary_event as _emit_boundary_event
90
+ from review_agent_registry import is_registered_review_lens, strip_plugin_prefix
91
+ from review_gate_hash import (
92
+ EMPTY_DIGEST,
93
+ branch_diff_gate_hash,
94
+ default_base_ref,
95
+ review_gate_hash,
96
+ )
97
+ from stdin_json import read_stdin_json
98
+
99
+
100
+ def emit_boundary_event(*args, **kwargs) -> None:
101
+ """Local safety net (#859): even a misbehaving helper must never affect
102
+ this hook's exit code, stdout, or stderr."""
103
+ try:
104
+ _emit_boundary_event(*args, **kwargs)
105
+ except Exception: # noqa: BLE001, S110 - fail-open by design
106
+ pass
107
+
108
+
109
+ def main() -> int:
110
+ payload = read_stdin_json()
111
+ if payload is None:
112
+ # Empty or malformed stdin -> silent-pass.
113
+ return 0
114
+
115
+ tool_input = payload.get("tool_input")
116
+ if not isinstance(tool_input, dict):
117
+ return 0
118
+
119
+ subagent_type = tool_input.get("subagent_type")
120
+ if not isinstance(subagent_type, str) or not subagent_type:
121
+ return 0
122
+
123
+ # `is_registered_review_lens()` (review_agent_registry.py) owns the
124
+ # strip-prefix + registry-read + membership check, including the
125
+ # "unreadable registry collapses to skip" posture — this is the
126
+ # WRITE/POSITIVE-evidence side (recording that a dispatch happened),
127
+ # where collapsing an unreadable registry to "don't record" is the safe
128
+ # direction: narrowing corroboration can only narrow, never widen, what
129
+ # counts as a passing gate later.
130
+ if not is_registered_review_lens(subagent_type):
131
+ # Not a real, registered review agent, or the registry could not be
132
+ # read at all — never recorded, not even as a rejected/flagged entry
133
+ # (module docstring).
134
+ return 0
135
+
136
+ # Normalize the plugin-qualified dispatch form ("dev-team:doc-review") to
137
+ # the bare name the registry's closed set uses, so the plugin's normal,
138
+ # installed invocation form is recognized identically to a bare-named one.
139
+ subagent_type = strip_plugin_prefix(subagent_type)
140
+
141
+ cwd = payload.get("cwd") or "."
142
+ session_id = payload.get("session_id")
143
+ tool_name = payload.get("tool_name") or "Agent"
144
+
145
+ # Stamp the CURRENT content hash (#1461 security review, revised #1904
146
+ # Bug 2b) — binds this dispatch to whatever is under review right now,
147
+ # so the corroboration reader can require dispatch evidence for the SAME
148
+ # content as the eventual `.pr-review-passed` write, not merely "some
149
+ # review happened recently" against unrelated content. A hash-
150
+ # computation failure (e.g. no git repo) fails open per this hook's own
151
+ # convention: still record the dispatch, just without a subject_hash —
152
+ # such an event can never satisfy a gate check, which requires an exact
153
+ # hash match, so this can only ever under-record, never forge evidence.
154
+ try:
155
+ subject_hash = review_gate_hash(cwd)
156
+ if subject_hash == EMPTY_DIGEST:
157
+ # Nothing staged — the routine state during a `--since <base>`-
158
+ # scoped review (skills/pr/SKILL.md requires a clean working
159
+ # tree before that review runs). Stamping EMPTY_DIGEST here
160
+ # would be the exact Bug 1 hazard (a constant shared by every
161
+ # such dispatch, regardless of real content) AND would leave
162
+ # this evidence unable to corroborate `hooks/pre_pr_review.py`'s
163
+ # gate, which always compares against `branch_diff_gate_hash()`.
164
+ # Fall back to that same content domain; refuse to stamp (None)
165
+ # rather than fall back to the empty digest a second time.
166
+ base_ref = default_base_ref(cwd)
167
+ branch_hash = branch_diff_gate_hash(base_ref, cwd) if base_ref is not None else None
168
+ subject_hash = (
169
+ branch_hash if branch_hash and branch_hash != EMPTY_DIGEST else None
170
+ )
171
+ except Exception: # noqa: BLE001 - fail-open: a hash failure never blocks a dispatch
172
+ subject_hash = None
173
+
174
+ emit_boundary_event(
175
+ cwd,
176
+ "agent_dispatch_ledger",
177
+ tool_name,
178
+ "record",
179
+ subagent_type,
180
+ session_id,
181
+ subject_hash=subject_hash,
182
+ )
183
+ return 0
184
+
185
+
186
+ if __name__ == "__main__":
187
+ try:
188
+ sys.exit(main())
189
+ except Exception: # noqa: BLE001 - fail-open: a hook bug must never block a dispatch
190
+ sys.exit(0)
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env python3
2
+ """autocompact_setup_nudge — Claude Code SessionStart hook (#2177, slice 3).
3
+
4
+ The plugin no longer forces a handoff at a context ceiling; instead
5
+ `/dev-team:setup` sets the harness's own `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`.
6
+ That makes `/setup` load-bearing, so this hook advises running it when a repo
7
+ shows no sign it has been.
8
+
9
+ Channel: plain stdout (`sys.stdout.write`), matching the other nudge hooks
10
+ (`repo_review_nudge.py`, `mcp_json_repowise_nudge.py`). Like them it is
11
+ self-silencing from state — once the key is configured it never prints — and
12
+ has no once-per-session marker.
13
+
14
+ - Key absent (process env, settings.local.json, settings.json, user settings):
15
+ one advisory line.
16
+ - Key present but invalid (not an integer 1-100): one corrective line.
17
+ - Key valid, opted out, or SessionStart source is "compact": silent.
18
+
19
+ Opt-out: `DEV_TEAM_AUTOCOMPACT_NUDGE=0` or the marker file
20
+ `.claude/memory/autocompact-nudge-off` (written by `/setup --no-autocompact`).
21
+
22
+ Project dir: `$CLAUDE_PROJECT_DIR`, else the payload `cwd`, else the process
23
+ cwd. Advisory only: fail-open, always exits 0, never blocks session start.
24
+ Stdlib only.
25
+ """
26
+
27
+ from __future__ import annotations
28
+
29
+ import os
30
+ import sys
31
+ from pathlib import Path
32
+
33
+ _LIB = Path(__file__).resolve().parent / "lib"
34
+ if str(_LIB) not in sys.path:
35
+ sys.path.insert(0, str(_LIB))
36
+
37
+ from autocompact_config import KEY, Status, detect # type: ignore[import-not-found]
38
+ from stdin_json import read_stdin_json, resolve_cwd # type: ignore[import-not-found]
39
+
40
+ OPT_OUT_ENV = "DEV_TEAM_AUTOCOMPACT_NUDGE"
41
+ OPT_OUT_MARKER = Path(".claude") / "memory" / "autocompact-nudge-off"
42
+
43
+ ABSENT_MESSAGE = (
44
+ "dev-team: context autocompact is not configured for this repo; "
45
+ "run /dev-team:setup to set it (default 40%). "
46
+ f"Silence: {OPT_OUT_ENV}=0 or create {OPT_OUT_MARKER.as_posix()}\n"
47
+ )
48
+
49
+
50
+ _MAX_SHOWN = 40
51
+
52
+
53
+ def invalid_message(raw: object, source: str | None) -> str:
54
+ shown = repr(raw)
55
+ if len(shown) > _MAX_SHOWN:
56
+ shown = shown[: _MAX_SHOWN - 3] + "..."
57
+ where = f" in {source}" if source else ""
58
+ return (
59
+ f"dev-team: {KEY}={shown}{where} is invalid (need integer 1-100); "
60
+ "re-run /dev-team:setup\n"
61
+ )
62
+
63
+
64
+ def _project_dir(payload: dict) -> Path:
65
+ override = os.environ.get("CLAUDE_PROJECT_DIR")
66
+ if override and Path(override).is_dir():
67
+ return Path(override)
68
+ return Path(resolve_cwd(payload))
69
+
70
+
71
+ def message_for(payload: dict) -> str:
72
+ """The text to print, or '' when the hook should stay silent."""
73
+ if payload.get("source") == "compact":
74
+ return ""
75
+ if os.environ.get(OPT_OUT_ENV) == "0":
76
+ return ""
77
+ project = _project_dir(payload)
78
+ if (project / OPT_OUT_MARKER).exists():
79
+ return ""
80
+ detection = detect(project, os.environ)
81
+ if detection.status is Status.ABSENT:
82
+ return ABSENT_MESSAGE
83
+ if detection.status is Status.INVALID:
84
+ return invalid_message(detection.raw, detection.source)
85
+ return ""
86
+
87
+
88
+ def main() -> int:
89
+ try:
90
+ text = message_for(read_stdin_json() or {})
91
+ if text:
92
+ sys.stdout.write(text)
93
+ except Exception: # noqa: BLE001 - advisory hook: never block session start
94
+ return 0
95
+ return 0
96
+
97
+
98
+ if __name__ == "__main__":
99
+ sys.exit(main())