xtrm-tools 2.0.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 (447) hide show
  1. package/CHANGELOG.md +496 -0
  2. package/README.md +762 -0
  3. package/cli/dist/index.cjs +55245 -0
  4. package/cli/dist/index.cjs.map +1 -0
  5. package/cli/dist/index.d.cts +2 -0
  6. package/cli/package.json +43 -0
  7. package/config/.env.example +40 -0
  8. package/config/hooks.json +36 -0
  9. package/config/mcp_servers.json +46 -0
  10. package/config/mcp_servers_optional.json +53 -0
  11. package/config/settings.json +70 -0
  12. package/hooks/README.md +156 -0
  13. package/hooks/__pycache__/agent_context.cpython-314.pyc +0 -0
  14. package/hooks/agent_context.py +105 -0
  15. package/hooks/gitnexus/gitnexus-hook.cjs +133 -0
  16. package/hooks/serena-workflow-reminder.py +74 -0
  17. package/hooks/skill-discovery.py +90 -0
  18. package/hooks/skill-suggestion.py +112 -0
  19. package/hooks/test_agent_context.py +112 -0
  20. package/hooks/type-safety-enforcement.py +107 -0
  21. package/package.json +48 -0
  22. package/project-skills/main-guard/.claude/hooks/main-guard.cjs +188 -0
  23. package/project-skills/main-guard/.claude/settings.json +16 -0
  24. package/project-skills/main-guard/.claude/skills/using-main-guard/SKILL.md +135 -0
  25. package/project-skills/main-guard/README.md +163 -0
  26. package/project-skills/py-quality-gate/.claude/hooks/quality-check.py +311 -0
  27. package/project-skills/py-quality-gate/.claude/settings.json +16 -0
  28. package/project-skills/py-quality-gate/.claude/skills/using-py-quality-gate/SKILL.md +112 -0
  29. package/project-skills/py-quality-gate/README.md +147 -0
  30. package/project-skills/service-skills-set/.claude/git-hooks/__pycache__/doc_reminder.cpython-314.pyc +0 -0
  31. package/project-skills/service-skills-set/.claude/git-hooks/__pycache__/skill_staleness.cpython-314.pyc +0 -0
  32. package/project-skills/service-skills-set/.claude/git-hooks/doc_reminder.py +67 -0
  33. package/project-skills/service-skills-set/.claude/git-hooks/skill_staleness.py +194 -0
  34. package/project-skills/service-skills-set/.claude/service-registry.json +4 -0
  35. package/project-skills/service-skills-set/.claude/settings.json +37 -0
  36. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/SKILL.md +433 -0
  37. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/references/script_quality_standards.md +412 -0
  38. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/references/service_skill_system_guide.md +264 -0
  39. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/bootstrap.py +308 -0
  40. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/deep_dive.py +304 -0
  41. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/scaffolder.py +482 -0
  42. package/project-skills/service-skills-set/.claude/skills/scoping-service-skills/SKILL.md +231 -0
  43. package/project-skills/service-skills-set/.claude/skills/scoping-service-skills/scripts/scope.py +74 -0
  44. package/project-skills/service-skills-set/.claude/skills/updating-service-skills/SKILL.md +136 -0
  45. package/project-skills/service-skills-set/.claude/skills/updating-service-skills/scripts/__pycache__/drift_detector.cpython-314.pyc +0 -0
  46. package/project-skills/service-skills-set/.claude/skills/updating-service-skills/scripts/drift_detector.py +222 -0
  47. package/project-skills/service-skills-set/.claude/skills/using-service-skills/SKILL.md +108 -0
  48. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/__pycache__/cataloger.cpython-314.pyc +0 -0
  49. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/__pycache__/skill_activator.cpython-314.pyc +0 -0
  50. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/cataloger.py +74 -0
  51. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/skill_activator.py +152 -0
  52. package/project-skills/service-skills-set/README.md +93 -0
  53. package/project-skills/service-skills-set/__pycache__/install-service-skills.cpython-314.pyc +0 -0
  54. package/project-skills/service-skills-set/install-service-skills.py +163 -0
  55. package/project-skills/service-skills-set/service-skills-readme.md +236 -0
  56. package/project-skills/tdd-guard/.claude/settings.json +38 -0
  57. package/project-skills/tdd-guard/.claude/skills/using-tdd-guard/SKILL.md +74 -0
  58. package/project-skills/tdd-guard/CLAUDE.md +98 -0
  59. package/project-skills/tdd-guard/CONTRIBUTING.md +38 -0
  60. package/project-skills/tdd-guard/DEVELOPMENT.md +127 -0
  61. package/project-skills/tdd-guard/LICENSE +21 -0
  62. package/project-skills/tdd-guard/README.md +396 -0
  63. package/project-skills/tdd-guard/docs/adr/001-claude-session-subdirectory.md +52 -0
  64. package/project-skills/tdd-guard/docs/adr/002-secure-claude-binary-path.md +56 -0
  65. package/project-skills/tdd-guard/docs/adr/003-remove-configurable-data-directory.md +56 -0
  66. package/project-skills/tdd-guard/docs/adr/004-monorepo-architecture.md +64 -0
  67. package/project-skills/tdd-guard/docs/adr/005-claude-project-dir-support.md +55 -0
  68. package/project-skills/tdd-guard/docs/adr/006-phpunit-separate-repository.md +93 -0
  69. package/project-skills/tdd-guard/docs/adr/007-golangci-lint-path-support.md +83 -0
  70. package/project-skills/tdd-guard/docs/adr/008-storybook-reporter-design.md +182 -0
  71. package/project-skills/tdd-guard/docs/assets/tdd-guard-demo-screenshot.gif +0 -0
  72. package/project-skills/tdd-guard/docs/config-migration.md +143 -0
  73. package/project-skills/tdd-guard/docs/configuration.md +137 -0
  74. package/project-skills/tdd-guard/docs/custom-instructions.md +43 -0
  75. package/project-skills/tdd-guard/docs/enforcement.md +46 -0
  76. package/project-skills/tdd-guard/docs/ignore-patterns.md +81 -0
  77. package/project-skills/tdd-guard/docs/linting.md +109 -0
  78. package/project-skills/tdd-guard/docs/quick-commands.md +52 -0
  79. package/project-skills/tdd-guard/docs/session-management.md +75 -0
  80. package/project-skills/tdd-guard/docs/storybook-vitest-addon.md +120 -0
  81. package/project-skills/tdd-guard/docs/validation-model.md +63 -0
  82. package/project-skills/tdd-guard/eslint.config.mjs +140 -0
  83. package/project-skills/tdd-guard/package-lock.json +16937 -0
  84. package/project-skills/tdd-guard/package.json +102 -0
  85. package/project-skills/tdd-guard/reporters/go/README.md +67 -0
  86. package/project-skills/tdd-guard/reporters/go/cmd/tdd-guard-go/main.go +127 -0
  87. package/project-skills/tdd-guard/reporters/go/cmd/tdd-guard-go/main_test.go +280 -0
  88. package/project-skills/tdd-guard/reporters/go/go.mod +3 -0
  89. package/project-skills/tdd-guard/reporters/go/go.sum +0 -0
  90. package/project-skills/tdd-guard/reporters/go/internal/formatter/formatter.go +126 -0
  91. package/project-skills/tdd-guard/reporters/go/internal/formatter/formatter_test.go +264 -0
  92. package/project-skills/tdd-guard/reporters/go/internal/io/tee_reader.go +26 -0
  93. package/project-skills/tdd-guard/reporters/go/internal/io/tee_reader_test.go +37 -0
  94. package/project-skills/tdd-guard/reporters/go/internal/parser/mixed_reader.go +94 -0
  95. package/project-skills/tdd-guard/reporters/go/internal/parser/mixed_reader_test.go +198 -0
  96. package/project-skills/tdd-guard/reporters/go/internal/parser/parser.go +245 -0
  97. package/project-skills/tdd-guard/reporters/go/internal/parser/parser_test.go +547 -0
  98. package/project-skills/tdd-guard/reporters/go/internal/storage/storage.go +35 -0
  99. package/project-skills/tdd-guard/reporters/go/internal/storage/storage_test.go +113 -0
  100. package/project-skills/tdd-guard/reporters/go/internal/transformer/transformer.go +103 -0
  101. package/project-skills/tdd-guard/reporters/go/internal/transformer/transformer_test.go +303 -0
  102. package/project-skills/tdd-guard/reporters/jest/README.md +102 -0
  103. package/project-skills/tdd-guard/reporters/jest/package.json +38 -0
  104. package/project-skills/tdd-guard/reporters/phpunit/.php-cs-fixer.php +28 -0
  105. package/project-skills/tdd-guard/reporters/phpunit/README.md +97 -0
  106. package/project-skills/tdd-guard/reporters/phpunit/SYNC_README.md +29 -0
  107. package/project-skills/tdd-guard/reporters/phpunit/composer.json +55 -0
  108. package/project-skills/tdd-guard/reporters/phpunit/phpunit.xml.dist +19 -0
  109. package/project-skills/tdd-guard/reporters/phpunit/psalm.xml +44 -0
  110. package/project-skills/tdd-guard/reporters/phpunit/src/Event/ErroredTestSubscriber.php +28 -0
  111. package/project-skills/tdd-guard/reporters/phpunit/src/Event/FailedTestSubscriber.php +28 -0
  112. package/project-skills/tdd-guard/reporters/phpunit/src/Event/IncompleteTestSubscriber.php +28 -0
  113. package/project-skills/tdd-guard/reporters/phpunit/src/Event/PassedTestSubscriber.php +27 -0
  114. package/project-skills/tdd-guard/reporters/phpunit/src/Event/SkippedTestSubscriber.php +28 -0
  115. package/project-skills/tdd-guard/reporters/phpunit/src/Event/TestRunnerFinishedSubscriber.php +24 -0
  116. package/project-skills/tdd-guard/reporters/phpunit/src/PathValidator.php +88 -0
  117. package/project-skills/tdd-guard/reporters/phpunit/src/Storage.php +26 -0
  118. package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardExtension.php +33 -0
  119. package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardListener.php +158 -0
  120. package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardSubscriber.php +35 -0
  121. package/project-skills/tdd-guard/reporters/phpunit/src/TestResultCollector.php +105 -0
  122. package/project-skills/tdd-guard/reporters/phpunit/tests/PathValidatorTest.php +74 -0
  123. package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardExtensionFailedTest.php +241 -0
  124. package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardExtensionTest.php +84 -0
  125. package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardStorageLocationTest.php +71 -0
  126. package/project-skills/tdd-guard/reporters/pytest/README.md +77 -0
  127. package/project-skills/tdd-guard/reporters/pytest/pyproject.toml +43 -0
  128. package/project-skills/tdd-guard/reporters/pytest/pytest.ini.example +7 -0
  129. package/project-skills/tdd-guard/reporters/pytest/tdd_guard_pytest/__init__.py +1 -0
  130. package/project-skills/tdd-guard/reporters/pytest/tdd_guard_pytest/pytest_reporter.py +134 -0
  131. package/project-skills/tdd-guard/reporters/pytest/tests/__init__.py +1 -0
  132. package/project-skills/tdd-guard/reporters/pytest/tests/conftest.py +3 -0
  133. package/project-skills/tdd-guard/reporters/pytest/tests/helpers.py +293 -0
  134. package/project-skills/tdd-guard/reporters/pytest/tests/test_config_option.py +38 -0
  135. package/project-skills/tdd-guard/reporters/pytest/tests/test_path_validation.py +59 -0
  136. package/project-skills/tdd-guard/reporters/pytest/tests/test_plugin_config.py +32 -0
  137. package/project-skills/tdd-guard/reporters/pytest/tests/test_project_root.py +296 -0
  138. package/project-skills/tdd-guard/reporters/pytest/tests/test_pytest_reporter.py +137 -0
  139. package/project-skills/tdd-guard/reporters/rspec/Gemfile +3 -0
  140. package/project-skills/tdd-guard/reporters/rust/Cargo.lock +458 -0
  141. package/project-skills/tdd-guard/reporters/rust/Cargo.toml +33 -0
  142. package/project-skills/tdd-guard/reporters/rust/Makefile.example +95 -0
  143. package/project-skills/tdd-guard/reporters/rust/README.md +88 -0
  144. package/project-skills/tdd-guard/reporters/rust/src/error_parser.rs +309 -0
  145. package/project-skills/tdd-guard/reporters/rust/src/main.rs +464 -0
  146. package/project-skills/tdd-guard/reporters/rust/src/parser.rs +225 -0
  147. package/project-skills/tdd-guard/reporters/rust/src/transformer.rs +409 -0
  148. package/project-skills/tdd-guard/reporters/storybook/README.md +108 -0
  149. package/project-skills/tdd-guard/reporters/storybook/package-lock.json +9482 -0
  150. package/project-skills/tdd-guard/reporters/storybook/package.json +43 -0
  151. package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.test-data.ts +22 -0
  152. package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.test.ts +190 -0
  153. package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.ts +88 -0
  154. package/project-skills/tdd-guard/reporters/storybook/src/index.ts +12 -0
  155. package/project-skills/tdd-guard/reporters/storybook/src/types.ts +37 -0
  156. package/project-skills/tdd-guard/reporters/storybook/tsconfig.json +11 -0
  157. package/project-skills/tdd-guard/reporters/test/artifacts/go/failing/go.mod +3 -0
  158. package/project-skills/tdd-guard/reporters/test/artifacts/go/failing/single_failing_test.go +13 -0
  159. package/project-skills/tdd-guard/reporters/test/artifacts/go/import/go.mod +3 -0
  160. package/project-skills/tdd-guard/reporters/test/artifacts/go/import/single_import_error_test.go +17 -0
  161. package/project-skills/tdd-guard/reporters/test/artifacts/go/passing/go.mod +3 -0
  162. package/project-skills/tdd-guard/reporters/test/artifacts/go/passing/single_passing_test.go +13 -0
  163. package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-failing.test.js +5 -0
  164. package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-import-error.test.js +8 -0
  165. package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-passing.test.js +5 -0
  166. package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SingleFailingTest.php +11 -0
  167. package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SingleImportErrorTest.php +14 -0
  168. package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SinglePassingTest.php +11 -0
  169. package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_failing.py +3 -0
  170. package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_import_error.py +6 -0
  171. package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_passing.py +3 -0
  172. package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/Cargo.lock +7 -0
  173. package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/Cargo.toml +4 -0
  174. package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/src/lib.rs +14 -0
  175. package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/Cargo.lock +7 -0
  176. package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/Cargo.toml +4 -0
  177. package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/src/lib.rs +13 -0
  178. package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/Cargo.lock +7 -0
  179. package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/Cargo.toml +4 -0
  180. package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/src/lib.rs +14 -0
  181. package/project-skills/tdd-guard/reporters/test/artifacts/storybook/Calculator.js +4 -0
  182. package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-failing.stories.js +15 -0
  183. package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-import-error.stories.js +14 -0
  184. package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-passing.stories.js +15 -0
  185. package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-failing.test.js +7 -0
  186. package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-import-error.test.js +9 -0
  187. package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-passing.test.js +7 -0
  188. package/project-skills/tdd-guard/reporters/test/factories/go.ts +59 -0
  189. package/project-skills/tdd-guard/reporters/test/factories/helpers.ts +48 -0
  190. package/project-skills/tdd-guard/reporters/test/factories/index.ts +7 -0
  191. package/project-skills/tdd-guard/reporters/test/factories/jest.ts +51 -0
  192. package/project-skills/tdd-guard/reporters/test/factories/phpunit.ts +63 -0
  193. package/project-skills/tdd-guard/reporters/test/factories/pytest.ts +41 -0
  194. package/project-skills/tdd-guard/reporters/test/factories/rust.ts +158 -0
  195. package/project-skills/tdd-guard/reporters/test/factories/storybook.ts +198 -0
  196. package/project-skills/tdd-guard/reporters/test/factories/vitest.ts +51 -0
  197. package/project-skills/tdd-guard/reporters/test/reporters.integration.test.ts +735 -0
  198. package/project-skills/tdd-guard/reporters/test/types.ts +28 -0
  199. package/project-skills/tdd-guard/reporters/vitest/README.md +64 -0
  200. package/project-skills/tdd-guard/reporters/vitest/package.json +35 -0
  201. package/project-skills/tdd-guard/src/cli/buildContext.test.ts +200 -0
  202. package/project-skills/tdd-guard/src/cli/buildContext.ts +48 -0
  203. package/project-skills/tdd-guard/src/cli/tdd-guard.test.ts +159 -0
  204. package/project-skills/tdd-guard/src/cli/tdd-guard.ts +48 -0
  205. package/project-skills/tdd-guard/src/config/Config.test.ts +538 -0
  206. package/project-skills/tdd-guard/src/config/Config.ts +172 -0
  207. package/project-skills/tdd-guard/src/contracts/schemas/guardSchemas.test.ts +58 -0
  208. package/project-skills/tdd-guard/src/contracts/schemas/guardSchemas.ts +8 -0
  209. package/project-skills/tdd-guard/src/contracts/schemas/lintSchemas.test.ts +347 -0
  210. package/project-skills/tdd-guard/src/contracts/schemas/lintSchemas.ts +61 -0
  211. package/project-skills/tdd-guard/src/contracts/schemas/pytestSchemas.test.ts +24 -0
  212. package/project-skills/tdd-guard/src/contracts/schemas/pytestSchemas.ts +7 -0
  213. package/project-skills/tdd-guard/src/contracts/schemas/reporterSchemas.test.ts +377 -0
  214. package/project-skills/tdd-guard/src/contracts/schemas/reporterSchemas.ts +75 -0
  215. package/project-skills/tdd-guard/src/contracts/schemas/toolSchemas.test.ts +563 -0
  216. package/project-skills/tdd-guard/src/contracts/schemas/toolSchemas.ts +140 -0
  217. package/project-skills/tdd-guard/src/contracts/types/ClientType.ts +1 -0
  218. package/project-skills/tdd-guard/src/contracts/types/ConfigOptions.ts +12 -0
  219. package/project-skills/tdd-guard/src/contracts/types/Context.ts +16 -0
  220. package/project-skills/tdd-guard/src/contracts/types/ModelClient.ts +3 -0
  221. package/project-skills/tdd-guard/src/contracts/types/ValidationResult.ts +6 -0
  222. package/project-skills/tdd-guard/src/guard/GuardManager.test.ts +336 -0
  223. package/project-skills/tdd-guard/src/guard/GuardManager.ts +83 -0
  224. package/project-skills/tdd-guard/src/hooks/HookEvents.test.ts +107 -0
  225. package/project-skills/tdd-guard/src/hooks/HookEvents.ts +39 -0
  226. package/project-skills/tdd-guard/src/hooks/fileTypeDetection.ts +16 -0
  227. package/project-skills/tdd-guard/src/hooks/postToolLint.test.ts +327 -0
  228. package/project-skills/tdd-guard/src/hooks/postToolLint.ts +165 -0
  229. package/project-skills/tdd-guard/src/hooks/processHookData.test.ts +465 -0
  230. package/project-skills/tdd-guard/src/hooks/processHookData.ts +203 -0
  231. package/project-skills/tdd-guard/src/hooks/sessionHandler.test.ts +136 -0
  232. package/project-skills/tdd-guard/src/hooks/sessionHandler.ts +31 -0
  233. package/project-skills/tdd-guard/src/hooks/userPromptHandler.test.ts +131 -0
  234. package/project-skills/tdd-guard/src/hooks/userPromptHandler.ts +55 -0
  235. package/project-skills/tdd-guard/src/index.ts +19 -0
  236. package/project-skills/tdd-guard/src/linters/Linter.ts +5 -0
  237. package/project-skills/tdd-guard/src/linters/eslint/ESLint.test.ts +183 -0
  238. package/project-skills/tdd-guard/src/linters/eslint/ESLint.ts +82 -0
  239. package/project-skills/tdd-guard/src/linters/golangci/GolangciLint.test.ts +170 -0
  240. package/project-skills/tdd-guard/src/linters/golangci/GolangciLint.ts +148 -0
  241. package/project-skills/tdd-guard/src/processors/index.ts +1 -0
  242. package/project-skills/tdd-guard/src/processors/lintProcessor.ts +77 -0
  243. package/project-skills/tdd-guard/src/processors/testResults/TestResultsProcessor.test.ts +303 -0
  244. package/project-skills/tdd-guard/src/processors/testResults/TestResultsProcessor.ts +255 -0
  245. package/project-skills/tdd-guard/src/providers/LinterProvider.test.ts +43 -0
  246. package/project-skills/tdd-guard/src/providers/LinterProvider.ts +20 -0
  247. package/project-skills/tdd-guard/src/providers/ModelClientProvider.test.ts +68 -0
  248. package/project-skills/tdd-guard/src/providers/ModelClientProvider.ts +22 -0
  249. package/project-skills/tdd-guard/src/storage/FileStorage.test.ts +76 -0
  250. package/project-skills/tdd-guard/src/storage/FileStorage.ts +108 -0
  251. package/project-skills/tdd-guard/src/storage/MemoryStorage.ts +57 -0
  252. package/project-skills/tdd-guard/src/storage/Storage.test.ts +227 -0
  253. package/project-skills/tdd-guard/src/storage/Storage.ts +17 -0
  254. package/project-skills/tdd-guard/src/validation/context/context.test.ts +364 -0
  255. package/project-skills/tdd-guard/src/validation/context/context.ts +155 -0
  256. package/project-skills/tdd-guard/src/validation/models/AnthropicApi.test.ts +171 -0
  257. package/project-skills/tdd-guard/src/validation/models/AnthropicApi.ts +49 -0
  258. package/project-skills/tdd-guard/src/validation/models/ClaudeAgentSdk.test.ts +167 -0
  259. package/project-skills/tdd-guard/src/validation/models/ClaudeAgentSdk.ts +54 -0
  260. package/project-skills/tdd-guard/src/validation/models/ClaudeCli.test.ts +239 -0
  261. package/project-skills/tdd-guard/src/validation/models/ClaudeCli.ts +57 -0
  262. package/project-skills/tdd-guard/src/validation/prompts/file-types.ts +52 -0
  263. package/project-skills/tdd-guard/src/validation/prompts/operations/edit.ts +58 -0
  264. package/project-skills/tdd-guard/src/validation/prompts/operations/multi-edit.ts +54 -0
  265. package/project-skills/tdd-guard/src/validation/prompts/operations/write.ts +54 -0
  266. package/project-skills/tdd-guard/src/validation/prompts/response.ts +40 -0
  267. package/project-skills/tdd-guard/src/validation/prompts/rules.ts +51 -0
  268. package/project-skills/tdd-guard/src/validation/prompts/system-prompt.ts +10 -0
  269. package/project-skills/tdd-guard/src/validation/prompts/tools/lint-results.ts +15 -0
  270. package/project-skills/tdd-guard/src/validation/prompts/tools/test-output.ts +14 -0
  271. package/project-skills/tdd-guard/src/validation/prompts/tools/todos.ts +9 -0
  272. package/project-skills/tdd-guard/src/validation/validator.test.ts +268 -0
  273. package/project-skills/tdd-guard/src/validation/validator.ts +159 -0
  274. package/project-skills/tdd-guard/test/artifacts/go/.golangci.yml +6 -0
  275. package/project-skills/tdd-guard/test/artifacts/go/with-issues/file-with-issues.go +12 -0
  276. package/project-skills/tdd-guard/test/artifacts/go/with-issues/go.mod +3 -0
  277. package/project-skills/tdd-guard/test/artifacts/go/without-issues/file-without-issues.go +7 -0
  278. package/project-skills/tdd-guard/test/artifacts/go/without-issues/go.mod +3 -0
  279. package/project-skills/tdd-guard/test/artifacts/javascript/eslint.config.js +20 -0
  280. package/project-skills/tdd-guard/test/artifacts/javascript/file-with-issues.js +12 -0
  281. package/project-skills/tdd-guard/test/artifacts/javascript/file-without-issues.js +10 -0
  282. package/project-skills/tdd-guard/test/hooks/fileTypeDetection.test.ts +26 -0
  283. package/project-skills/tdd-guard/test/hooks/processHookData.fileType.test.ts +46 -0
  284. package/project-skills/tdd-guard/test/hooks/processHookData.python.test.ts +68 -0
  285. package/project-skills/tdd-guard/test/integration/test-context.test.ts +66 -0
  286. package/project-skills/tdd-guard/test/integration/validator.core.test.ts +96 -0
  287. package/project-skills/tdd-guard/test/integration/validator.scenarios.test.ts +497 -0
  288. package/project-skills/tdd-guard/test/utils/assertions.ts +29 -0
  289. package/project-skills/tdd-guard/test/utils/factories/contextFactory.ts +30 -0
  290. package/project-skills/tdd-guard/test/utils/factories/editFactory.ts +82 -0
  291. package/project-skills/tdd-guard/test/utils/factories/helpers.test.ts +46 -0
  292. package/project-skills/tdd-guard/test/utils/factories/helpers.ts +46 -0
  293. package/project-skills/tdd-guard/test/utils/factories/lintFactory.ts +352 -0
  294. package/project-skills/tdd-guard/test/utils/factories/modelClientProviderFactory.ts +21 -0
  295. package/project-skills/tdd-guard/test/utils/factories/multiEditFactory.ts +79 -0
  296. package/project-skills/tdd-guard/test/utils/factories/operations.ts +57 -0
  297. package/project-skills/tdd-guard/test/utils/factories/reporterFactory.ts +55 -0
  298. package/project-skills/tdd-guard/test/utils/factories/scenarios/index.ts +22 -0
  299. package/project-skills/tdd-guard/test/utils/factories/scenarios/languages/python.ts +745 -0
  300. package/project-skills/tdd-guard/test/utils/factories/scenarios/languages/typescript.ts +767 -0
  301. package/project-skills/tdd-guard/test/utils/factories/scenarios/types.ts +77 -0
  302. package/project-skills/tdd-guard/test/utils/factories/scenarios/utils.ts +15 -0
  303. package/project-skills/tdd-guard/test/utils/factories/sessionStartFactory.ts +36 -0
  304. package/project-skills/tdd-guard/test/utils/factories/testDefaults.ts +90 -0
  305. package/project-skills/tdd-guard/test/utils/factories/testResultsFactory.ts +234 -0
  306. package/project-skills/tdd-guard/test/utils/factories/todoFactory.ts +99 -0
  307. package/project-skills/tdd-guard/test/utils/factories/userPromptSubmitFactory.ts +39 -0
  308. package/project-skills/tdd-guard/test/utils/factories/writeFactory.ts +70 -0
  309. package/project-skills/tdd-guard/test/utils/index.ts +131 -0
  310. package/project-skills/tdd-guard/tsconfig.build.json +16 -0
  311. package/project-skills/tdd-guard/tsconfig.eslint.json +17 -0
  312. package/project-skills/tdd-guard/tsconfig.json +32 -0
  313. package/project-skills/tdd-guard/tsconfig.node.json +10 -0
  314. package/project-skills/tdd-guard/vitest.config.ts +85 -0
  315. package/project-skills/ts-quality-gate/.claude/hooks/hook-config.json +66 -0
  316. package/project-skills/ts-quality-gate/.claude/hooks/quality-check.cjs +1251 -0
  317. package/project-skills/ts-quality-gate/.claude/settings.json +16 -0
  318. package/project-skills/ts-quality-gate/.claude/skills/using-ts-quality-gate/SKILL.md +81 -0
  319. package/project-skills/ts-quality-gate/README.md +115 -0
  320. package/skills/README.txt +31 -0
  321. package/skills/clean-code/SKILL.md +201 -0
  322. package/skills/delegating/SKILL.md +196 -0
  323. package/skills/delegating/config.yaml +210 -0
  324. package/skills/delegating/references/orchestration-protocols.md +41 -0
  325. package/skills/docker-expert/SKILL.md +409 -0
  326. package/skills/documenting/CHANGELOG.md +23 -0
  327. package/skills/documenting/README.md +148 -0
  328. package/skills/documenting/SKILL.md +113 -0
  329. package/skills/documenting/examples/example_pattern.md +70 -0
  330. package/skills/documenting/examples/example_reference.md +70 -0
  331. package/skills/documenting/examples/example_ssot_analytics.md +64 -0
  332. package/skills/documenting/examples/example_workflow.md +141 -0
  333. package/skills/documenting/references/changelog-format.md +97 -0
  334. package/skills/documenting/references/metadata-schema.md +136 -0
  335. package/skills/documenting/references/taxonomy.md +81 -0
  336. package/skills/documenting/references/versioning-rules.md +78 -0
  337. package/skills/documenting/scripts/__pycache__/drift_detector.cpython-314.pyc +0 -0
  338. package/skills/documenting/scripts/__pycache__/orchestrator.cpython-314.pyc +0 -0
  339. package/skills/documenting/scripts/__pycache__/validate_metadata.cpython-314.pyc +0 -0
  340. package/skills/documenting/scripts/bump_version.sh +60 -0
  341. package/skills/documenting/scripts/changelog/__init__.py +0 -0
  342. package/skills/documenting/scripts/changelog/__pycache__/__init__.cpython-314.pyc +0 -0
  343. package/skills/documenting/scripts/changelog/__pycache__/add_entry.cpython-314.pyc +0 -0
  344. package/skills/documenting/scripts/changelog/__pycache__/bump_release.cpython-314.pyc +0 -0
  345. package/skills/documenting/scripts/changelog/__pycache__/validate_changelog.cpython-314.pyc +0 -0
  346. package/skills/documenting/scripts/changelog/add_entry.py +216 -0
  347. package/skills/documenting/scripts/changelog/bump_release.py +117 -0
  348. package/skills/documenting/scripts/changelog/init_changelog.py +54 -0
  349. package/skills/documenting/scripts/changelog/validate_changelog.py +128 -0
  350. package/skills/documenting/scripts/drift_detector.py +266 -0
  351. package/skills/documenting/scripts/generate_template.py +311 -0
  352. package/skills/documenting/scripts/list_by_category.sh +84 -0
  353. package/skills/documenting/scripts/orchestrator.py +255 -0
  354. package/skills/documenting/scripts/validate_metadata.py +242 -0
  355. package/skills/documenting/templates/CHANGELOG.md.template +13 -0
  356. package/skills/documenting/tests/__pycache__/test_changelog.cpython-314-pytest-9.0.2.pyc +0 -0
  357. package/skills/documenting/tests/__pycache__/test_drift_detector.cpython-314-pytest-9.0.2.pyc +0 -0
  358. package/skills/documenting/tests/__pycache__/test_orchestrator.cpython-314-pytest-9.0.2.pyc +0 -0
  359. package/skills/documenting/tests/__pycache__/test_validate_metadata.cpython-314-pytest-9.0.2.pyc +0 -0
  360. package/skills/documenting/tests/integration_test.sh +70 -0
  361. package/skills/documenting/tests/test_changelog.py +201 -0
  362. package/skills/documenting/tests/test_drift_detector.py +80 -0
  363. package/skills/documenting/tests/test_orchestrator.py +52 -0
  364. package/skills/documenting/tests/test_validate_metadata.py +64 -0
  365. package/skills/find-skills/SKILL.md +133 -0
  366. package/skills/gitnexus-debugging/SKILL.md +85 -0
  367. package/skills/gitnexus-exploring/SKILL.md +75 -0
  368. package/skills/gitnexus-impact-analysis/SKILL.md +94 -0
  369. package/skills/gitnexus-refactoring/SKILL.md +113 -0
  370. package/skills/hook-development/SKILL.md +797 -0
  371. package/skills/hook-development/examples/load-context.sh +55 -0
  372. package/skills/hook-development/examples/quality-check.js +1168 -0
  373. package/skills/hook-development/examples/validate-bash.sh +43 -0
  374. package/skills/hook-development/examples/validate-write.sh +38 -0
  375. package/skills/hook-development/references/advanced.md +527 -0
  376. package/skills/hook-development/references/migration.md +369 -0
  377. package/skills/hook-development/references/patterns.md +412 -0
  378. package/skills/hook-development/scripts/README.md +164 -0
  379. package/skills/hook-development/scripts/hook-linter.sh +153 -0
  380. package/skills/hook-development/scripts/test-hook.sh +252 -0
  381. package/skills/hook-development/scripts/validate-hook-schema.sh +159 -0
  382. package/skills/obsidian-cli/SKILL.md +106 -0
  383. package/skills/orchestrating-agents/SKILL.md +135 -0
  384. package/skills/orchestrating-agents/config.yaml +45 -0
  385. package/skills/orchestrating-agents/references/agent-context-integration.md +37 -0
  386. package/skills/orchestrating-agents/references/examples.md +45 -0
  387. package/skills/orchestrating-agents/references/handover-protocol.md +31 -0
  388. package/skills/orchestrating-agents/references/workflows.md +42 -0
  389. package/skills/orchestrating-agents/scripts/detect_neighbors.py +23 -0
  390. package/skills/prompt-improving/README.md +162 -0
  391. package/skills/prompt-improving/SKILL.md +74 -0
  392. package/skills/prompt-improving/references/analysis_commands.md +24 -0
  393. package/skills/prompt-improving/references/chain_of_thought.md +24 -0
  394. package/skills/prompt-improving/references/mcp_definitions.md +20 -0
  395. package/skills/prompt-improving/references/multishot.md +23 -0
  396. package/skills/prompt-improving/references/xml_core.md +60 -0
  397. package/skills/python-testing/SKILL.md +815 -0
  398. package/skills/senior-backend/SKILL.md +209 -0
  399. package/skills/senior-backend/references/api_design_patterns.md +103 -0
  400. package/skills/senior-backend/references/backend_security_practices.md +103 -0
  401. package/skills/senior-backend/references/database_optimization_guide.md +103 -0
  402. package/skills/senior-backend/scripts/api_load_tester.py +114 -0
  403. package/skills/senior-backend/scripts/api_scaffolder.py +114 -0
  404. package/skills/senior-backend/scripts/database_migration_tool.py +114 -0
  405. package/skills/senior-data-scientist/SKILL.md +226 -0
  406. package/skills/senior-data-scientist/references/experiment_design_frameworks.md +80 -0
  407. package/skills/senior-data-scientist/references/feature_engineering_patterns.md +80 -0
  408. package/skills/senior-data-scientist/references/statistical_methods_advanced.md +80 -0
  409. package/skills/senior-data-scientist/scripts/experiment_designer.py +100 -0
  410. package/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py +100 -0
  411. package/skills/senior-data-scientist/scripts/model_evaluation_suite.py +100 -0
  412. package/skills/senior-devops/SKILL.md +209 -0
  413. package/skills/senior-devops/references/cicd_pipeline_guide.md +103 -0
  414. package/skills/senior-devops/references/deployment_strategies.md +103 -0
  415. package/skills/senior-devops/references/infrastructure_as_code.md +103 -0
  416. package/skills/senior-devops/scripts/deployment_manager.py +114 -0
  417. package/skills/senior-devops/scripts/pipeline_generator.py +114 -0
  418. package/skills/senior-devops/scripts/terraform_scaffolder.py +114 -0
  419. package/skills/senior-security/SKILL.md +209 -0
  420. package/skills/senior-security/references/cryptography_implementation.md +103 -0
  421. package/skills/senior-security/references/penetration_testing_guide.md +103 -0
  422. package/skills/senior-security/references/security_architecture_patterns.md +103 -0
  423. package/skills/senior-security/scripts/pentest_automator.py +114 -0
  424. package/skills/senior-security/scripts/security_auditor.py +114 -0
  425. package/skills/senior-security/scripts/threat_modeler.py +114 -0
  426. package/skills/skill-creator/LICENSE.txt +202 -0
  427. package/skills/skill-creator/SKILL.md +479 -0
  428. package/skills/skill-creator/agents/analyzer.md +274 -0
  429. package/skills/skill-creator/agents/comparator.md +202 -0
  430. package/skills/skill-creator/agents/grader.md +223 -0
  431. package/skills/skill-creator/assets/eval_review.html +146 -0
  432. package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  433. package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  434. package/skills/skill-creator/references/schemas.md +430 -0
  435. package/skills/skill-creator/scripts/__init__.py +0 -0
  436. package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  437. package/skills/skill-creator/scripts/generate_report.py +326 -0
  438. package/skills/skill-creator/scripts/improve_description.py +248 -0
  439. package/skills/skill-creator/scripts/package_skill.py +136 -0
  440. package/skills/skill-creator/scripts/quick_validate.py +103 -0
  441. package/skills/skill-creator/scripts/run_eval.py +310 -0
  442. package/skills/skill-creator/scripts/run_loop.py +332 -0
  443. package/skills/skill-creator/scripts/utils.py +47 -0
  444. package/skills/using-TDD/SKILL.md +410 -0
  445. package/skills/using-serena-lsp/README.md +8 -0
  446. package/skills/using-serena-lsp/REFERENCE.md +194 -0
  447. package/skills/using-serena-lsp/SKILL.md +82 -0
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Python Quality Gate - PostToolUse hook for Claude Code.
4
+ Runs ruff (linting/formatting) and mypy (type checking) on edited Python files.
5
+
6
+ Exit codes:
7
+ 0 - All checks passed
8
+ 1 - Fatal error
9
+ 2 - Blocking errors found (Claude must fix)
10
+ """
11
+
12
+ import json
13
+ import os
14
+ import sys
15
+ import subprocess
16
+ import shutil
17
+ from pathlib import Path
18
+
19
+ # Colors for output
20
+ class Colors:
21
+ RED = '\x1b[0;31m'
22
+ GREEN = '\x1b[0;32m'
23
+ YELLOW = '\x1b[0;33m'
24
+ BLUE = '\x1b[0;34m'
25
+ CYAN = '\x1b[0;36m'
26
+ RESET = '\x1b[0m'
27
+
28
+ def log_info(msg: str):
29
+ print(f"{Colors.BLUE}[INFO]{Colors.RESET} {msg}", file=sys.stderr)
30
+
31
+ def log_error(msg: str):
32
+ print(f"{Colors.RED}[ERROR]{Colors.RESET} {msg}", file=sys.stderr)
33
+
34
+ def log_success(msg: str):
35
+ print(f"{Colors.GREEN}[OK]{Colors.RESET} {msg}", file=sys.stderr)
36
+
37
+ def log_warning(msg: str):
38
+ print(f"{Colors.YELLOW}[WARN]{Colors.RESET} {msg}", file=sys.stderr)
39
+
40
+ def log_debug(msg: str):
41
+ if os.environ.get('CLAUDE_HOOKS_DEBUG', 'false').lower() == 'true':
42
+ print(f"{Colors.CYAN}[DEBUG]{Colors.RESET} {msg}", file=sys.stderr)
43
+
44
+ def find_project_root(file_path: str) -> str:
45
+ """Find project root by looking for pyproject.toml, setup.py, or .git"""
46
+ path = Path(file_path).parent
47
+ while path != path.parent:
48
+ if (path / 'pyproject.toml').exists() or \
49
+ (path / 'setup.py').exists() or \
50
+ (path / '.git').exists():
51
+ return str(path)
52
+ path = path.parent
53
+ return str(path)
54
+
55
+ def is_python_file(file_path: str) -> bool:
56
+ """Check if file is a Python source file"""
57
+ return file_path.endswith('.py') and not file_path.endswith('__init__.py')
58
+
59
+ def check_ruff(file_path: str, project_root: str, autofix: bool = False) -> tuple[bool, list[str], list[str]]:
60
+ """
61
+ Run ruff linting and formatting checks.
62
+ Returns: (passed, errors, autofixes)
63
+ """
64
+ errors = []
65
+ autofixes = []
66
+
67
+ # Check if ruff is available
68
+ ruff_path = shutil.which('ruff')
69
+ if not ruff_path:
70
+ log_debug('Ruff not found in PATH - skipping ruff checks')
71
+ return True, errors, autofixes
72
+
73
+ log_info('Running Ruff linting...')
74
+
75
+ # Run ruff check
76
+ cmd = ['ruff', 'check', '--output-format=full', file_path]
77
+ try:
78
+ result = subprocess.run(cmd, capture_output=True, text=True, cwd=project_root)
79
+
80
+ if result.returncode != 0:
81
+ if autofix:
82
+ log_warning('Ruff issues found, attempting auto-fix...')
83
+ fix_cmd = ['ruff', 'check', '--fix', file_path]
84
+ fix_result = subprocess.run(fix_cmd, capture_output=True, text=True, cwd=project_root)
85
+
86
+ if fix_result.returncode == 0:
87
+ log_success('Ruff auto-fixed all issues!')
88
+ autofixes.append('Ruff auto-fixed linting issues')
89
+ else:
90
+ errors.append(f'Ruff found issues that could not be auto-fixed')
91
+ errors.extend(result.stdout.strip().split('\n'))
92
+ else:
93
+ errors.append(f'Ruff found linting issues in {os.path.basename(file_path)}')
94
+ errors.extend(result.stdout.strip().split('\n'))
95
+ else:
96
+ log_success('Ruff linting passed')
97
+
98
+ except Exception as e:
99
+ log_debug(f'Ruff check error: {e}')
100
+
101
+ # Run ruff format check
102
+ log_info('Running Ruff format check...')
103
+ format_cmd = ['ruff', 'format', '--check', file_path]
104
+ try:
105
+ result = subprocess.run(format_cmd, capture_output=True, text=True, cwd=project_root)
106
+
107
+ if result.returncode != 0:
108
+ if autofix:
109
+ log_warning('Ruff format issues found, auto-formatting...')
110
+ format_fix_cmd = ['ruff', 'format', file_path]
111
+ format_fix_result = subprocess.run(format_fix_cmd, capture_output=True, text=True, cwd=project_root)
112
+
113
+ if format_fix_result.returncode == 0:
114
+ log_success('Ruff auto-formatted the file!')
115
+ autofixes.append('Ruff auto-formatted the file')
116
+ else:
117
+ errors.append(f'Ruff formatting issues in {os.path.basename(file_path)}')
118
+ else:
119
+ errors.append(f'Ruff formatting issues in {os.path.basename(file_path)}')
120
+ else:
121
+ log_success('Ruff formatting correct')
122
+
123
+ except Exception as e:
124
+ log_debug(f'Ruff format error: {e}')
125
+
126
+ return len(errors) == 0, errors, autofixes
127
+
128
+ def check_mypy(file_path: str, project_root: str) -> tuple[bool, list[str]]:
129
+ """
130
+ Run mypy type checking.
131
+ Returns: (passed, errors)
132
+ """
133
+ errors = []
134
+
135
+ # Check if mypy is available
136
+ mypy_path = shutil.which('mypy')
137
+ if not mypy_path:
138
+ log_debug('Mypy not found in PATH - skipping type checking')
139
+ return True, errors
140
+
141
+ log_info('Running Mypy type checking...')
142
+
143
+ cmd = ['mypy', '--pretty', file_path]
144
+ try:
145
+ result = subprocess.run(cmd, capture_output=True, text=True, cwd=project_root)
146
+
147
+ if result.returncode != 0:
148
+ errors.append(f'Mypy found type errors in {os.path.basename(file_path)}')
149
+ if result.stdout:
150
+ errors.extend(result.stdout.strip().split('\n'))
151
+ if result.stderr:
152
+ errors.extend(result.stderr.strip().split('\n'))
153
+ else:
154
+ log_success('Mypy type checking passed')
155
+
156
+ except Exception as e:
157
+ log_debug(f'Mypy error: {e}')
158
+
159
+ return len(errors) == 0, errors
160
+
161
+ def check_pytest_suggestions(file_path: str, project_root: str):
162
+ """Suggest running tests if test file exists"""
163
+ base_name = file_path.replace('.py', '')
164
+ test_paths = [
165
+ f'{base_name}_test.py',
166
+ f'{base_name}_tests.py',
167
+ f'test_{Path(file_path).name}',
168
+ ]
169
+
170
+ # Check same directory
171
+ for test_path in test_paths:
172
+ if Path(test_path).exists():
173
+ log_warning(f'💡 Related test found: {os.path.basename(test_path)}')
174
+ log_warning(' Consider running: pytest')
175
+ return
176
+
177
+ # Check __tests__ directory
178
+ tests_dir = Path(file_path).parent / '__tests__'
179
+ if tests_dir.exists():
180
+ for test_path in tests_dir.glob(f'test_{Path(file_path).name}'):
181
+ log_warning(f'💡 Related test found: __tests__/{test_path.name}')
182
+ log_warning(' Consider running: pytest')
183
+ return
184
+
185
+ log_warning(f'💡 No test file found for {os.path.basename(file_path)}')
186
+
187
+ def print_summary(errors: list[str], autofixes: list[str]):
188
+ """Print summary of errors and autofixes"""
189
+ if autofixes:
190
+ print(f'\n{Colors.BLUE}═══ Auto-fixes Applied ═══{Colors.RESET}', file=sys.stderr)
191
+ for fix in autofixes:
192
+ print(f'{Colors.GREEN}✨{Colors.RESET} {fix}', file=sys.stderr)
193
+ print(f'{Colors.GREEN}Automatically fixed {len(autofixes)} issue(s)!{Colors.RESET}', file=sys.stderr)
194
+
195
+ if errors:
196
+ print(f'\n{Colors.BLUE}═══ Quality Check Summary ═══{Colors.RESET}', file=sys.stderr)
197
+ for error in errors:
198
+ print(f'{Colors.RED}❌{Colors.RESET} {error}', file=sys.stderr)
199
+ print(f'\n{Colors.RED}Found {len(errors)} issue(s) that MUST be fixed!{Colors.RESET}', file=sys.stderr)
200
+ print(f'{Colors.RED}══════════════════════════════════════{Colors.RESET}', file=sys.stderr)
201
+ print(f'{Colors.RED}❌ ALL ISSUES ARE BLOCKING ❌{Colors.RESET}', file=sys.stderr)
202
+ print(f'{Colors.RED}══════════════════════════════════════{Colors.RESET}', file=sys.stderr)
203
+ print(f'{Colors.RED}Fix EVERYTHING above until all checks are ✅ GREEN{Colors.RESET}', file=sys.stderr)
204
+
205
+ def parse_json_input() -> dict:
206
+ """Parse JSON input from stdin"""
207
+ input_data = sys.stdin.read().strip()
208
+
209
+ if not input_data:
210
+ log_warning('No JSON input provided.')
211
+ print(f'\n{Colors.YELLOW}👉 Hook executed but no input to process.{Colors.RESET}', file=sys.stderr)
212
+ sys.exit(0)
213
+
214
+ try:
215
+ return json.loads(input_data)
216
+ except json.JSONDecodeError as e:
217
+ log_error(f'Failed to parse JSON: {e}')
218
+ sys.exit(1)
219
+
220
+ def extract_file_path(input_data: dict) -> str | None:
221
+ """Extract file path from tool input"""
222
+ tool_input = input_data.get('tool_input', {})
223
+ return tool_input.get('file_path') or tool_input.get('path')
224
+
225
+ def main():
226
+ """Main entry point"""
227
+ print('', file=sys.stderr)
228
+ print(f'📦 Python Quality Check - Starting...', file=sys.stderr)
229
+ print('─────────────────────────────────────', file=sys.stderr)
230
+
231
+ # Parse input
232
+ input_data = parse_json_input()
233
+ file_path = extract_file_path(input_data)
234
+
235
+ if not file_path:
236
+ log_warning('No file path found in JSON input.')
237
+ print(f'\n{Colors.YELLOW}👉 No file to check - tool may not be file-related.{Colors.RESET}', file=sys.stderr)
238
+ sys.exit(0)
239
+
240
+ # Check if file exists
241
+ if not Path(file_path).exists():
242
+ log_info(f'File does not exist: {file_path}')
243
+ print(f'\n{Colors.YELLOW}👉 File skipped - doesn\'t exist.{Colors.RESET}', file=sys.stderr)
244
+ sys.exit(0)
245
+
246
+ # Skip non-Python files
247
+ if not is_python_file(file_path):
248
+ log_info(f'Skipping non-Python file: {file_path}')
249
+ print(f'\n{Colors.GREEN}✅ No checks needed for {os.path.basename(file_path)}{Colors.RESET}', file=sys.stderr)
250
+ sys.exit(0)
251
+
252
+ # Update header
253
+ print('', file=sys.stderr)
254
+ print(f'🔍 Validating: {os.path.basename(file_path)}', file=sys.stderr)
255
+ print('─────────────────────────────────────', file=sys.stderr)
256
+ log_info(f'Checking: {file_path}')
257
+
258
+ # Find project root
259
+ project_root = find_project_root(file_path)
260
+ log_debug(f'Project root: {project_root}')
261
+
262
+ # Get config from environment
263
+ autofix = os.environ.get('CLAUDE_HOOKS_AUTOFIX', 'true').lower() == 'true'
264
+ ruff_enabled = os.environ.get('CLAUDE_HOOKS_RUFF_ENABLED', 'true').lower() != 'false'
265
+ mypy_enabled = os.environ.get('CLAUDE_HOOKS_MYPY_ENABLED', 'true').lower() != 'false'
266
+
267
+ all_errors = []
268
+ all_autofixes = []
269
+
270
+ # Run ruff checks
271
+ if ruff_enabled:
272
+ ruff_passed, ruff_errors, ruff_autofixes = check_ruff(file_path, project_root, autofix)
273
+ all_errors.extend(ruff_errors)
274
+ all_autofixes.extend(ruff_autofixes)
275
+
276
+ # Run mypy checks
277
+ if mypy_enabled:
278
+ mypy_passed, mypy_errors = check_mypy(file_path, project_root)
279
+ all_errors.extend(mypy_errors)
280
+
281
+ # Print summary
282
+ print_summary(all_errors, all_autofixes)
283
+
284
+ # Exit with appropriate code
285
+ if all_errors:
286
+ print(f'\n{Colors.RED}🛑 FAILED - Fix issues in your edited file! 🛑{Colors.RESET}', file=sys.stderr)
287
+ print(f'{Colors.CYAN}💡 CLAUDE.md CHECK:{Colors.RESET}', file=sys.stderr)
288
+ print(f'{Colors.CYAN} → What CLAUDE.md pattern would have prevented this?{Colors.RESET}', file=sys.stderr)
289
+ print(f'{Colors.YELLOW}📋 NEXT STEPS:{Colors.RESET}', file=sys.stderr)
290
+ print(f'{Colors.YELLOW} 1. Fix the issues listed above{Colors.RESET}', file=sys.stderr)
291
+ print(f'{Colors.YELLOW} 2. The hook will run again automatically{Colors.RESET}', file=sys.stderr)
292
+ print(f'{Colors.YELLOW} 3. Continue once all checks pass{Colors.RESET}', file=sys.stderr)
293
+ sys.exit(2)
294
+ else:
295
+ print(f'\n{Colors.GREEN}✅ Quality check passed for {os.path.basename(file_path)}{Colors.RESET}', file=sys.stderr)
296
+ if all_autofixes:
297
+ print(f'\n{Colors.YELLOW}👉 File quality verified. Auto-fixes applied. Continue with your task.{Colors.RESET}', file=sys.stderr)
298
+ else:
299
+ print(f'\n{Colors.YELLOW}👉 File quality verified. Continue with your task.{Colors.RESET}', file=sys.stderr)
300
+
301
+ # Suggest tests
302
+ check_pytest_suggestions(file_path, project_root)
303
+
304
+ sys.exit(0)
305
+
306
+ if __name__ == '__main__':
307
+ try:
308
+ main()
309
+ except Exception as e:
310
+ log_error(f'Fatal error: {e}')
311
+ sys.exit(1)
@@ -0,0 +1,16 @@
1
+ {
2
+ "hooks": {
3
+ "PostToolUse": [
4
+ {
5
+ "matcher": "Write|Edit",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/quality-check.py\"",
10
+ "timeout": 30
11
+ }
12
+ ]
13
+ }
14
+ ]
15
+ }
16
+ }
@@ -0,0 +1,112 @@
1
+ # Using PY Quality Gate
2
+
3
+ **PY Quality Gate** enforces Python code quality with ruff (linting/formatting) and mypy (type checking). Runs automatically on every file edit.
4
+
5
+ ## What It Does
6
+
7
+ - **Ruff linting** - Fast Python linting (10-100x faster than flake8)
8
+ - **Ruff formatting** - Code formatting (Black-compatible)
9
+ - **Mypy type checking** - Static type validation
10
+ - **Auto-fix** - Automatically fixes issues when possible
11
+ - **Fast feedback** - Runs in <1s for most files
12
+
13
+ ## How It Works
14
+
15
+ When you edit a Python file:
16
+
17
+ 1. PostToolUse hook fires after Write/Edit
18
+ 2. Runs `quality-check.py` with the file path
19
+ 3. Checks ruff lint, ruff format, mypy types
20
+ 4. Auto-fixes issues if configured
21
+ 5. Returns exit code 2 if blocking errors found
22
+
23
+ ## Requirements
24
+
25
+ - Python 3.8+
26
+ - ruff installed (`pip install ruff`)
27
+ - mypy installed (`pip install mypy`) - optional
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ # Install project skill
33
+ xtrm install project py-quality-gate
34
+
35
+ # Install dependencies
36
+ pip install ruff mypy
37
+ ```
38
+
39
+ ## Configuration
40
+
41
+ Configure via environment variables in your shell or `.env`:
42
+
43
+ ```bash
44
+ # Enable/disable checks
45
+ export CLAUDE_HOOKS_RUFF_ENABLED=true
46
+ export CLAUDE_HOOKS_MYPY_ENABLED=true
47
+
48
+ # Auto-fix settings
49
+ export CLAUDE_HOOKS_AUTOFIX=true
50
+
51
+ # Debug mode
52
+ export CLAUDE_HOOKS_DEBUG=true
53
+ ```
54
+
55
+ ## Ruff Configuration
56
+
57
+ Create `pyproject.toml` or `ruff.toml` in your project:
58
+
59
+ ```toml
60
+ [tool.ruff]
61
+ line-length = 88
62
+ target-version = "py38"
63
+
64
+ [tool.ruff.lint]
65
+ select = ["E", "F", "W", "I", "N", "UP", "B", "C4"]
66
+ ```
67
+
68
+ ## Mypy Configuration
69
+
70
+ Create `mypy.ini` or `pyproject.toml`:
71
+
72
+ ```ini
73
+ [mypy]
74
+ python_version = 3.8
75
+ warn_return_any = True
76
+ warn_unused_configs = True
77
+ disallow_untyped_defs = False
78
+ ```
79
+
80
+ ## Exit Codes
81
+
82
+ | Code | Meaning |
83
+ |------|---------|
84
+ | 0 | All checks passed |
85
+ | 1 | Fatal error (hook crashed) |
86
+ | 2 | Blocking errors found (Claude must fix) |
87
+
88
+ ## Troubleshooting
89
+
90
+ **"ruff: command not found"**
91
+ - Install: `pip install ruff` or `pipx install ruff`
92
+
93
+ **"mypy: command not found"**
94
+ - Install: `pip install mypy`
95
+ - Or set `CLAUDE_HOOKS_MYPY_ENABLED=false`
96
+
97
+ **Hook not running**
98
+ - Verify PostToolUse hook in `.claude/settings.json`
99
+ - Check Python path is correct
100
+
101
+ ## Test Suggestions
102
+
103
+ The hook automatically suggests running pytest if related test files exist:
104
+ - `test_<filename>.py`
105
+ - `<filename>_test.py`
106
+ - `__tests__/test_<filename>.py`
107
+
108
+ ## See Also
109
+
110
+ - Full documentation: `.claude/docs/py-quality-gate-readme.md`
111
+ - Ruff docs: https://docs.astral.sh/ruff/
112
+ - Mypy docs: https://mypy.readthedocs.io/
@@ -0,0 +1,147 @@
1
+ # PY Quality Gate
2
+
3
+ **Python quality gate** for Claude Code. Runs ruff (linting/formatting) and mypy (type checking) automatically on every file edit.
4
+
5
+ ## What It Does
6
+
7
+ PY Quality Gate enforces Python code quality standards in real-time:
8
+
9
+ | Check | Description | Auto-fix |
10
+ |-------|-------------|----------|
11
+ | **Ruff lint** | Code style, best practices, errors | Yes |
12
+ | **Ruff format** | Black-compatible formatting | Yes |
13
+ | **Mypy types** | Static type checking | No |
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ # Install project skill
19
+ xtrm install project py-quality-gate
20
+
21
+ # Install Python dependencies
22
+ pip install ruff mypy
23
+ ```
24
+
25
+ ## How It Works
26
+
27
+ The quality gate runs as a `PostToolUse` hook:
28
+
29
+ 1. You edit a Python file
30
+ 2. After the edit completes, the hook fires
31
+ 3. `quality-check.py` validates the file
32
+ 4. Issues are reported with auto-fix when possible
33
+ 5. Exit code 2 blocks if critical errors found
34
+
35
+ ## Configuration
36
+
37
+ ### Environment Variables
38
+
39
+ ```bash
40
+ # Enable/disable checks
41
+ export CLAUDE_HOOKS_RUFF_ENABLED=true
42
+ export CLAUDE_HOOKS_MYPY_ENABLED=true
43
+
44
+ # Auto-fix settings
45
+ export CLAUDE_HOOKS_AUTOFIX=true
46
+
47
+ # Debug mode
48
+ export CLAUDE_HOOKS_DEBUG=true
49
+ ```
50
+
51
+ ### Ruff Configuration
52
+
53
+ Create `pyproject.toml` in your project:
54
+
55
+ ```toml
56
+ [tool.ruff]
57
+ line-length = 88
58
+ target-version = "py38"
59
+
60
+ [tool.ruff.lint]
61
+ select = ["E", "F", "W", "I", "N", "UP", "B", "C4"]
62
+ ignore = ["E501"] # Line length (handled by formatter)
63
+ ```
64
+
65
+ ### Mypy Configuration
66
+
67
+ Create `mypy.ini` in your project:
68
+
69
+ ```ini
70
+ [mypy]
71
+ python_version = 3.8
72
+ warn_return_any = True
73
+ warn_unused_configs = True
74
+ disallow_untyped_defs = False
75
+ ignore_missing_imports = True
76
+ ```
77
+
78
+ ## Features
79
+
80
+ ### Ruff Linting
81
+ - 10-100x faster than flake8
82
+ - Auto-fixes supported
83
+ - 500+ built-in rules
84
+ - Compatible with Black
85
+
86
+ ### Ruff Formatting
87
+ - Black-compatible formatter
88
+ - Fast and consistent
89
+ - Auto-fixes formatting issues
90
+
91
+ ### Mypy Type Checking
92
+ - Static type validation
93
+ - Catches type errors before runtime
94
+ - Configurable strictness
95
+
96
+ ### Smart Test Suggestions
97
+ - Detects related test files
98
+ - Suggests running pytest
99
+ - Supports multiple test naming conventions
100
+
101
+ ## Exit Codes
102
+
103
+ | Code | Meaning |
104
+ |------|---------|
105
+ | 0 | All checks passed |
106
+ | 1 | Fatal error (hook crashed) |
107
+ | 2 | Blocking errors found |
108
+
109
+ ## Troubleshooting
110
+
111
+ **Ruff not found**
112
+ ```bash
113
+ pip install ruff
114
+ # or
115
+ pipx install ruff
116
+ ```
117
+
118
+ **Mypy not found**
119
+ ```bash
120
+ pip install mypy
121
+ ```
122
+
123
+ **Hook not running**
124
+ - Verify PostToolUse hook in `.claude/settings.json`
125
+ - Check Python path: `which python3`
126
+
127
+ **False positives from dependencies**
128
+ - Add to `mypy.ini`: `ignore_missing_imports = True`
129
+ - Add to `pyproject.toml`: exclude patterns
130
+
131
+ ## Quick Commands
132
+
133
+ ```bash
134
+ # Run ruff manually
135
+ ruff check .
136
+ ruff format .
137
+
138
+ # Run mypy manually
139
+ mypy .
140
+
141
+ # Run pytest
142
+ pytest
143
+ ```
144
+
145
+ ## Reference
146
+
147
+ Inspired by: https://github.com/bartolli/claude-code-typescript-hooks
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Pre-commit hook: Documentation reminder.
4
+
5
+ Warns when behavior-changing source files are staged for commit without
6
+ corresponding SSOT documentation updates. Always exits 0 (non-blocking).
7
+
8
+ Usage: called automatically by .githooks/pre-commit
9
+ """
10
+ import subprocess
11
+ import sys
12
+
13
+ # Source paths that indicate behavior-changing code.
14
+ # If any staged file starts with one of these, the reminder fires.
15
+ SOURCE_PATHS = [
16
+ "scripts/core/",
17
+ "scripts/data/",
18
+ "scripts/ingestion/",
19
+ "mcp_server/",
20
+ "alembic/",
21
+ ]
22
+
23
+ # Proxy for "agent already ran /documenting".
24
+ # If any of these are also staged, the reminder is suppressed.
25
+ SSOT_PATHS = [
26
+ ".serena/memories/",
27
+ ]
28
+
29
+ # Colors
30
+ YELLOW = "\033[1;33m"
31
+ BLUE = "\033[0;34m"
32
+ NC = "\033[0m"
33
+
34
+
35
+ def get_staged_files() -> list[str]:
36
+ result = subprocess.run(
37
+ ["git", "diff", "--cached", "--name-only"],
38
+ capture_output=True, text=True
39
+ )
40
+ return [f for f in result.stdout.splitlines() if f]
41
+
42
+
43
+ def main() -> None:
44
+ staged = get_staged_files()
45
+ if not staged:
46
+ sys.exit(0)
47
+
48
+ source_changed = [f for f in staged if any(f.startswith(p) for p in SOURCE_PATHS)]
49
+ ssot_changed = [f for f in staged if any(f.startswith(p) for p in SSOT_PATHS)]
50
+
51
+ if source_changed and not ssot_changed:
52
+ print()
53
+ print(f"{YELLOW}[doc-hook] ⚠ Source changes staged without SSOT updates.{NC}")
54
+ print(f"{BLUE}[doc-hook] If this commit changes behavior or architecture, run /documenting first.{NC}")
55
+ print(f"[doc-hook] Changed source paths:")
56
+ for f in source_changed[:6]:
57
+ print(f"[doc-hook] - {f}")
58
+ if len(source_changed) > 6:
59
+ print(f"[doc-hook] ... and {len(source_changed) - 6} more")
60
+ print(f"[doc-hook] Commit proceeds — this is a reminder, not a block.")
61
+ print()
62
+
63
+ sys.exit(0)
64
+
65
+
66
+ if __name__ == "__main__":
67
+ main()