xtrm-tools 0.5.25 → 0.5.26

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 (252) hide show
  1. package/.claude-plugin/marketplace.json +19 -0
  2. package/.claude-plugin/plugin.json +9 -0
  3. package/cli/dist/index.cjs +59 -52
  4. package/cli/dist/index.cjs.map +1 -1
  5. package/cli/package.json +1 -1
  6. package/hooks/beads-claim-sync.mjs +1 -3
  7. package/package.json +5 -1
  8. package/plugins/xtrm-tools/.claude-plugin/plugin.json +9 -0
  9. package/plugins/xtrm-tools/.mcp.json +18 -0
  10. package/plugins/xtrm-tools/hooks/README.md +61 -0
  11. package/plugins/xtrm-tools/hooks/beads-claim-sync.mjs +223 -0
  12. package/plugins/xtrm-tools/hooks/beads-commit-gate.mjs +70 -0
  13. package/plugins/xtrm-tools/hooks/beads-compact-restore.mjs +69 -0
  14. package/plugins/xtrm-tools/hooks/beads-compact-save.mjs +51 -0
  15. package/plugins/xtrm-tools/hooks/beads-edit-gate.mjs +85 -0
  16. package/plugins/xtrm-tools/hooks/beads-gate-core.mjs +236 -0
  17. package/plugins/xtrm-tools/hooks/beads-gate-messages.mjs +68 -0
  18. package/plugins/xtrm-tools/hooks/beads-gate-utils.mjs +194 -0
  19. package/plugins/xtrm-tools/hooks/beads-memory-gate.mjs +81 -0
  20. package/plugins/xtrm-tools/hooks/beads-stop-gate.mjs +53 -0
  21. package/plugins/xtrm-tools/hooks/gitnexus/gitnexus-hook.cjs +222 -0
  22. package/plugins/xtrm-tools/hooks/hooks.json +115 -0
  23. package/plugins/xtrm-tools/hooks/quality-check-env.mjs +79 -0
  24. package/plugins/xtrm-tools/hooks/quality-check.cjs +1286 -0
  25. package/plugins/xtrm-tools/hooks/quality-check.py +345 -0
  26. package/plugins/xtrm-tools/hooks/statusline.mjs +145 -0
  27. package/plugins/xtrm-tools/hooks/using-xtrm-reminder.mjs +35 -0
  28. package/plugins/xtrm-tools/hooks/worktree-boundary.mjs +33 -0
  29. package/plugins/xtrm-tools/hooks/xtrm-logger.mjs +123 -0
  30. package/plugins/xtrm-tools/hooks/xtrm-session-logger.mjs +27 -0
  31. package/plugins/xtrm-tools/hooks/xtrm-tool-logger.mjs +53 -0
  32. package/plugins/xtrm-tools/skills/README.txt +31 -0
  33. package/plugins/xtrm-tools/skills/clean-code/SKILL.md +201 -0
  34. package/plugins/xtrm-tools/skills/creating-service-skills/SKILL.md +433 -0
  35. package/plugins/xtrm-tools/skills/creating-service-skills/references/script_quality_standards.md +425 -0
  36. package/plugins/xtrm-tools/skills/creating-service-skills/references/service_skill_system_guide.md +278 -0
  37. package/plugins/xtrm-tools/skills/creating-service-skills/scripts/bootstrap.py +326 -0
  38. package/plugins/xtrm-tools/skills/creating-service-skills/scripts/deep_dive.py +304 -0
  39. package/plugins/xtrm-tools/skills/creating-service-skills/scripts/scaffolder.py +482 -0
  40. package/plugins/xtrm-tools/skills/delegating/SKILL.md +196 -0
  41. package/plugins/xtrm-tools/skills/delegating/config.yaml +210 -0
  42. package/plugins/xtrm-tools/skills/delegating/references/orchestration-protocols.md +41 -0
  43. package/plugins/xtrm-tools/skills/docker-expert/SKILL.md +409 -0
  44. package/plugins/xtrm-tools/skills/documenting/CHANGELOG.md +23 -0
  45. package/plugins/xtrm-tools/skills/documenting/README.md +148 -0
  46. package/plugins/xtrm-tools/skills/documenting/SKILL.md +113 -0
  47. package/plugins/xtrm-tools/skills/documenting/examples/example_pattern.md +70 -0
  48. package/plugins/xtrm-tools/skills/documenting/examples/example_reference.md +70 -0
  49. package/plugins/xtrm-tools/skills/documenting/examples/example_ssot_analytics.md +64 -0
  50. package/plugins/xtrm-tools/skills/documenting/examples/example_workflow.md +141 -0
  51. package/plugins/xtrm-tools/skills/documenting/references/changelog-format.md +97 -0
  52. package/plugins/xtrm-tools/skills/documenting/references/metadata-schema.md +136 -0
  53. package/plugins/xtrm-tools/skills/documenting/references/taxonomy.md +81 -0
  54. package/plugins/xtrm-tools/skills/documenting/references/versioning-rules.md +78 -0
  55. package/plugins/xtrm-tools/skills/documenting/scripts/bump_version.sh +60 -0
  56. package/plugins/xtrm-tools/skills/documenting/scripts/changelog/__init__.py +0 -0
  57. package/plugins/xtrm-tools/skills/documenting/scripts/changelog/add_entry.py +216 -0
  58. package/plugins/xtrm-tools/skills/documenting/scripts/changelog/bump_release.py +117 -0
  59. package/plugins/xtrm-tools/skills/documenting/scripts/changelog/init_changelog.py +54 -0
  60. package/plugins/xtrm-tools/skills/documenting/scripts/changelog/validate_changelog.py +128 -0
  61. package/plugins/xtrm-tools/skills/documenting/scripts/drift_detector.py +266 -0
  62. package/plugins/xtrm-tools/skills/documenting/scripts/generate_template.py +311 -0
  63. package/plugins/xtrm-tools/skills/documenting/scripts/list_by_category.sh +84 -0
  64. package/plugins/xtrm-tools/skills/documenting/scripts/orchestrator.py +255 -0
  65. package/plugins/xtrm-tools/skills/documenting/scripts/validate_metadata.py +242 -0
  66. package/plugins/xtrm-tools/skills/documenting/templates/CHANGELOG.md.template +13 -0
  67. package/plugins/xtrm-tools/skills/documenting/tests/integration_test.sh +70 -0
  68. package/plugins/xtrm-tools/skills/documenting/tests/test_changelog.py +201 -0
  69. package/plugins/xtrm-tools/skills/documenting/tests/test_drift_detector.py +80 -0
  70. package/plugins/xtrm-tools/skills/documenting/tests/test_orchestrator.py +52 -0
  71. package/plugins/xtrm-tools/skills/documenting/tests/test_validate_metadata.py +64 -0
  72. package/plugins/xtrm-tools/skills/find-skills/SKILL.md +133 -0
  73. package/plugins/xtrm-tools/skills/gitnexus-debugging/SKILL.md +85 -0
  74. package/plugins/xtrm-tools/skills/gitnexus-exploring/SKILL.md +75 -0
  75. package/plugins/xtrm-tools/skills/gitnexus-impact-analysis/SKILL.md +94 -0
  76. package/plugins/xtrm-tools/skills/gitnexus-refactoring/SKILL.md +113 -0
  77. package/plugins/xtrm-tools/skills/hook-development/SKILL.md +797 -0
  78. package/plugins/xtrm-tools/skills/hook-development/examples/load-context.sh +55 -0
  79. package/plugins/xtrm-tools/skills/hook-development/examples/quality-check.js +1168 -0
  80. package/plugins/xtrm-tools/skills/hook-development/examples/validate-bash.sh +43 -0
  81. package/plugins/xtrm-tools/skills/hook-development/examples/validate-write.sh +38 -0
  82. package/plugins/xtrm-tools/skills/hook-development/references/advanced.md +527 -0
  83. package/plugins/xtrm-tools/skills/hook-development/references/migration.md +369 -0
  84. package/plugins/xtrm-tools/skills/hook-development/references/patterns.md +412 -0
  85. package/plugins/xtrm-tools/skills/hook-development/scripts/README.md +164 -0
  86. package/plugins/xtrm-tools/skills/hook-development/scripts/hook-linter.sh +153 -0
  87. package/plugins/xtrm-tools/skills/hook-development/scripts/test-hook.sh +252 -0
  88. package/plugins/xtrm-tools/skills/hook-development/scripts/validate-hook-schema.sh +159 -0
  89. package/plugins/xtrm-tools/skills/obsidian-cli/SKILL.md +106 -0
  90. package/plugins/xtrm-tools/skills/orchestrating-agents/SKILL.md +135 -0
  91. package/plugins/xtrm-tools/skills/orchestrating-agents/config.yaml +45 -0
  92. package/plugins/xtrm-tools/skills/orchestrating-agents/references/agent-context-integration.md +37 -0
  93. package/plugins/xtrm-tools/skills/orchestrating-agents/references/examples.md +45 -0
  94. package/plugins/xtrm-tools/skills/orchestrating-agents/references/handover-protocol.md +31 -0
  95. package/plugins/xtrm-tools/skills/orchestrating-agents/references/workflows.md +42 -0
  96. package/plugins/xtrm-tools/skills/orchestrating-agents/scripts/detect_neighbors.py +23 -0
  97. package/plugins/xtrm-tools/skills/prompt-improving/README.md +162 -0
  98. package/plugins/xtrm-tools/skills/prompt-improving/SKILL.md +74 -0
  99. package/plugins/xtrm-tools/skills/prompt-improving/references/analysis_commands.md +24 -0
  100. package/plugins/xtrm-tools/skills/prompt-improving/references/chain_of_thought.md +24 -0
  101. package/plugins/xtrm-tools/skills/prompt-improving/references/mcp_definitions.md +20 -0
  102. package/plugins/xtrm-tools/skills/prompt-improving/references/multishot.md +23 -0
  103. package/plugins/xtrm-tools/skills/prompt-improving/references/xml_core.md +60 -0
  104. package/plugins/xtrm-tools/skills/python-testing/SKILL.md +815 -0
  105. package/plugins/xtrm-tools/skills/scoping-service-skills/SKILL.md +231 -0
  106. package/plugins/xtrm-tools/skills/scoping-service-skills/scripts/scope.py +74 -0
  107. package/plugins/xtrm-tools/skills/senior-backend/SKILL.md +209 -0
  108. package/plugins/xtrm-tools/skills/senior-backend/references/api_design_patterns.md +103 -0
  109. package/plugins/xtrm-tools/skills/senior-backend/references/backend_security_practices.md +103 -0
  110. package/plugins/xtrm-tools/skills/senior-backend/references/database_optimization_guide.md +103 -0
  111. package/plugins/xtrm-tools/skills/senior-backend/scripts/api_load_tester.py +114 -0
  112. package/plugins/xtrm-tools/skills/senior-backend/scripts/api_scaffolder.py +114 -0
  113. package/plugins/xtrm-tools/skills/senior-backend/scripts/database_migration_tool.py +114 -0
  114. package/plugins/xtrm-tools/skills/senior-data-scientist/SKILL.md +226 -0
  115. package/plugins/xtrm-tools/skills/senior-data-scientist/references/experiment_design_frameworks.md +80 -0
  116. package/plugins/xtrm-tools/skills/senior-data-scientist/references/feature_engineering_patterns.md +80 -0
  117. package/plugins/xtrm-tools/skills/senior-data-scientist/references/statistical_methods_advanced.md +80 -0
  118. package/plugins/xtrm-tools/skills/senior-data-scientist/scripts/experiment_designer.py +100 -0
  119. package/plugins/xtrm-tools/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py +100 -0
  120. package/plugins/xtrm-tools/skills/senior-data-scientist/scripts/model_evaluation_suite.py +100 -0
  121. package/plugins/xtrm-tools/skills/senior-devops/SKILL.md +209 -0
  122. package/plugins/xtrm-tools/skills/senior-devops/references/cicd_pipeline_guide.md +103 -0
  123. package/plugins/xtrm-tools/skills/senior-devops/references/deployment_strategies.md +103 -0
  124. package/plugins/xtrm-tools/skills/senior-devops/references/infrastructure_as_code.md +103 -0
  125. package/plugins/xtrm-tools/skills/senior-devops/scripts/deployment_manager.py +114 -0
  126. package/plugins/xtrm-tools/skills/senior-devops/scripts/pipeline_generator.py +114 -0
  127. package/plugins/xtrm-tools/skills/senior-devops/scripts/terraform_scaffolder.py +114 -0
  128. package/plugins/xtrm-tools/skills/senior-security/SKILL.md +209 -0
  129. package/plugins/xtrm-tools/skills/senior-security/references/cryptography_implementation.md +103 -0
  130. package/plugins/xtrm-tools/skills/senior-security/references/penetration_testing_guide.md +103 -0
  131. package/plugins/xtrm-tools/skills/senior-security/references/security_architecture_patterns.md +103 -0
  132. package/plugins/xtrm-tools/skills/senior-security/scripts/pentest_automator.py +114 -0
  133. package/plugins/xtrm-tools/skills/senior-security/scripts/security_auditor.py +114 -0
  134. package/plugins/xtrm-tools/skills/senior-security/scripts/threat_modeler.py +114 -0
  135. package/plugins/xtrm-tools/skills/skill-creator/LICENSE.txt +202 -0
  136. package/plugins/xtrm-tools/skills/skill-creator/SKILL.md +479 -0
  137. package/plugins/xtrm-tools/skills/skill-creator/agents/analyzer.md +274 -0
  138. package/plugins/xtrm-tools/skills/skill-creator/agents/comparator.md +202 -0
  139. package/plugins/xtrm-tools/skills/skill-creator/agents/grader.md +223 -0
  140. package/plugins/xtrm-tools/skills/skill-creator/assets/eval_review.html +146 -0
  141. package/plugins/xtrm-tools/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  142. package/plugins/xtrm-tools/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  143. package/plugins/xtrm-tools/skills/skill-creator/references/schemas.md +430 -0
  144. package/plugins/xtrm-tools/skills/skill-creator/scripts/__init__.py +0 -0
  145. package/plugins/xtrm-tools/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  146. package/plugins/xtrm-tools/skills/skill-creator/scripts/generate_report.py +326 -0
  147. package/plugins/xtrm-tools/skills/skill-creator/scripts/improve_description.py +248 -0
  148. package/plugins/xtrm-tools/skills/skill-creator/scripts/package_skill.py +136 -0
  149. package/plugins/xtrm-tools/skills/skill-creator/scripts/quick_validate.py +103 -0
  150. package/plugins/xtrm-tools/skills/skill-creator/scripts/run_eval.py +310 -0
  151. package/plugins/xtrm-tools/skills/skill-creator/scripts/run_loop.py +332 -0
  152. package/plugins/xtrm-tools/skills/skill-creator/scripts/utils.py +47 -0
  153. package/plugins/xtrm-tools/skills/sync-docs/SKILL.md +155 -0
  154. package/plugins/xtrm-tools/skills/sync-docs/evals/evals.json +89 -0
  155. package/plugins/xtrm-tools/skills/sync-docs/references/doc-structure.md +99 -0
  156. package/plugins/xtrm-tools/skills/sync-docs/references/schema.md +103 -0
  157. package/plugins/xtrm-tools/skills/sync-docs/scripts/changelog/add_entry.py +216 -0
  158. package/plugins/xtrm-tools/skills/sync-docs/scripts/context_gatherer.py +240 -0
  159. package/plugins/xtrm-tools/skills/sync-docs/scripts/doc_structure_analyzer.py +495 -0
  160. package/plugins/xtrm-tools/skills/sync-docs/scripts/drift_detector.py +563 -0
  161. package/plugins/xtrm-tools/skills/sync-docs/scripts/validate_doc.py +365 -0
  162. package/plugins/xtrm-tools/skills/sync-docs/scripts/validate_metadata.py +185 -0
  163. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/benchmark.json +293 -0
  164. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/benchmark.md +13 -0
  165. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-doc-audit/eval_metadata.json +27 -0
  166. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/outputs/result.md +210 -0
  167. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/grading.json +28 -0
  168. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/timing.json +1 -0
  169. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/outputs/result.md +101 -0
  170. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/grading.json +28 -0
  171. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/timing.json +5 -0
  172. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/timing.json +5 -0
  173. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-fix-mode/eval_metadata.json +27 -0
  174. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/outputs/result.md +198 -0
  175. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/grading.json +28 -0
  176. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/timing.json +1 -0
  177. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/outputs/result.md +94 -0
  178. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/grading.json +28 -0
  179. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/timing.json +1 -0
  180. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/eval_metadata.json +27 -0
  181. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/outputs/result.md +237 -0
  182. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/grading.json +28 -0
  183. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
  184. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/outputs/result.md +134 -0
  185. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/grading.json +28 -0
  186. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/timing.json +1 -0
  187. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/benchmark.json +297 -0
  188. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/benchmark.md +13 -0
  189. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-doc-audit/eval_metadata.json +27 -0
  190. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/outputs/result.md +137 -0
  191. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/grading.json +92 -0
  192. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/timing.json +1 -0
  193. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/outputs/result.md +134 -0
  194. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/grading.json +86 -0
  195. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/timing.json +1 -0
  196. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-fix-mode/eval_metadata.json +27 -0
  197. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/outputs/result.md +193 -0
  198. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/grading.json +72 -0
  199. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/timing.json +1 -0
  200. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/outputs/result.md +211 -0
  201. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/grading.json +91 -0
  202. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/timing.json +5 -0
  203. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/eval_metadata.json +27 -0
  204. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/outputs/result.md +182 -0
  205. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
  206. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
  207. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/outputs/result.md +222 -0
  208. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/grading.json +88 -0
  209. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
  210. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/benchmark.json +298 -0
  211. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/benchmark.md +13 -0
  212. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-doc-audit/eval_metadata.json +27 -0
  213. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/outputs/result.md +125 -0
  214. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/grading.json +97 -0
  215. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/timing.json +5 -0
  216. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/outputs/result.md +144 -0
  217. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/grading.json +78 -0
  218. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/timing.json +5 -0
  219. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-fix-mode/eval_metadata.json +27 -0
  220. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/outputs/result.md +104 -0
  221. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/grading.json +91 -0
  222. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/timing.json +5 -0
  223. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/outputs/result.md +79 -0
  224. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/grading.json +82 -0
  225. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/timing.json +5 -0
  226. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/eval_metadata.json +27 -0
  227. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase1_context.json +302 -0
  228. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase2_drift.txt +33 -0
  229. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase3_analysis.json +114 -0
  230. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase4_fix.txt +118 -0
  231. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase5_validate.txt +38 -0
  232. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/result.md +158 -0
  233. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
  234. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/timing.json +5 -0
  235. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/outputs/result.md +71 -0
  236. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/grading.json +90 -0
  237. package/plugins/xtrm-tools/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
  238. package/plugins/xtrm-tools/skills/test-planning/SKILL.md +208 -0
  239. package/plugins/xtrm-tools/skills/test-planning/evals/evals.json +23 -0
  240. package/plugins/xtrm-tools/skills/updating-service-skills/SKILL.md +136 -0
  241. package/plugins/xtrm-tools/skills/updating-service-skills/scripts/drift_detector.py +222 -0
  242. package/plugins/xtrm-tools/skills/using-TDD/SKILL.md +410 -0
  243. package/plugins/xtrm-tools/skills/using-quality-gates/SKILL.md +254 -0
  244. package/plugins/xtrm-tools/skills/using-serena-lsp/README.md +8 -0
  245. package/plugins/xtrm-tools/skills/using-serena-lsp/REFERENCE.md +194 -0
  246. package/plugins/xtrm-tools/skills/using-serena-lsp/SKILL.md +82 -0
  247. package/plugins/xtrm-tools/skills/using-service-skills/SKILL.md +108 -0
  248. package/plugins/xtrm-tools/skills/using-service-skills/scripts/cataloger.py +74 -0
  249. package/plugins/xtrm-tools/skills/using-service-skills/scripts/skill_activator.py +152 -0
  250. package/plugins/xtrm-tools/skills/using-service-skills/scripts/test_skill_activator.py +58 -0
  251. package/plugins/xtrm-tools/skills/using-xtrm/SKILL.md +124 -0
  252. package/plugins/xtrm-tools/skills/xt-end/SKILL.md +128 -0
