xtrm-tools 0.5.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 (333) hide show
  1. package/CHANGELOG.md +504 -0
  2. package/README.md +201 -0
  3. package/cli/dist/index.cjs +57378 -0
  4. package/cli/dist/index.cjs.map +1 -0
  5. package/cli/dist/index.d.cts +2 -0
  6. package/cli/package.json +47 -0
  7. package/config/.env.example +40 -0
  8. package/config/hooks.json +72 -0
  9. package/config/instructions/agents-top.md +30 -0
  10. package/config/instructions/claude-top.md +30 -0
  11. package/config/mcp_servers.json +57 -0
  12. package/config/mcp_servers_optional.json +53 -0
  13. package/config/pi/auth.json.template +14 -0
  14. package/config/pi/extensions/auto-session-name/index.ts +29 -0
  15. package/config/pi/extensions/auto-session-name/package.json +16 -0
  16. package/config/pi/extensions/auto-update/index.ts +71 -0
  17. package/config/pi/extensions/auto-update/package.json +16 -0
  18. package/config/pi/extensions/beads/index.ts +166 -0
  19. package/config/pi/extensions/beads/package.json +16 -0
  20. package/config/pi/extensions/bg-process/index.ts +230 -0
  21. package/config/pi/extensions/bg-process/package.json +16 -0
  22. package/config/pi/extensions/compact-header/index.ts +69 -0
  23. package/config/pi/extensions/compact-header/package.json +16 -0
  24. package/config/pi/extensions/core/adapter.ts +52 -0
  25. package/config/pi/extensions/core/guard-rules.ts +102 -0
  26. package/config/pi/extensions/core/lib.ts +3 -0
  27. package/config/pi/extensions/core/logger.ts +45 -0
  28. package/config/pi/extensions/core/runner.ts +71 -0
  29. package/config/pi/extensions/core/session-state.ts +59 -0
  30. package/config/pi/extensions/custom-footer/index.ts +160 -0
  31. package/config/pi/extensions/custom-footer/package.json +16 -0
  32. package/config/pi/extensions/custom-provider-qwen-cli/index.ts +363 -0
  33. package/config/pi/extensions/custom-provider-qwen-cli/package.json +1 -0
  34. package/config/pi/extensions/git-checkpoint/index.ts +53 -0
  35. package/config/pi/extensions/git-checkpoint/package.json +16 -0
  36. package/config/pi/extensions/minimal-mode/index.ts +201 -0
  37. package/config/pi/extensions/minimal-mode/package.json +16 -0
  38. package/config/pi/extensions/plan-mode/README.md +65 -0
  39. package/config/pi/extensions/plan-mode/index.ts +417 -0
  40. package/config/pi/extensions/plan-mode/package.json +12 -0
  41. package/config/pi/extensions/plan-mode/utils.ts +324 -0
  42. package/config/pi/extensions/quality-gates/index.ts +67 -0
  43. package/config/pi/extensions/quality-gates/package.json +16 -0
  44. package/config/pi/extensions/service-skills/index.ts +108 -0
  45. package/config/pi/extensions/service-skills/package.json +16 -0
  46. package/config/pi/extensions/session-flow/index.ts +131 -0
  47. package/config/pi/extensions/session-flow/package.json +16 -0
  48. package/config/pi/extensions/todo/index.ts +299 -0
  49. package/config/pi/extensions/todo/package.json +16 -0
  50. package/config/pi/extensions/xtrm-loader/index.ts +89 -0
  51. package/config/pi/extensions/xtrm-loader/package.json +16 -0
  52. package/config/pi/install-schema.json +44 -0
  53. package/config/pi/models.json.template +76 -0
  54. package/config/pi/pi-worktrees-settings.json +6 -0
  55. package/config/pi/settings.json.template +16 -0
  56. package/config/settings.json +70 -0
  57. package/hooks/README.md +75 -0
  58. package/hooks/agent_context.py +105 -0
  59. package/hooks/beads-claim-sync.mjs +166 -0
  60. package/hooks/beads-commit-gate.mjs +55 -0
  61. package/hooks/beads-compact-restore.mjs +69 -0
  62. package/hooks/beads-compact-save.mjs +51 -0
  63. package/hooks/beads-edit-gate.mjs +45 -0
  64. package/hooks/beads-gate-core.mjs +215 -0
  65. package/hooks/beads-gate-messages.mjs +87 -0
  66. package/hooks/beads-gate-utils.mjs +185 -0
  67. package/hooks/beads-memory-gate.mjs +61 -0
  68. package/hooks/beads-stop-gate.mjs +32 -0
  69. package/hooks/branch-state.mjs +39 -0
  70. package/hooks/gitnexus/gitnexus-hook.cjs +222 -0
  71. package/hooks/guard-rules.mjs +118 -0
  72. package/hooks/hooks.json +116 -0
  73. package/hooks/main-guard-post-push.mjs +71 -0
  74. package/hooks/main-guard.mjs +119 -0
  75. package/hooks/quality-check.cjs +1286 -0
  76. package/hooks/quality-check.py +345 -0
  77. package/hooks/serena-workflow-reminder.py +74 -0
  78. package/package.json +77 -0
  79. package/project-skills/quality-gates/.claude/hooks/hook-config.json +66 -0
  80. package/project-skills/quality-gates/.claude/hooks/quality-check.cjs +1286 -0
  81. package/project-skills/quality-gates/.claude/hooks/quality-check.py +334 -0
  82. package/project-skills/quality-gates/.claude/settings.json +3 -0
  83. package/project-skills/quality-gates/.claude/skills/using-quality-gates/SKILL.md +254 -0
  84. package/project-skills/quality-gates/README.md +109 -0
  85. package/project-skills/quality-gates/evals/evals.json +181 -0
  86. package/project-skills/quality-gates/workspace/iteration-1/FINAL-EVAL-SUMMARY.md +75 -0
  87. package/project-skills/quality-gates/workspace/iteration-1/edge-case-auto-fix-verification/with_skill/outputs/response.md +59 -0
  88. package/project-skills/quality-gates/workspace/iteration-1/edge-case-mixed-language-project/with_skill/outputs/response.md +60 -0
  89. package/project-skills/quality-gates/workspace/iteration-1/eval-summary.md +105 -0
  90. package/project-skills/quality-gates/workspace/iteration-1/partial-install-python-only/with_skill/outputs/response.md +93 -0
  91. package/project-skills/quality-gates/workspace/iteration-1/python-refactor-request/with_skill/outputs/response.md +104 -0
  92. package/project-skills/quality-gates/workspace/iteration-1/quality-gate-error-fix/with_skill/outputs/response.md +74 -0
  93. package/project-skills/quality-gates/workspace/iteration-1/should-not-trigger-general-chat/with_skill/outputs/response.md +18 -0
  94. package/project-skills/quality-gates/workspace/iteration-1/should-not-trigger-math-question/with_skill/outputs/response.md +18 -0
  95. package/project-skills/quality-gates/workspace/iteration-1/should-not-trigger-unrelated-coding/with_skill/outputs/response.md +56 -0
  96. package/project-skills/quality-gates/workspace/iteration-1/tdd-guard-blocking-confusion/with_skill/outputs/response.md +67 -0
  97. package/project-skills/quality-gates/workspace/iteration-1/typescript-feature-with-tests/with_skill/outputs/response.md +97 -0
  98. package/project-skills/service-skills-set/.claude/git-hooks/doc_reminder.py +67 -0
  99. package/project-skills/service-skills-set/.claude/git-hooks/skill_staleness.py +194 -0
  100. package/project-skills/service-skills-set/.claude/service-registry.json +4 -0
  101. package/project-skills/service-skills-set/.claude/settings.json +37 -0
  102. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/SKILL.md +433 -0
  103. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/references/script_quality_standards.md +425 -0
  104. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/references/service_skill_system_guide.md +278 -0
  105. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/bootstrap.py +308 -0
  106. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/deep_dive.py +304 -0
  107. package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/scaffolder.py +482 -0
  108. package/project-skills/service-skills-set/.claude/skills/scoping-service-skills/SKILL.md +231 -0
  109. package/project-skills/service-skills-set/.claude/skills/scoping-service-skills/scripts/scope.py +74 -0
  110. package/project-skills/service-skills-set/.claude/skills/updating-service-skills/SKILL.md +136 -0
  111. package/project-skills/service-skills-set/.claude/skills/updating-service-skills/scripts/drift_detector.py +222 -0
  112. package/project-skills/service-skills-set/.claude/skills/using-service-skills/SKILL.md +108 -0
  113. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/cataloger.py +74 -0
  114. package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/skill_activator.py +152 -0
  115. package/project-skills/service-skills-set/README.md +93 -0
  116. package/project-skills/service-skills-set/install-service-skills.py +193 -0
  117. package/project-skills/service-skills-set/service-skills-readme.md +236 -0
  118. package/skills/README.txt +31 -0
  119. package/skills/clean-code/SKILL.md +201 -0
  120. package/skills/creating-service-skills/SKILL.md +433 -0
  121. package/skills/creating-service-skills/references/script_quality_standards.md +425 -0
  122. package/skills/creating-service-skills/references/service_skill_system_guide.md +278 -0
  123. package/skills/creating-service-skills/scripts/bootstrap.py +326 -0
  124. package/skills/creating-service-skills/scripts/deep_dive.py +304 -0
  125. package/skills/creating-service-skills/scripts/scaffolder.py +482 -0
  126. package/skills/delegating/SKILL.md +196 -0
  127. package/skills/delegating/config.yaml +210 -0
  128. package/skills/delegating/references/orchestration-protocols.md +41 -0
  129. package/skills/docker-expert/SKILL.md +409 -0
  130. package/skills/documenting/CHANGELOG.md +23 -0
  131. package/skills/documenting/README.md +148 -0
  132. package/skills/documenting/SKILL.md +113 -0
  133. package/skills/documenting/examples/example_pattern.md +70 -0
  134. package/skills/documenting/examples/example_reference.md +70 -0
  135. package/skills/documenting/examples/example_ssot_analytics.md +64 -0
  136. package/skills/documenting/examples/example_workflow.md +141 -0
  137. package/skills/documenting/references/changelog-format.md +97 -0
  138. package/skills/documenting/references/metadata-schema.md +136 -0
  139. package/skills/documenting/references/taxonomy.md +81 -0
  140. package/skills/documenting/references/versioning-rules.md +78 -0
  141. package/skills/documenting/scripts/bump_version.sh +60 -0
  142. package/skills/documenting/scripts/changelog/__init__.py +0 -0
  143. package/skills/documenting/scripts/changelog/add_entry.py +216 -0
  144. package/skills/documenting/scripts/changelog/bump_release.py +117 -0
  145. package/skills/documenting/scripts/changelog/init_changelog.py +54 -0
  146. package/skills/documenting/scripts/changelog/validate_changelog.py +128 -0
  147. package/skills/documenting/scripts/drift_detector.py +266 -0
  148. package/skills/documenting/scripts/generate_template.py +311 -0
  149. package/skills/documenting/scripts/list_by_category.sh +84 -0
  150. package/skills/documenting/scripts/orchestrator.py +255 -0
  151. package/skills/documenting/scripts/validate_metadata.py +242 -0
  152. package/skills/documenting/templates/CHANGELOG.md.template +13 -0
  153. package/skills/find-skills/SKILL.md +133 -0
  154. package/skills/gitnexus-debugging/SKILL.md +85 -0
  155. package/skills/gitnexus-exploring/SKILL.md +75 -0
  156. package/skills/gitnexus-impact-analysis/SKILL.md +94 -0
  157. package/skills/gitnexus-refactoring/SKILL.md +113 -0
  158. package/skills/hook-development/SKILL.md +797 -0
  159. package/skills/hook-development/examples/load-context.sh +55 -0
  160. package/skills/hook-development/examples/quality-check.js +1168 -0
  161. package/skills/hook-development/examples/validate-bash.sh +43 -0
  162. package/skills/hook-development/examples/validate-write.sh +38 -0
  163. package/skills/hook-development/references/advanced.md +527 -0
  164. package/skills/hook-development/references/migration.md +369 -0
  165. package/skills/hook-development/references/patterns.md +412 -0
  166. package/skills/hook-development/scripts/README.md +164 -0
  167. package/skills/hook-development/scripts/hook-linter.sh +153 -0
  168. package/skills/hook-development/scripts/test-hook.sh +252 -0
  169. package/skills/hook-development/scripts/validate-hook-schema.sh +159 -0
  170. package/skills/obsidian-cli/SKILL.md +106 -0
  171. package/skills/orchestrating-agents/SKILL.md +135 -0
  172. package/skills/orchestrating-agents/config.yaml +45 -0
  173. package/skills/orchestrating-agents/references/agent-context-integration.md +37 -0
  174. package/skills/orchestrating-agents/references/examples.md +45 -0
  175. package/skills/orchestrating-agents/references/handover-protocol.md +31 -0
  176. package/skills/orchestrating-agents/references/workflows.md +42 -0
  177. package/skills/orchestrating-agents/scripts/detect_neighbors.py +23 -0
  178. package/skills/prompt-improving/README.md +162 -0
  179. package/skills/prompt-improving/SKILL.md +74 -0
  180. package/skills/prompt-improving/references/analysis_commands.md +24 -0
  181. package/skills/prompt-improving/references/chain_of_thought.md +24 -0
  182. package/skills/prompt-improving/references/mcp_definitions.md +20 -0
  183. package/skills/prompt-improving/references/multishot.md +23 -0
  184. package/skills/prompt-improving/references/xml_core.md +60 -0
  185. package/skills/python-testing/SKILL.md +815 -0
  186. package/skills/scoping-service-skills/SKILL.md +231 -0
  187. package/skills/scoping-service-skills/scripts/scope.py +74 -0
  188. package/skills/senior-backend/SKILL.md +209 -0
  189. package/skills/senior-backend/references/api_design_patterns.md +103 -0
  190. package/skills/senior-backend/references/backend_security_practices.md +103 -0
  191. package/skills/senior-backend/references/database_optimization_guide.md +103 -0
  192. package/skills/senior-backend/scripts/api_load_tester.py +114 -0
  193. package/skills/senior-backend/scripts/api_scaffolder.py +114 -0
  194. package/skills/senior-backend/scripts/database_migration_tool.py +114 -0
  195. package/skills/senior-data-scientist/SKILL.md +226 -0
  196. package/skills/senior-data-scientist/references/experiment_design_frameworks.md +80 -0
  197. package/skills/senior-data-scientist/references/feature_engineering_patterns.md +80 -0
  198. package/skills/senior-data-scientist/references/statistical_methods_advanced.md +80 -0
  199. package/skills/senior-data-scientist/scripts/experiment_designer.py +100 -0
  200. package/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py +100 -0
  201. package/skills/senior-data-scientist/scripts/model_evaluation_suite.py +100 -0
  202. package/skills/senior-devops/SKILL.md +209 -0
  203. package/skills/senior-devops/references/cicd_pipeline_guide.md +103 -0
  204. package/skills/senior-devops/references/deployment_strategies.md +103 -0
  205. package/skills/senior-devops/references/infrastructure_as_code.md +103 -0
  206. package/skills/senior-devops/scripts/deployment_manager.py +114 -0
  207. package/skills/senior-devops/scripts/pipeline_generator.py +114 -0
  208. package/skills/senior-devops/scripts/terraform_scaffolder.py +114 -0
  209. package/skills/senior-security/SKILL.md +209 -0
  210. package/skills/senior-security/references/cryptography_implementation.md +103 -0
  211. package/skills/senior-security/references/penetration_testing_guide.md +103 -0
  212. package/skills/senior-security/references/security_architecture_patterns.md +103 -0
  213. package/skills/senior-security/scripts/pentest_automator.py +114 -0
  214. package/skills/senior-security/scripts/security_auditor.py +114 -0
  215. package/skills/senior-security/scripts/threat_modeler.py +114 -0
  216. package/skills/skill-creator/LICENSE.txt +202 -0
  217. package/skills/skill-creator/SKILL.md +479 -0
  218. package/skills/skill-creator/agents/analyzer.md +274 -0
  219. package/skills/skill-creator/agents/comparator.md +202 -0
  220. package/skills/skill-creator/agents/grader.md +223 -0
  221. package/skills/skill-creator/assets/eval_review.html +146 -0
  222. package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  223. package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  224. package/skills/skill-creator/references/schemas.md +430 -0
  225. package/skills/skill-creator/scripts/__init__.py +0 -0
  226. package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  227. package/skills/skill-creator/scripts/generate_report.py +326 -0
  228. package/skills/skill-creator/scripts/improve_description.py +248 -0
  229. package/skills/skill-creator/scripts/package_skill.py +136 -0
  230. package/skills/skill-creator/scripts/quick_validate.py +103 -0
  231. package/skills/skill-creator/scripts/run_eval.py +310 -0
  232. package/skills/skill-creator/scripts/run_loop.py +332 -0
  233. package/skills/skill-creator/scripts/utils.py +47 -0
  234. package/skills/sync-docs/SKILL.md +132 -0
  235. package/skills/sync-docs/evals/evals.json +89 -0
  236. package/skills/sync-docs/references/doc-structure.md +99 -0
  237. package/skills/sync-docs/references/schema.md +103 -0
  238. package/skills/sync-docs/scripts/changelog/add_entry.py +216 -0
  239. package/skills/sync-docs/scripts/context_gatherer.py +240 -0
  240. package/skills/sync-docs/scripts/doc_structure_analyzer.py +495 -0
  241. package/skills/sync-docs/scripts/drift_detector.py +327 -0
  242. package/skills/sync-docs/scripts/validate_doc.py +365 -0
  243. package/skills/sync-docs/scripts/validate_metadata.py +185 -0
  244. package/skills/sync-docs-workspace/iteration-1/benchmark.json +293 -0
  245. package/skills/sync-docs-workspace/iteration-1/benchmark.md +13 -0
  246. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/eval_metadata.json +27 -0
  247. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/outputs/result.md +210 -0
  248. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/grading.json +28 -0
  249. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/timing.json +1 -0
  250. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/outputs/result.md +101 -0
  251. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/grading.json +28 -0
  252. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/timing.json +5 -0
  253. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/timing.json +5 -0
  254. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/eval_metadata.json +27 -0
  255. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/outputs/result.md +198 -0
  256. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/grading.json +28 -0
  257. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/timing.json +1 -0
  258. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/outputs/result.md +94 -0
  259. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/grading.json +28 -0
  260. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/timing.json +1 -0
  261. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/eval_metadata.json +27 -0
  262. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/outputs/result.md +237 -0
  263. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/grading.json +28 -0
  264. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
  265. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/outputs/result.md +134 -0
  266. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/grading.json +28 -0
  267. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/timing.json +1 -0
  268. package/skills/sync-docs-workspace/iteration-2/benchmark.json +297 -0
  269. package/skills/sync-docs-workspace/iteration-2/benchmark.md +13 -0
  270. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/eval_metadata.json +27 -0
  271. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/outputs/result.md +137 -0
  272. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/grading.json +92 -0
  273. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/timing.json +1 -0
  274. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/outputs/result.md +134 -0
  275. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/grading.json +86 -0
  276. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/timing.json +1 -0
  277. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/eval_metadata.json +27 -0
  278. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/outputs/result.md +193 -0
  279. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/grading.json +72 -0
  280. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/timing.json +1 -0
  281. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/outputs/result.md +211 -0
  282. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/grading.json +91 -0
  283. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/timing.json +5 -0
  284. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/eval_metadata.json +27 -0
  285. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/outputs/result.md +182 -0
  286. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
  287. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
  288. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/outputs/result.md +222 -0
  289. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/grading.json +88 -0
  290. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
  291. package/skills/sync-docs-workspace/iteration-3/benchmark.json +298 -0
  292. package/skills/sync-docs-workspace/iteration-3/benchmark.md +13 -0
  293. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/eval_metadata.json +27 -0
  294. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/outputs/result.md +125 -0
  295. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/grading.json +97 -0
  296. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/timing.json +5 -0
  297. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/outputs/result.md +144 -0
  298. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/grading.json +78 -0
  299. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/timing.json +5 -0
  300. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/eval_metadata.json +27 -0
  301. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/outputs/result.md +104 -0
  302. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/grading.json +91 -0
  303. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/timing.json +5 -0
  304. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/outputs/result.md +79 -0
  305. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/grading.json +82 -0
  306. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/timing.json +5 -0
  307. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/eval_metadata.json +27 -0
  308. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase1_context.json +302 -0
  309. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase2_drift.txt +33 -0
  310. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase3_analysis.json +114 -0
  311. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase4_fix.txt +118 -0
  312. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase5_validate.txt +38 -0
  313. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/result.md +158 -0
  314. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
  315. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/timing.json +5 -0
  316. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/outputs/result.md +71 -0
  317. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/grading.json +90 -0
  318. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
  319. package/skills/test-planning/SKILL.md +208 -0
  320. package/skills/test-planning/evals/evals.json +23 -0
  321. package/skills/updating-service-skills/SKILL.md +136 -0
  322. package/skills/updating-service-skills/scripts/drift_detector.py +222 -0
  323. package/skills/using-TDD/SKILL.md +410 -0
  324. package/skills/using-quality-gates/SKILL.md +254 -0
  325. package/skills/using-serena-lsp/README.md +8 -0
  326. package/skills/using-serena-lsp/REFERENCE.md +194 -0
  327. package/skills/using-serena-lsp/SKILL.md +82 -0
  328. package/skills/using-service-skills/SKILL.md +108 -0
  329. package/skills/using-service-skills/scripts/cataloger.py +74 -0
  330. package/skills/using-service-skills/scripts/skill_activator.py +152 -0
  331. package/skills/using-service-skills/scripts/test_skill_activator.py +58 -0
  332. package/skills/using-xtrm/SKILL.md +245 -0
  333. package/skills/xt-end/SKILL.md +128 -0
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "xtrm-cli",
3
+ "version": "0.5.0",
4
+ "description": "Claude Code tools installer (skills, hooks, MCP servers)",
5
+ "main": "./dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "xtrm": "dist/index.cjs",
9
+ "xt": "dist/index.cjs"
10
+ },
11
+ "scripts": {
12
+ "build": "tsup",
13
+ "dev": "tsx src/index.ts",
14
+ "typecheck": "tsc --noEmit",
15
+ "test": "vitest run",
16
+ "start": "node dist/index.cjs"
17
+ },
18
+ "dependencies": {
19
+ "boxen": "^8.0.1",
20
+ "cli-table3": "^0.6.5",
21
+ "commander": "^14.0.3",
22
+ "comment-json": "^4.2.3",
23
+ "conf": "^12.0.0",
24
+ "dotenv": "^16.4.5",
25
+ "fs-extra": "^11.2.0",
26
+ "kleur": "^4.1.5",
27
+ "listr2": "^10.1.1",
28
+ "minimist": "^1.2.8",
29
+ "ora": "^9.3.0",
30
+ "project": "^0.1.6",
31
+ "prompts": "^2.4.2",
32
+ "tdd-guard": "^1.1.0",
33
+ "zod": "^4.3.6"
34
+ },
35
+ "devDependencies": {
36
+ "@types/fs-extra": "^11.0.4",
37
+ "@types/node": "^25.3.0",
38
+ "tdd-guard-vitest": "^0.1.6",
39
+ "tsup": "^8.5.1",
40
+ "tsx": "^4.21.0",
41
+ "typescript": "^5.9.3",
42
+ "vitest": "^4.0.18"
43
+ },
44
+ "engines": {
45
+ "node": ">=20.0.0"
46
+ }
47
+ }
@@ -0,0 +1,40 @@
1
+ # MCP Servers Environment Variables
2
+ #
3
+ # IMPORTANT: DO NOT edit this file directly!
4
+ # Copy your environment variables to: ~/.config/jaggers-agent-tools/.env
5
+ #
6
+ # The CLI will automatically create and manage this file during sync.
7
+ #
8
+ # To get started:
9
+ # 1. Run the sync command: npx ./cli
10
+ # 2. The CLI will create ~/.config/jaggers-agent-tools/.env if missing
11
+ # 3. Edit that file and add your API keys
12
+ # 4. Re-run sync to apply the changes
13
+
14
+ # =============================================================================
15
+ # MCP: Context7 (Documentation Lookup)
16
+ # =============================================================================
17
+ # Get your API key from: https://context7.com/
18
+ # Required for context7 MCP server to function
19
+ CONTEXT7_API_KEY=ctx7sk-your-api-key-here
20
+
21
+ # =============================================================================
22
+ # MCP: Serena (Code Analysis)
23
+ # =============================================================================
24
+ # Optional: Override auto-detected project name
25
+ # If not set, Serena will auto-detect from current working directory
26
+ # SERENA_PROJECT_NAME=my-project
27
+
28
+ # =============================================================================
29
+ # MCP: Omni Search Engine (Optional)
30
+ # =============================================================================
31
+ # No environment variables required
32
+ # Service must be running locally on http://127.0.0.1:8765/sse
33
+ # See: https://github.com/Jaggerxtrm/omni-search-engine
34
+
35
+ # =============================================================================
36
+ # MCP: unitAI (Optional)
37
+ # =============================================================================
38
+ # No environment variables required
39
+ # Requires Node.js with npx available
40
+ # See: https://github.com/Jaggerxtrm/unitAI
@@ -0,0 +1,72 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "script": "beads-compact-restore.mjs",
6
+ "timeout": 5000
7
+ },
8
+ {
9
+ "script": "serena-workflow-reminder.py"
10
+ }
11
+ ],
12
+ "UserPromptSubmit": [
13
+ {
14
+ "script": "branch-state.mjs",
15
+ "timeout": 3000
16
+ }
17
+ ],
18
+ "PreToolUse": [
19
+ {
20
+ "matcher": "Edit|Write|MultiEdit|NotebookEdit|mcp__serena__rename_symbol|mcp__serena__replace_symbol_body|mcp__serena__insert_after_symbol|mcp__serena__insert_before_symbol",
21
+ "script": "beads-edit-gate.mjs",
22
+ "timeout": 5000
23
+ },
24
+ {
25
+ "matcher": "Bash",
26
+ "script": "beads-commit-gate.mjs",
27
+ "timeout": 5000
28
+ }
29
+ ],
30
+ "PostToolUse": [
31
+ {
32
+ "matcher": "Bash|execute_shell_command|bash",
33
+ "script": "beads-claim-sync.mjs",
34
+ "timeout": 5000
35
+ },
36
+ {
37
+ "matcher": "Write|Edit|MultiEdit|mcp__serena__rename_symbol|mcp__serena__replace_symbol_body|mcp__serena__insert_after_symbol|mcp__serena__insert_before_symbol",
38
+ "script": "quality-check.cjs",
39
+ "timeout": 30000
40
+ },
41
+ {
42
+ "matcher": "Write|Edit|MultiEdit|mcp__serena__rename_symbol|mcp__serena__replace_symbol_body|mcp__serena__insert_after_symbol|mcp__serena__insert_before_symbol",
43
+ "script": "quality-check.py",
44
+ "timeout": 30000
45
+ },
46
+ {
47
+ "matcher": "Bash|mcp__serena__find_symbol|mcp__serena__get_symbols_overview|mcp__serena__search_for_pattern|mcp__serena__find_referencing_symbols|mcp__serena__replace_symbol_body|mcp__serena__insert_after_symbol|mcp__serena__insert_before_symbol|mcp__serena__rename_symbol",
48
+ "script": "gitnexus/gitnexus-hook.cjs",
49
+ "timeout": 10000
50
+ }
51
+ ],
52
+ "Stop": [
53
+ {
54
+ "script": "beads-stop-gate.mjs",
55
+ "timeout": 5000
56
+ },
57
+ {
58
+ "script": "beads-memory-gate.mjs",
59
+ "timeout": 8000
60
+ }
61
+ ],
62
+ "PreCompact": [
63
+ {
64
+ "script": "beads-compact-save.mjs",
65
+ "timeout": 5000
66
+ }
67
+ ]
68
+ },
69
+ "statusLine": {
70
+ "script": "statusline-starship.sh"
71
+ }
72
+ }
@@ -0,0 +1,30 @@
1
+ # XTRM Agent Workflow (Short)
2
+
3
+ This file is an **agent operating manual** (not a project overview).
4
+
5
+ 1. **Start with scope**
6
+ - Clarify task intent if ambiguous.
7
+ - Prefer semantic discovery (Serena + GitNexus) over broad grep-first exploration.
8
+
9
+ 2. **Track work in `bd`**
10
+ - Use `bd ready --json` / `bd update <id> --claim --json` before edits.
11
+ - Create discovered follow-ups with `--deps discovered-from:<id>`.
12
+
13
+ 3. **Branch per issue (strict)**
14
+ - Create a **new branch for each issue** from latest `main`.
15
+ - Do **not** continue new work on a previously used branch.
16
+ - Branch format: `feature/<issue-id>-<short-description>` (or `fix/...`, `chore/...`).
17
+
18
+ 4. **Edit safely**
19
+ - Use Serena symbol tools for code changes when possible.
20
+ - Run GitNexus impact checks before symbol changes and detect-changes before commit.
21
+
22
+ 5. **PR merge + return to main**
23
+ - Always merge via PR (squash merge preferred).
24
+ - After merge: switch to `main` and sync (`git reset --hard origin/main`).
25
+ - Delete merged branch locally and remotely (`git branch -d <branch>` and `git push origin --delete <branch>`).
26
+
27
+ 6. **Before finishing**
28
+ - Run relevant tests/linters.
29
+ - Close/update bead state.
30
+ - Ensure changes are committed and pushed.
@@ -0,0 +1,30 @@
1
+ # XTRM Agent Workflow (Short)
2
+
3
+ This file is an **agent operating manual** (not a project overview).
4
+
5
+ 1. **Start with scope**
6
+ - Clarify task intent if ambiguous.
7
+ - Prefer semantic discovery (Serena + GitNexus) over broad grep-first exploration.
8
+
9
+ 2. **Track work in `bd`**
10
+ - Use `bd ready --json` / `bd update <id> --claim --json` before edits.
11
+ - Create discovered follow-ups with `--deps discovered-from:<id>`.
12
+
13
+ 3. **Branch per issue (strict)**
14
+ - Create a **new branch for each issue** from latest `main`.
15
+ - Do **not** continue new work on a previously used branch.
16
+ - Branch format: `feature/<issue-id>-<short-description>` (or `fix/...`, `chore/...`).
17
+
18
+ 4. **Edit safely**
19
+ - Use Serena symbol tools for code changes when possible.
20
+ - Run GitNexus impact checks before symbol changes and detect-changes before commit.
21
+
22
+ 5. **PR merge + return to main**
23
+ - Always merge via PR (squash merge preferred).
24
+ - After merge: switch to `main` and sync (`git reset --hard origin/main`).
25
+ - Delete merged branch locally and remotely (`git branch -d <branch>` and `git push origin --delete <branch>`).
26
+
27
+ 6. **Before finishing**
28
+ - Run relevant tests/linters.
29
+ - Close/update bead state.
30
+ - Ensure changes are committed and pushed.
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "../vsync_repo/schemas/mcp_servers.schema.json",
3
+ "$metadata": {
4
+ "description": "Core MCP servers - installed by default for all agents",
5
+ "agents": ["claude-code", "gemini", "qwen", "antigravity"],
6
+ "version": "2.0.0"
7
+ },
8
+ "mcpServers": {
9
+ "serena": {
10
+ "type": "stdio",
11
+ "command": "uvx",
12
+ "args": [
13
+ "--from",
14
+ "git+https://github.com/oraios/serena",
15
+ "serena",
16
+ "start-mcp-server",
17
+ "--context",
18
+ "ide-assistant"
19
+ ],
20
+ "env": {},
21
+ "_notes": {
22
+ "project": "Auto-detected from current working directory during usage",
23
+ "prerequisite": "Requires uvx (uv package manager)"
24
+ }
25
+ },
26
+ "context7": {
27
+ "type": "http",
28
+ "url": "https://mcp.context7.com/mcp",
29
+ "headers": {
30
+ "CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}"
31
+ },
32
+ "_notes": {
33
+ "auth": "Requires API key - user will be prompted during sync",
34
+ "env_file": "Store key in .env or ~/.jaggers/.env"
35
+ }
36
+ },
37
+ "github-grep": {
38
+ "type": "http",
39
+ "url": "https://mcp.grep.app"
40
+ },
41
+ "deepwiki": {
42
+ "type": "http",
43
+ "url": "https://mcp.deepwiki.com/mcp"
44
+ },
45
+ "gitnexus": {
46
+ "type": "stdio",
47
+ "command": "npx",
48
+ "args": ["-y", "gitnexus", "mcp"],
49
+ "env": {},
50
+ "_notes": {
51
+ "description": "Code intelligence MCP - provides graph queries for impact analysis, execution flows, symbol context",
52
+ "prerequisite": "Run 'gitnexus analyze' in the project first to build the index",
53
+ "auto_index": "xtrm project init runs gitnexus analyze automatically"
54
+ }
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "$schema": "../vsync_repo/schemas/mcp_servers.schema.json",
3
+ "$metadata": {
4
+ "description": "Optional MCP servers - user chooses during sync",
5
+ "agents": [
6
+ "claude-code",
7
+ "gemini",
8
+ "qwen",
9
+ "antigravity"
10
+ ],
11
+ "version": "2.0.0"
12
+ },
13
+ "mcpServers": {
14
+ "unitAI": {
15
+ "type": "stdio",
16
+ "command": "npx",
17
+ "args": [
18
+ "-y",
19
+ "@jaggerxtrm/unitai"
20
+ ],
21
+ "env": {},
22
+ "_notes": {
23
+ "description": "Multi-agent workflow orchestration system",
24
+ "repository": "https://github.com/Jaggerxtrm/unitAI",
25
+ "prerequisite": "Requires npx (Node.js)"
26
+ }
27
+ },
28
+ "omni-search-engine": {
29
+ "type": "sse",
30
+ "url": "http://127.0.0.1:8765/sse",
31
+ "env": {},
32
+ "_notes": {
33
+ "description": "Local search engine with SSE transport",
34
+ "repository": "https://github.com/Jaggerxtrm/omni-search-engine",
35
+ "prerequisite": "Requires running omni-search-engine service on port 8765"
36
+ }
37
+ },
38
+ "gitnexus": {
39
+ "type": "stdio",
40
+ "command": "gitnexus",
41
+ "args": [
42
+ "mcp"
43
+ ],
44
+ "env": {},
45
+ "_notes": {
46
+ "description": "Knowledge graph over your codebase \u2014 call chains, blast radius, execution flows, semantic search",
47
+ "prerequisite": "Requires npm install -g gitnexus",
48
+ "install_cmd": "npm install -g gitnexus",
49
+ "post_install_message": "\u26a1 GitNexus must be indexed per project!\n Run inside each project you want to use it with:\n\n npx gitnexus analyze\n"
50
+ }
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "zai": {
3
+ "type": "api_key",
4
+ "key": "{{ZAI_API_KEY}}"
5
+ },
6
+ "dashscope": {
7
+ "type": "api_key",
8
+ "key": "{{DASHSCOPE_API_KEY}}"
9
+ },
10
+ "anthropic": {},
11
+ "google-gemini-cli": {},
12
+ "qwen-cli": {},
13
+ "google-antigravity": {}
14
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * oh-pi Auto Session Name Extension
3
+ *
4
+ * Automatically names sessions based on the first user message.
5
+ */
6
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
7
+
8
+ export default function (pi: ExtensionAPI) {
9
+ let named = false;
10
+
11
+ pi.on("session_start", async (_event, ctx) => {
12
+ named = !!pi.getSessionName();
13
+ });
14
+
15
+ pi.on("agent_end", async (event) => {
16
+ if (named) return;
17
+ const userMsg = event.messages.find((m) => m.role === "user");
18
+ if (!userMsg) return;
19
+ const text = typeof userMsg.content === "string"
20
+ ? userMsg.content
21
+ : userMsg.content.filter((b) => b.type === "text").map((b) => (b as { text: string }).text).join(" ");
22
+ if (!text) return;
23
+ const name = text.slice(0, 60).replace(/\n/g, " ").trim();
24
+ if (name) {
25
+ pi.setSessionName(name);
26
+ named = true;
27
+ }
28
+ });
29
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@xtrm/pi-auto-session-name",
3
+ "version": "1.0.0",
4
+ "description": "xtrm Pi extension: auto-session-name",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./index.ts"
8
+ },
9
+ "keywords": [
10
+ "pi",
11
+ "extension",
12
+ "xtrm"
13
+ ],
14
+ "author": "xtrm",
15
+ "license": "MIT"
16
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * oh-pi Auto Update — check for new oh-pi version on session start
3
+ */
4
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
5
+ import { execSync } from "node:child_process";
6
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { homedir } from "node:os";
9
+
10
+ const CHECK_INTERVAL = 24 * 60 * 60 * 1000; // 24h
11
+ const STAMP_FILE = join(homedir(), ".pi", "agent", ".update-check");
12
+
13
+ function readStamp(): number {
14
+ try { return Number(readFileSync(STAMP_FILE, "utf8").trim()) || 0; } catch { return 0; }
15
+ }
16
+
17
+ function writeStamp() {
18
+ try { writeFileSync(STAMP_FILE, String(Date.now())); } catch {}
19
+ }
20
+
21
+ function getLatestVersion(): string | null {
22
+ try {
23
+ return execSync("npm view oh-pi version", { encoding: "utf8", timeout: 8000 }).trim();
24
+ } catch { return null; }
25
+ }
26
+
27
+ function getCurrentVersion(): string | null {
28
+ // Read from the installed package.json
29
+ try {
30
+ const pkgPath = join(__dirname, "..", "..", "package.json");
31
+ if (existsSync(pkgPath)) {
32
+ return JSON.parse(readFileSync(pkgPath, "utf8")).version;
33
+ }
34
+ } catch {}
35
+ // Fallback: npm list
36
+ try {
37
+ const out = JSON.parse(execSync("npm list -g oh-pi --json --depth=0", { encoding: "utf8", timeout: 8000 }));
38
+ return out.dependencies?.["oh-pi"]?.version ?? null;
39
+ } catch { return null; }
40
+ }
41
+
42
+ export function isNewer(latest: string, current: string): boolean {
43
+ const a = latest.split(".").map(Number);
44
+ const b = current.split(".").map(Number);
45
+ for (let i = 0; i < 3; i++) {
46
+ if ((a[i] ?? 0) > (b[i] ?? 0)) return true;
47
+ if ((a[i] ?? 0) < (b[i] ?? 0)) return false;
48
+ }
49
+ return false;
50
+ }
51
+
52
+ export default function (pi: ExtensionAPI) {
53
+ pi.on("session_start", async (_event, ctx) => {
54
+ // Non-blocking: run check in background
55
+ setTimeout(async () => {
56
+ try {
57
+ if (Date.now() - readStamp() < CHECK_INTERVAL) return;
58
+ writeStamp();
59
+
60
+ const current = getCurrentVersion();
61
+ const latest = getLatestVersion();
62
+ if (!current || !latest || !isNewer(latest, current)) return;
63
+
64
+ const msg = `oh-pi ${latest} available (current: ${current}). Run: npx oh-pi@latest`;
65
+ if (ctx.hasUI) {
66
+ ctx.ui.toast?.(msg) ?? console.log(`\nšŸ’” ${msg}\n`);
67
+ }
68
+ } catch {}
69
+ }, 2000);
70
+ });
71
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@xtrm/pi-auto-update",
3
+ "version": "1.0.0",
4
+ "description": "xtrm Pi extension: auto-update",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./index.ts"
8
+ },
9
+ "keywords": [
10
+ "pi",
11
+ "extension",
12
+ "xtrm"
13
+ ],
14
+ "author": "xtrm",
15
+ "license": "MIT"
16
+ }
@@ -0,0 +1,166 @@
1
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
+ import { isToolCallEventType, isBashToolResult } from "@mariozechner/pi-coding-agent";
3
+ import { SubprocessRunner, EventAdapter, Logger } from "../core/lib";
4
+
5
+ const logger = new Logger({ namespace: "beads" });
6
+
7
+ export default function (pi: ExtensionAPI) {
8
+ const getCwd = (ctx: any) => ctx.cwd || process.cwd();
9
+
10
+ let cachedSessionId: string | null = null;
11
+ let memoryGateFired = false;
12
+
13
+ // Resolve a stable session ID across event types.
14
+ const getSessionId = (ctx: any): string => {
15
+ const fromManager = ctx?.sessionManager?.getSessionId?.();
16
+ const fromContext = ctx?.sessionId ?? ctx?.session_id;
17
+ const resolved = fromManager || fromContext || cachedSessionId || process.pid.toString();
18
+ if (resolved && !cachedSessionId) cachedSessionId = resolved;
19
+ return resolved;
20
+ };
21
+
22
+ const getSessionClaim = async (sessionId: string, cwd: string): Promise<string | null> => {
23
+ const result = await SubprocessRunner.run("bd", ["kv", "get", `claimed:${sessionId}`], { cwd });
24
+ if (result.code === 0) return result.stdout.trim();
25
+ return null;
26
+ };
27
+
28
+ const hasTrackableWork = async (cwd: string): Promise<boolean> => {
29
+ const result = await SubprocessRunner.run("bd", ["list"], { cwd });
30
+ if (result.code === 0) {
31
+ const counts = EventAdapter.parseBdCounts(result.stdout);
32
+ if (counts) return (counts.open + counts.inProgress) > 0;
33
+ }
34
+ return false;
35
+ };
36
+
37
+ const hasInProgressWork = async (cwd: string): Promise<boolean> => {
38
+ const result = await SubprocessRunner.run("bd", ["list"], { cwd });
39
+ if (result.code === 0 && result.stdout.includes("Total:")) {
40
+ const m = result.stdout.match(/Total:\s*\d+\s+issues?\s*\((\d+)\s+open,\s*(\d+)\s+in progress\)/);
41
+ if (m) return parseInt(m[2], 10) > 0;
42
+ }
43
+ return false;
44
+ };
45
+
46
+ pi.on("session_start", async (_event, ctx) => {
47
+ cachedSessionId = ctx?.sessionManager?.getSessionId?.() ?? ctx?.sessionId ?? ctx?.session_id ?? cachedSessionId;
48
+ return undefined;
49
+ });
50
+
51
+ pi.on("tool_call", async (event, ctx) => {
52
+ const cwd = getCwd(ctx);
53
+ if (!EventAdapter.isBeadsProject(cwd)) return undefined;
54
+ const sessionId = getSessionId(ctx);
55
+
56
+ if (EventAdapter.isMutatingFileTool(event)) {
57
+ const claim = await getSessionClaim(sessionId, cwd);
58
+ if (!claim) {
59
+ const hasWork = await hasTrackableWork(cwd);
60
+ if (hasWork) {
61
+ if (ctx.hasUI) {
62
+ ctx.ui.notify("Beads: Edit blocked. Claim an issue first.", "warning");
63
+ }
64
+ return {
65
+ block: true,
66
+ reason: `No active claim for session ${sessionId}.\n bd update <id> --claim\n`,
67
+ };
68
+ }
69
+ }
70
+ }
71
+
72
+ if (isToolCallEventType("bash", event)) {
73
+ const command = event.input.command;
74
+ if (command && /\bgit\s+commit\b/.test(command)) {
75
+ const claim = await getSessionClaim(sessionId, cwd);
76
+ if (claim) {
77
+ const inProgress = await hasInProgressWork(cwd);
78
+ if (inProgress) {
79
+ return {
80
+ block: true,
81
+ reason: `Active claim [${claim}] — close it first.\n bd close ${claim}\n (Pi workflow) publish/merge are external steps; do not rely on xtrm finish.\n`,
82
+ };
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ return undefined;
89
+ });
90
+
91
+ pi.on("tool_result", async (event, ctx) => {
92
+ if (isBashToolResult(event)) {
93
+ const command = event.input.command;
94
+ const sessionId = getSessionId(ctx);
95
+
96
+ // Auto-claim on bd update --claim regardless of exit code.
97
+ // bd returns exit 1 with "already in_progress" when status unchanged — still a valid claim intent.
98
+ if (command && /\bbd\s+update\b/.test(command) && /--claim\b/.test(command)) {
99
+ const issueMatch = command.match(/\bbd\s+update\s+(\S+)/);
100
+ if (issueMatch) {
101
+ const issueId = issueMatch[1];
102
+ const cwd = getCwd(ctx);
103
+ await SubprocessRunner.run("bd", ["kv", "set", `claimed:${sessionId}`, issueId], { cwd });
104
+ const claimNotice = `\n\nāœ… **Beads**: Session \`${sessionId}\` claimed issue \`${issueId}\`. File edits are now unblocked.`;
105
+ return { content: [...event.content, { type: "text", text: claimNotice }] };
106
+ }
107
+ }
108
+
109
+ if (command && /\bbd\s+close\b/.test(command) && !event.isError) {
110
+ const reminder = "\n\n**Beads Insight**: Work completed. Consider if this session produced insights worth persisting via `bd remember`.";
111
+ const newContent = [...event.content, { type: "text", text: reminder }];
112
+ return { content: newContent };
113
+ }
114
+ }
115
+ return undefined;
116
+ });
117
+
118
+ // Dual safety net: warn about unclosed claims when session ends (non-blocking)
119
+ const notifySessionEnd = async (ctx: any) => {
120
+ const cwd = getCwd(ctx);
121
+ if (!EventAdapter.isBeadsProject(cwd)) return;
122
+ const sessionId = getSessionId(ctx);
123
+ const claim = await getSessionClaim(sessionId, cwd);
124
+ if (!claim) return;
125
+
126
+ const message = `Beads: session ending with active claim [${claim}]`;
127
+ if (ctx.hasUI) {
128
+ ctx.ui.notify(message, "warning");
129
+ } else {
130
+ logger.warn(message);
131
+ }
132
+ };
133
+
134
+ // Memory gate: if the session's claimed issue was closed, prompt for insights.
135
+ // Uses sendUserMessage to trigger a new agent turn (Pi has no blocking stop hook).
136
+ // memoryGateFired prevents re-triggering on the follow-up agent_end.
137
+ const triggerMemoryGateIfNeeded = async (ctx: any) => {
138
+ if (memoryGateFired) return;
139
+ const cwd = getCwd(ctx);
140
+ if (!EventAdapter.isBeadsProject(cwd)) return;
141
+ const sessionId = getSessionId(ctx);
142
+ const claimId = await getSessionClaim(sessionId, cwd);
143
+ if (!claimId) return;
144
+
145
+ const result = await SubprocessRunner.run("bd", ["list", "--status=closed"], { cwd });
146
+ if (result.code !== 0 || !result.stdout.includes(claimId)) return;
147
+
148
+ memoryGateFired = true;
149
+ pi.sendUserMessage(
150
+ `🧠 Memory gate: claim \`${claimId}\` was closed this session.\n` +
151
+ `For each closed issue, worth persisting?\n` +
152
+ ` YES → \`bd remember "<insight>"\` NO → note "nothing to persist"`,
153
+ );
154
+ };
155
+
156
+ pi.on("agent_end", async (_event, ctx) => {
157
+ await notifySessionEnd(ctx);
158
+ await triggerMemoryGateIfNeeded(ctx);
159
+ return undefined;
160
+ });
161
+
162
+ pi.on("session_shutdown", async (_event, ctx) => {
163
+ await notifySessionEnd(ctx);
164
+ return undefined;
165
+ });
166
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@xtrm/pi-beads",
3
+ "version": "1.0.0",
4
+ "description": "xtrm Pi extension: beads",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./index.ts"
8
+ },
9
+ "keywords": [
10
+ "pi",
11
+ "extension",
12
+ "xtrm"
13
+ ],
14
+ "author": "xtrm",
15
+ "license": "MIT"
16
+ }