package/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xtrm-cli",
3
- "version": "0.5.25",
3
+ "version": "0.5.26",
4
4
  "description": "Claude Code tools installer (skills, hooks, MCP servers)",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",
@@ -150,7 +150,6 @@ function main() {
150
150
  kind: 'bd.claimed',
151
151
  outcome: 'allow',
152
152
  issueId,
153
- message: `Session ${sessionId} claimed issue ${issueId}`,
154
153
  });
155
154
 
156
155
  process.stdout.write(JSON.stringify({
@@ -191,7 +190,6 @@ function main() {
191
190
  kind: 'bd.closed',
192
191
  outcome: 'allow',
193
192
  issueId: closedIssueId,
194
- message: `Issue ${closedIssueId} closed`,
195
193
  });
196
194
  }
197
195
  if (commit) {
@@ -203,7 +201,7 @@ function main() {
203
201
  kind: 'bd.committed',
204
202
  outcome: commit.ok ? 'allow' : 'block',
205
203
  issueId: closedIssueId ?? null,
206
- message: commit.message,
204
+ data: { msg: commit.message },
207
205
  extra: { ok: commit.ok },
208
206
  });
209
207
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xtrm-tools",
3
- "version": "0.5.25",
3
+ "version": "0.5.26",
4
4
  "description": "Claude Code tools installer (skills, hooks, MCP servers)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -20,6 +20,8 @@
20
20
  "hooks",
21
21
  "skills",
22
22
  "project-skills",
23
+ ".claude-plugin",
24
+ "plugins",
23
25
  "!**/__pycache__/**",
24
26
  "!**/*.pyc",
25
27
  "!project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/test_*.py",
@@ -48,6 +50,8 @@
48
50
  "lint": "echo 'No linting configured'",
49
51
  "test": "npm test --workspace cli",
50
52
  "version": "npm run sync:cli-version && git add cli/package.json",
53
+ "prepack": "node scripts/prepack-plugin.mjs",
54
+ "postpack": "node scripts/postpack-plugin.mjs",
51
55
  "prepublishOnly": "npm run sync:cli-version && npm run build"
52
56
  },
53
57
  "engines": {
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "xtrm-tools",
3
+ "version": "0.5.26",
4
+ "description": "xtrm-tools: dual-runtime workflow enforcement (Claude Code + Pi) — hooks, extensions, skills, and MCP servers",
5
+ "author": {
6
+ "name": "jaggers"
7
+ },
8
+ "mcpServers": "./.mcp.json"
9
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "mcpServers": {
3
+ "github-grep": {
4
+ "type": "http",
5
+ "url": "https://mcp.grep.app"
6
+ },
7
+ "deepwiki": {
8
+ "type": "http",
9
+ "url": "https://mcp.deepwiki.com/mcp"
10
+ },
11
+ "gitnexus": {
12
+ "type": "stdio",
13
+ "command": "npx",
14
+ "args": ["-y", "gitnexus", "mcp"],
15
+ "env": {}
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,61 @@
1
+ # Hooks
2
+
3
+ Claude Code hooks that extend agent behavior with automated checks, workflow enhancements, and safety guardrails.
4
+
5
+ ## Overview
6
+
7
+ Hooks intercept specific events in the Claude Code lifecycle. Following architecture decisions in v2.0.0+, the hook ecosystem is designed exclusively for Claude Code.
8
+
9
+ *Note: In v2.1.15+, several older hooks (`skill-suggestion.py`, `skill-discovery.py`, `gitnexus-impact-reminder.py`, and `type-safety-enforcement.py`) were removed or superseded by native capabilities, CLI commands, and consolidated quality gates.*
10
+
11
+ ## Project Hooks
12
+
13
+ ### gitnexus-hook.cjs
14
+
15
+ **Purpose**: Enriches tool calls with knowledge graph context via `gitnexus augment`. Now supports Serena tools and uses a deduplication cache for efficiency.
16
+
17
+ **Trigger**: PostToolUse (Grep|Glob|Bash|Serena edit tools)
18
+
19
+ ## Beads Issue Tracking Gates
20
+
21
+ The beads gate hooks integrate the `bd` (beads) issue tracker directly into Claude's workflow, ensuring no code changes happen without an active ticket.
22
+
23
+ **Installation**: Installed with `xtrm install all` or included when `beads`+`dolt` is available.
24
+
25
+ ### Core Gates
26
+ - **`beads-edit-gate.mjs`** (PreToolUse) — Blocks writes/edits without an active issue claim.
27
+ - **`beads-commit-gate.mjs`** (PreToolUse) — Blocks commits with an unresolved session claim.
28
+ - **`beads-stop-gate.mjs`** (Stop) — Blocks session stop while a claim remains open.
29
+ - **`beads-close-memory-prompt.mjs`** (PostToolUse) — Prompts memory handoff after `bd close`.
30
+
31
+ ### Compaction & State Preservation (v2.1.18+)
32
+ - **`beads-pre-compact.mjs`** (PreCompact) — Saves the currently `in_progress` beads state before Claude clears context.
33
+ - **`beads-session-start.mjs`** (SessionStart) — Restores the `in_progress` state when the session restarts after compaction.
34
+
35
+ *Note: As of v2.1.18+, hook blocking messages are quieted and compacted to save tokens.*
36
+
37
+ ## Hook Timeouts
38
+
39
+ Adjust hook execution timeouts in `settings.json` if commands take longer than expected:
40
+
41
+ ```json
42
+ {
43
+ "hooks": {
44
+ "PostToolUse": [{
45
+ "hooks": [{
46
+ "timeout": 5000 // Timeout in milliseconds (5000ms = 5 seconds)
47
+ }]
48
+ }]
49
+ }
50
+ }
51
+ ```
52
+
53
+ ## Creating Custom Hooks
54
+
55
+ To create new project-specific hooks, use the `hook-development` global skill. Follow the canonical structure defined in the `xtrm-tools` core libraries.
56
+
57
+ For debugging orphaned hooks, use `xtrm clean`.
58
+
59
+ ## Pi Extensions Migration
60
+
61
+ Core workflow hooks have been migrated to native Pi Extensions for better performance and integration. See the [Pi Extensions Migration Guide](../docs/pi-extensions-migration.md) for details.
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env node
2
+ // beads-claim-sync — PostToolUse hook
3
+ // bd update --claim → set kv claim
4
+ // bd close → auto-commit staged changes, set closed-this-session kv for memory gate
5
+
6
+ import { spawnSync } from 'node:child_process';
7
+ import { readFileSync, existsSync, writeFileSync, unlinkSync, mkdirSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+ import { resolveSessionId } from './beads-gate-utils.mjs';
10
+ import { logEvent } from './xtrm-logger.mjs';
11
+
12
+ function readInput() {
13
+ try {
14
+ return JSON.parse(readFileSync(0, 'utf-8'));
15
+ } catch {
16
+ return null;
17
+ }
18
+ }
19
+
20
+ function isBeadsProject(cwd) {
21
+ return existsSync(join(cwd, '.beads'));
22
+ }
23
+
24
+ function isShellTool(toolName) {
25
+ return toolName === 'Bash' || toolName === 'bash' || toolName === 'execute_shell_command';
26
+ }
27
+
28
+ function commandSucceeded(payload) {
29
+ const tr = payload?.tool_response ?? payload?.tool_result ?? payload?.result;
30
+ if (!tr || typeof tr !== 'object') return true;
31
+
32
+ if (tr.success === false) return false;
33
+ if (tr.error) return false;
34
+
35
+ const numeric = [tr.exit_code, tr.exitCode, tr.status, tr.returncode].find((v) => Number.isInteger(v));
36
+ if (typeof numeric === 'number' && numeric !== 0) return false;
37
+
38
+ return true;
39
+ }
40
+
41
+ function runGit(args, cwd, timeout = 8000) {
42
+ return spawnSync('git', args, {
43
+ cwd,
44
+ stdio: ['pipe', 'pipe', 'pipe'],
45
+ encoding: 'utf8',
46
+ timeout,
47
+ });
48
+ }
49
+
50
+ function runBd(args, cwd, timeout = 5000) {
51
+ return spawnSync('bd', args, {
52
+ cwd,
53
+ stdio: ['pipe', 'pipe', 'pipe'],
54
+ encoding: 'utf8',
55
+ timeout,
56
+ });
57
+ }
58
+
59
+ function hasGitChanges(cwd) {
60
+ const result = runGit(['status', '--porcelain'], cwd);
61
+ if (result.status !== 0) return false;
62
+ return result.stdout.trim().length > 0;
63
+ }
64
+
65
+ function getCloseReason(cwd, issueId, command) {
66
+ // 1. Parse --reason "..." from the command itself (fastest, no extra call)
67
+ const reasonMatch = command.match(/--reason[=\s]+["']([^"']+)["']/);
68
+ if (reasonMatch) return reasonMatch[1].trim();
69
+
70
+ // 2. Fall back to bd show <id> --json
71
+ const show = runBd(['show', issueId, '--json'], cwd);
72
+ if (show.status === 0 && show.stdout) {
73
+ try {
74
+ const parsed = JSON.parse(show.stdout);
75
+ const reason = parsed?.[0]?.close_reason;
76
+ if (typeof reason === 'string' && reason.trim().length > 0) return reason.trim();
77
+ } catch { /* fall through */ }
78
+ }
79
+
80
+ return `Close ${issueId}`;
81
+ }
82
+
83
+ function stageUntracked(cwd) {
84
+ const result = runGit(['ls-files', '--others', '--exclude-standard'], cwd);
85
+ if (result.status !== 0) return;
86
+ const untracked = result.stdout.trim().split('\n').filter(Boolean);
87
+ if (untracked.length === 0) return;
88
+ runGit(['add', '--', ...untracked], cwd);
89
+ }
90
+
91
+ function autoCommit(cwd, issueId, command) {
92
+ if (!hasGitChanges(cwd)) {
93
+ return { ok: true, message: 'No changes detected — auto-commit skipped.' };
94
+ }
95
+
96
+ stageUntracked(cwd);
97
+
98
+ const reason = getCloseReason(cwd, issueId, command);
99
+ const commitMessage = `${reason} (${issueId})`;
100
+ const result = runGit(['commit', '-am', commitMessage], cwd, 15000);
101
+ if (result.status !== 0) {
102
+ const err = (result.stderr || result.stdout || '').trim();
103
+ return { ok: false, message: `Auto-commit failed: ${err || 'unknown error'}` };
104
+ }
105
+
106
+ return { ok: true, message: `Auto-committed: \`${commitMessage}\`` };
107
+ }
108
+
109
+
110
+ function main() {
111
+ const input = readInput();
112
+ if (!input || input.hook_event_name !== 'PostToolUse') process.exit(0);
113
+ if (!isShellTool(input.tool_name)) process.exit(0);
114
+
115
+ const cwd = input.cwd || process.cwd();
116
+ if (!isBeadsProject(cwd)) process.exit(0);
117
+
118
+ const command = input.tool_input?.command || '';
119
+ const sessionId = resolveSessionId(input);
120
+
121
+ // Auto-claim: bd update <id> --claim (fire regardless of exit code — bd returns 1 for "already in_progress")
122
+ if (/\bbd\s+update\b/.test(command) && /--claim\b/.test(command)) {
123
+ const match = command.match(/\bbd\s+update\s+(\S+)/);
124
+ if (match) {
125
+ const issueId = match[1];
126
+ const result = spawnSync('bd', ['kv', 'set', `claimed:${sessionId}`, issueId], {
127
+ cwd,
128
+ stdio: ['pipe', 'pipe', 'pipe'],
129
+ timeout: 5000,
130
+ });
131
+
132
+ if (result.status !== 0) {
133
+ const err = (result.stderr || result.stdout || '').toString().trim();
134
+ if (err) process.stderr.write(`Beads claim sync warning: ${err}\n`);
135
+ process.exit(0);
136
+ }
137
+
138
+ // Write claim state for statusline
139
+ try {
140
+ const xtrmDir = join(cwd, '.xtrm');
141
+ mkdirSync(xtrmDir, { recursive: true });
142
+ writeFileSync(join(xtrmDir, 'statusline-claim'), issueId);
143
+ } catch { /* non-fatal */ }
144
+
145
+ logEvent({
146
+ cwd,
147
+ runtime: 'claude',
148
+ sessionId,
149
+ layer: 'bd',
150
+ kind: 'bd.claimed',
151
+ outcome: 'allow',
152
+ issueId,
153
+ });
154
+
155
+ process.stdout.write(JSON.stringify({
156
+ additionalContext: `\n✅ **Beads**: Session \`${sessionId}\` claimed issue \`${issueId}\`.`,
157
+ }));
158
+ process.stdout.write('\n');
159
+ process.exit(0);
160
+ }
161
+ }
162
+
163
+ // On bd close: auto-commit staged changes, then mark closed-this-session for memory gate
164
+ if (/\bbd\s+close\b/.test(command) && commandSucceeded(input)) {
165
+ const match = command.match(/\bbd\s+close\s+(\S+)/);
166
+ const closedIssueId = match?.[1];
167
+
168
+ // Auto-commit before marking the gate (no-op if clean)
169
+ const commit = closedIssueId ? autoCommit(cwd, closedIssueId, command) : null;
170
+
171
+ // Clear claim state for statusline
172
+ try { unlinkSync(join(cwd, '.xtrm', 'statusline-claim')); } catch { /* ok if missing */ }
173
+
174
+ // Mark this issue as closed this session (memory gate reads this)
175
+ if (closedIssueId) {
176
+ spawnSync('bd', ['kv', 'set', `closed-this-session:${sessionId}`, closedIssueId], {
177
+ cwd,
178
+ stdio: ['pipe', 'pipe', 'pipe'],
179
+ timeout: 5000,
180
+ });
181
+ }
182
+
183
+ // Log bd lifecycle events
184
+ if (closedIssueId) {
185
+ logEvent({
186
+ cwd,
187
+ runtime: 'claude',
188
+ sessionId,
189
+ layer: 'bd',
190
+ kind: 'bd.closed',
191
+ outcome: 'allow',
192
+ issueId: closedIssueId,
193
+ });
194
+ }
195
+ if (commit) {
196
+ logEvent({
197
+ cwd,
198
+ runtime: 'claude',
199
+ sessionId,
200
+ layer: 'bd',
201
+ kind: 'bd.committed',
202
+ outcome: commit.ok ? 'allow' : 'block',
203
+ issueId: closedIssueId ?? null,
204
+ data: { msg: commit.message },
205
+ extra: { ok: commit.ok },
206
+ });
207
+ }
208
+
209
+ const commitLine = commit
210
+ ? `\n${commit.ok ? '✅' : '⚠️'} **Session Flow**: ${commit.message}`
211
+ : '';
212
+
213
+ process.stdout.write(JSON.stringify({
214
+ additionalContext: `\n🔓 **Beads**: Issue closed.${commitLine}\nEvaluate insights, then acknowledge:\n \`bd remember "<insight>"\` (or note "nothing")\n \`touch .beads/.memory-gate-done\``,
215
+ }));
216
+ process.stdout.write('\n');
217
+ process.exit(0);
218
+ }
219
+
220
+ process.exit(0);
221
+ }
222
+
223
+ main();
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ // beads-commit-gate — Claude Code PreToolUse hook
3
+ // Blocks `git commit` when this session still has an unclosed claim in bd kv.
4
+ // Falls back to global in_progress check when session_id is unavailable.
5
+ // Forces: close issues first, THEN commit.
6
+ // Exit 0: allow | Exit 2: block (stderr shown to Claude)
7
+ //
8
+ // Installed by: xtrm install
9
+
10
+ import {
11
+ readHookInput,
12
+ resolveSessionContext,
13
+ resolveClaimAndWorkState,
14
+ decideCommitGate,
15
+ } from './beads-gate-core.mjs';
16
+ import { withSafeBdContext } from './beads-gate-utils.mjs';
17
+ import { commitBlockMessage } from './beads-gate-messages.mjs';
18
+ import { logEvent } from './xtrm-logger.mjs';
19
+
20
+ const input = readHookInput();
21
+ if (!input) process.exit(0);
22
+
23
+ if ((input.tool_name ?? '') !== 'Bash') process.exit(0);
24
+
25
+ const command = input.tool_input?.command ?? '';
26
+ // Strip quoted strings to avoid matching patterns inside --reason "..." or similar args
27
+ const commandUnquoted = command.replace(/'[^']*'|"[^"]*"/g, '');
28
+
29
+ withSafeBdContext(() => {
30
+ const ctx = resolveSessionContext(input);
31
+ if (!ctx || !ctx.isBeadsProject) process.exit(0);
32
+
33
+ // Only intercept git commit for the claim-gate check
34
+ if (!/\bgit\s+commit\b/.test(commandUnquoted)) process.exit(0);
35
+
36
+ const state = resolveClaimAndWorkState(ctx);
37
+ const decision = decideCommitGate(ctx, state);
38
+
39
+ if (decision.allow) {
40
+ logEvent({
41
+ cwd: ctx.cwd,
42
+ runtime: 'claude',
43
+ sessionId: ctx.sessionId,
44
+ layer: 'gate',
45
+ kind: 'gate.commit.allow',
46
+ outcome: 'allow',
47
+ toolName: 'Bash',
48
+ issueId: state?.claimId ?? null,
49
+ });
50
+ process.exit(0);
51
+ }
52
+
53
+ // Block with structured decision
54
+ const reason = commitBlockMessage(decision.summary, decision.claimed);
55
+ logEvent({
56
+ cwd: ctx.cwd,
57
+ runtime: 'claude',
58
+ sessionId: ctx.sessionId,
59
+ layer: 'gate',
60
+ kind: 'gate.commit.block',
61
+ outcome: 'block',
62
+ toolName: 'Bash',
63
+ issueId: decision.claimed ?? null,
64
+ message: reason,
65
+ extra: { reason_code: decision.reason },
66
+ });
67
+ process.stdout.write(JSON.stringify({ decision: 'block', reason }));
68
+ process.stdout.write('\n');
69
+ process.exit(0);
70
+ });
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ // Claude Code SessionStart hook — restore in_progress beads issues after context compaction.
3
+ // Reads .beads/.last_active (written by beads-compact-save.mjs), reinstates statuses,
4
+ // restores session state file, deletes the marker, and injects a brief agent context message.
5
+ // Exit 0 in all paths (informational only).
6
+
7
+ import { execSync } from 'node:child_process';
8
+ import { readFileSync, existsSync, unlinkSync } from 'node:fs';
9
+ import path from 'node:path';
10
+
11
+ let input;
12
+ try {
13
+ input = JSON.parse(readFileSync(0, 'utf8'));
14
+ } catch {
15
+ process.exit(0);
16
+ }
17
+
18
+ const cwd = input.cwd ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
19
+ const lastActivePath = path.join(cwd, '.beads', '.last_active');
20
+
21
+ if (!existsSync(lastActivePath)) process.exit(0);
22
+
23
+ let ids = [];
24
+
25
+ try {
26
+ const raw = readFileSync(lastActivePath, 'utf8').trim();
27
+ if (raw.startsWith('{')) {
28
+ const parsed = JSON.parse(raw);
29
+ ids = Array.isArray(parsed.ids) ? parsed.ids.filter(Boolean) : [];
30
+ } else {
31
+ // Backward compatibility: legacy newline format
32
+ ids = raw.split('\n').filter(Boolean);
33
+ }
34
+ } catch {
35
+ // If file is malformed, just delete and continue fail-open.
36
+ }
37
+
38
+ // Clean up regardless of whether restore succeeds
39
+ unlinkSync(lastActivePath);
40
+
41
+ let restored = 0;
42
+ for (const id of ids) {
43
+ try {
44
+ execSync(`bd update ${id} --status in_progress`, {
45
+ encoding: 'utf8',
46
+ cwd,
47
+ stdio: ['pipe', 'pipe', 'pipe'],
48
+ timeout: 5000,
49
+ });
50
+ restored++;
51
+ } catch {
52
+ // ignore — issue may no longer exist
53
+ }
54
+ }
55
+
56
+ if (restored > 0) {
57
+ const lines = [`Restored ${restored} in_progress issue${restored === 1 ? '' : 's'} from last session before compaction.`];
58
+
59
+ process.stdout.write(
60
+ JSON.stringify({
61
+ hookSpecificOutput: {
62
+ hookEventName: 'SessionStart',
63
+ additionalSystemPrompt: `${lines.join(' ')} Check \`bd list\` for details.`,
64
+ },
65
+ }) + '\n',
66
+ );
67
+ }
68
+
69
+ process.exit(0);
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ // Claude Code PreCompact hook — save in_progress beads issues before context is compacted.
3
+ // Writes a compact bundle to .beads/.last_active for restore hook.
4
+ // Bundle includes issue IDs and xtrm session state when available.
5
+ // Exit 0 in all paths (informational only).
6
+
7
+ import { execSync } from 'node:child_process';
8
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
9
+ import path from 'node:path';
10
+
11
+ let input;
12
+ try {
13
+ input = JSON.parse(readFileSync(0, 'utf8'));
14
+ } catch {
15
+ process.exit(0);
16
+ }
17
+
18
+ const cwd = input.cwd ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
19
+ const beadsDir = path.join(cwd, '.beads');
20
+
21
+ if (!existsSync(beadsDir)) process.exit(0);
22
+
23
+ let output = '';
24
+ try {
25
+ output = execSync('bd list --status=in_progress', {
26
+ encoding: 'utf8',
27
+ cwd,
28
+ stdio: ['pipe', 'pipe', 'pipe'],
29
+ timeout: 8000,
30
+ }).trim();
31
+ } catch {
32
+ process.exit(0);
33
+ }
34
+
35
+ // Parse issue IDs — lines like "◐ proj-abc123 ● P1 Title"
36
+ const ids = [];
37
+ for (const line of output.split('\n')) {
38
+ const match = line.trim().match(/^[○◐●✓❄]\s+([\w-]+)\s/u);
39
+ if (match) ids.push(match[1]);
40
+ }
41
+
42
+ const bundle = {
43
+ ids,
44
+ savedAt: new Date().toISOString(),
45
+ };
46
+
47
+ if (bundle.ids.length === 0) process.exit(0);
48
+
49
+ writeFileSync(path.join(beadsDir, '.last_active'), JSON.stringify(bundle, null, 2) + '\n', 'utf8');
50
+
51
+ process.exit(0);
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ // beads-edit-gate — Claude Code PreToolUse hook
3
+ // Blocks file edits when this session has not claimed a beads issue via bd kv.
4
+ // Falls back to global in_progress check when session_id is unavailable.
5
+ // Only active in projects with a .beads/ directory.
6
+ // Exit 0: allow | Exit 2: block (stderr shown to Claude)
7
+ //
8
+ // Installed by: xtrm install
9
+
10
+ import {
11
+ readHookInput,
12
+ resolveSessionContext,
13
+ resolveClaimAndWorkState,
14
+ decideEditGate,
15
+ decideWorktreeBoundary,
16
+ } from './beads-gate-core.mjs';
17
+ import { withSafeBdContext, resolveCwd, resolveSessionId } from './beads-gate-utils.mjs';
18
+ import { editBlockMessage, editBlockFallbackMessage } from './beads-gate-messages.mjs';
19
+ import { logEvent } from './xtrm-logger.mjs';
20
+
21
+ const input = readHookInput();
22
+ if (!input) process.exit(0);
23
+
24
+ // Worktree boundary check — independent of beads, fires first
25
+ const _cwd = resolveCwd(input);
26
+ const _boundary = decideWorktreeBoundary(input, _cwd);
27
+ if (!_boundary.allow) {
28
+ const _wbReason = `🚫 Edit outside worktree boundary.\n File: ${_boundary.filePath}\n Allowed: ${_boundary.worktreeRoot}\n\n All edits must stay within the active worktree.`;
29
+ logEvent({
30
+ cwd: _cwd,
31
+ runtime: 'claude',
32
+ sessionId: resolveSessionId(input),
33
+ layer: 'gate',
34
+ kind: 'gate.worktree.block',
35
+ outcome: 'block',
36
+ toolName: input.tool_name,
37
+ message: _wbReason,
38
+ extra: { file: _boundary.filePath, worktree_root: _boundary.worktreeRoot },
39
+ });
40
+ process.stdout.write(JSON.stringify({ decision: 'block', reason: _wbReason }));
41
+ process.stdout.write('\n');
42
+ process.exit(0);
43
+ }
44
+
45
+ withSafeBdContext(() => {
46
+ const ctx = resolveSessionContext(input);
47
+ if (!ctx || !ctx.isBeadsProject) process.exit(0);
48
+
49
+ const state = resolveClaimAndWorkState(ctx);
50
+ const decision = decideEditGate(ctx, state);
51
+
52
+ if (decision.allow) {
53
+ logEvent({
54
+ cwd: ctx.cwd,
55
+ runtime: 'claude',
56
+ sessionId: ctx.sessionId,
57
+ layer: 'gate',
58
+ kind: 'gate.edit.allow',
59
+ outcome: 'allow',
60
+ toolName: input.tool_name,
61
+ issueId: state?.claimId ?? null,
62
+ extra: { file: input.tool_input?.file_path ?? null },
63
+ });
64
+ process.exit(0);
65
+ }
66
+
67
+ // Block with appropriate message
68
+ const reason = decision.reason === 'no_claim_with_work'
69
+ ? editBlockMessage(decision.sessionId)
70
+ : editBlockFallbackMessage();
71
+ logEvent({
72
+ cwd: ctx.cwd,
73
+ runtime: 'claude',
74
+ sessionId: ctx.sessionId,
75
+ layer: 'gate',
76
+ kind: 'gate.edit.block',
77
+ outcome: 'block',
78
+ toolName: input.tool_name,
79
+ message: reason,
80
+ extra: { file: input.tool_input?.file_path ?? null, reason_code: decision.reason },
81
+ });
82
+ process.stdout.write(JSON.stringify({ decision: 'block', reason }));
83
+ process.stdout.write('\n');
84
+ process.exit(0);
85
+ });