xtrm-tools 0.7.16 → 0.7.18

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 (264) hide show
  1. package/.xtrm/config/hooks.json +2 -0
  2. package/.xtrm/config/instructions/agents-top.md +2 -1
  3. package/.xtrm/registry.json +432 -707
  4. package/.xtrm/skills/default/creating-service-skills/scripts/bootstrap.py +82 -156
  5. package/.xtrm/skills/default/creating-service-skills/scripts/scaffolder.py +73 -121
  6. package/.xtrm/skills/default/hook-development/references/patterns.md +1 -1
  7. package/.xtrm/skills/default/last30days/scripts/test-v1-vs-v2.sh +2 -2
  8. package/.xtrm/skills/default/planning/SKILL.md +75 -29
  9. package/.xtrm/skills/default/releasing/SKILL.md +163 -57
  10. package/.xtrm/skills/default/security-pipeline/SKILL.md +192 -0
  11. package/.xtrm/skills/default/security-pipeline/scripts/security-bootstrap.sh +294 -0
  12. package/.xtrm/skills/default/security-pipeline/templates/.githooks/pre-push.template +39 -0
  13. package/.xtrm/skills/default/security-pipeline/templates/.github/workflows/gitleaks.yml +33 -0
  14. package/.xtrm/skills/default/security-pipeline/templates/.github/workflows/osv-scanner.yml +33 -0
  15. package/.xtrm/skills/default/security-pipeline/templates/.github/workflows/semgrep.yml +41 -0
  16. package/.xtrm/skills/default/security-pipeline/templates/.gitleaks.toml +44 -0
  17. package/.xtrm/skills/default/security-pipeline/templates/.pre-commit-config.yaml +67 -0
  18. package/.xtrm/skills/default/security-pipeline/templates/.semgrepignore +46 -0
  19. package/.xtrm/skills/default/security-pipeline/templates/scripts/security-scan.sh +57 -0
  20. package/.xtrm/skills/default/security-pipeline/templates/scripts/semgrep-diff.sh +68 -0
  21. package/.xtrm/skills/default/session-close-report/SKILL.md +167 -6
  22. package/.xtrm/skills/default/sync-docs/SKILL.md +1 -1
  23. package/.xtrm/skills/default/update-specialists/SKILL.md +204 -77
  24. package/.xtrm/skills/default/update-xt/SKILL.md +270 -4
  25. package/.xtrm/skills/default/updating-service-skills/scripts/drift_detector.py +22 -0
  26. package/.xtrm/skills/default/using-kpi/SKILL.md +47 -5
  27. package/.xtrm/skills/default/using-script-specialists/SKILL.md +7 -5
  28. package/.xtrm/skills/default/using-specialists/SKILL.md +13 -12
  29. package/.xtrm/skills/default/using-specialists-auto/SKILL.md +137 -0
  30. package/.xtrm/skills/default/using-specialists-v2/SKILL.md +15 -22
  31. package/.xtrm/skills/default/using-specialists-v3/SKILL.md +1074 -0
  32. package/.xtrm/skills/default/vaultctl/SKILL.md +2 -2
  33. package/CHANGELOG.md +91 -3
  34. package/cli/dist/index.cjs +12425 -3770
  35. package/cli/dist/index.cjs.map +1 -1
  36. package/cli/package.json +9 -3
  37. package/package.json +27 -7
  38. package/packages/pi-extensions/extensions/xtrm-ui/index.ts +76 -1
  39. package/packages/pi-extensions/package.json +1 -1
  40. package/.xtrm/config/pi/extensions/custom-footer/.pi/structured-returns/83051fe4-97da-4e2c-bdaa-343b32f4e714.combined.log +0 -7
  41. package/.xtrm/config/pi/extensions/custom-footer/.pi/structured-returns/83051fe4-97da-4e2c-bdaa-343b32f4e714.stderr.log +0 -0
  42. package/.xtrm/config/pi/extensions/custom-footer/.pi/structured-returns/83051fe4-97da-4e2c-bdaa-343b32f4e714.stdout.log +0 -7
  43. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/LICENSE +0 -22
  44. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/README.md +0 -29
  45. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts +0 -3
  46. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts.map +0 -1
  47. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js +0 -2
  48. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js.map +0 -1
  49. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts +0 -8
  50. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts.map +0 -1
  51. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js +0 -27
  52. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js.map +0 -1
  53. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts +0 -11
  54. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts.map +0 -1
  55. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js +0 -100
  56. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js.map +0 -1
  57. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts +0 -25
  58. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts.map +0 -1
  59. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js +0 -104
  60. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js.map +0 -1
  61. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts +0 -10
  62. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts.map +0 -1
  63. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js +0 -293
  64. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js.map +0 -1
  65. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts +0 -10
  66. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts.map +0 -1
  67. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js +0 -26
  68. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js.map +0 -1
  69. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts +0 -7
  70. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts.map +0 -1
  71. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js +0 -51
  72. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js.map +0 -1
  73. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts +0 -7
  74. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts.map +0 -1
  75. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js +0 -60
  76. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js.map +0 -1
  77. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts +0 -7
  78. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts.map +0 -1
  79. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js +0 -38
  80. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js.map +0 -1
  81. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts +0 -5
  82. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts.map +0 -1
  83. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js +0 -33
  84. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js.map +0 -1
  85. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts +0 -24
  86. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts.map +0 -1
  87. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js +0 -30
  88. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js.map +0 -1
  89. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts +0 -11
  90. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts.map +0 -1
  91. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js +0 -43
  92. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js.map +0 -1
  93. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts +0 -8
  94. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts.map +0 -1
  95. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js +0 -41
  96. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js.map +0 -1
  97. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts +0 -8
  98. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts.map +0 -1
  99. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js +0 -53
  100. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js.map +0 -1
  101. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts +0 -8
  102. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts.map +0 -1
  103. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js +0 -27
  104. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js.map +0 -1
  105. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts +0 -7
  106. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts.map +0 -1
  107. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js +0 -53
  108. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js.map +0 -1
  109. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts +0 -8
  110. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts.map +0 -1
  111. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js +0 -60
  112. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js.map +0 -1
  113. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts +0 -7
  114. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts.map +0 -1
  115. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js +0 -38
  116. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js.map +0 -1
  117. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts +0 -6
  118. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts.map +0 -1
  119. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js +0 -257
  120. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js.map +0 -1
  121. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts +0 -8
  122. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts.map +0 -1
  123. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js +0 -71
  124. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js.map +0 -1
  125. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts +0 -6
  126. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts.map +0 -1
  127. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js +0 -173
  128. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js.map +0 -1
  129. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts +0 -26
  130. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts.map +0 -1
  131. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js +0 -195
  132. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js.map +0 -1
  133. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts +0 -121
  134. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts.map +0 -1
  135. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js +0 -2
  136. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js.map +0 -1
  137. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts +0 -2
  138. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts.map +0 -1
  139. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js +0 -18
  140. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js.map +0 -1
  141. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts +0 -8
  142. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts.map +0 -1
  143. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js +0 -110
  144. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js.map +0 -1
  145. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts +0 -2
  146. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts.map +0 -1
  147. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js +0 -32
  148. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js.map +0 -1
  149. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts +0 -2
  150. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts.map +0 -1
  151. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js +0 -13
  152. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js.map +0 -1
  153. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts +0 -2
  154. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts.map +0 -1
  155. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js +0 -7
  156. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js.map +0 -1
  157. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts +0 -5
  158. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts.map +0 -1
  159. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js +0 -58
  160. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js.map +0 -1
  161. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts +0 -2
  162. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts.map +0 -1
  163. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js +0 -27
  164. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js.map +0 -1
  165. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts +0 -2
  166. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts.map +0 -1
  167. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js +0 -8
  168. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js.map +0 -1
  169. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/package.json +0 -40
  170. package/.xtrm/skills/default/planning/evals/evals.json +0 -19
  171. package/.xtrm/skills/default/quality-gates/evals/evals.json +0 -181
  172. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/FINAL-EVAL-SUMMARY.md +0 -75
  173. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/edge-case-auto-fix-verification/with_skill/outputs/response.md +0 -59
  174. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/edge-case-mixed-language-project/with_skill/outputs/response.md +0 -60
  175. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/eval-summary.md +0 -105
  176. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/partial-install-python-only/with_skill/outputs/response.md +0 -93
  177. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/python-refactor-request/with_skill/outputs/response.md +0 -104
  178. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/quality-gate-error-fix/with_skill/outputs/response.md +0 -74
  179. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-general-chat/with_skill/outputs/response.md +0 -18
  180. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-math-question/with_skill/outputs/response.md +0 -18
  181. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-unrelated-coding/with_skill/outputs/response.md +0 -56
  182. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/tdd-guard-blocking-confusion/with_skill/outputs/response.md +0 -67
  183. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/typescript-feature-with-tests/with_skill/outputs/response.md +0 -97
  184. package/.xtrm/skills/default/sync-docs/evals/evals.json +0 -89
  185. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/benchmark.json +0 -293
  186. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/benchmark.md +0 -13
  187. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/eval_metadata.json +0 -27
  188. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/outputs/result.md +0 -210
  189. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/grading.json +0 -28
  190. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/timing.json +0 -1
  191. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/outputs/result.md +0 -101
  192. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/grading.json +0 -28
  193. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/timing.json +0 -5
  194. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/timing.json +0 -5
  195. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/eval_metadata.json +0 -27
  196. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/outputs/result.md +0 -198
  197. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/grading.json +0 -28
  198. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/timing.json +0 -1
  199. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/outputs/result.md +0 -94
  200. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/grading.json +0 -28
  201. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/timing.json +0 -1
  202. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/eval_metadata.json +0 -27
  203. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/outputs/result.md +0 -237
  204. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/grading.json +0 -28
  205. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/timing.json +0 -1
  206. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/outputs/result.md +0 -134
  207. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/grading.json +0 -28
  208. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/timing.json +0 -1
  209. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/benchmark.json +0 -297
  210. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/benchmark.md +0 -13
  211. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/eval_metadata.json +0 -27
  212. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/outputs/result.md +0 -137
  213. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/grading.json +0 -92
  214. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/timing.json +0 -1
  215. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/outputs/result.md +0 -134
  216. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/grading.json +0 -86
  217. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/timing.json +0 -1
  218. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/eval_metadata.json +0 -27
  219. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/outputs/result.md +0 -193
  220. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/grading.json +0 -72
  221. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/timing.json +0 -1
  222. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/outputs/result.md +0 -211
  223. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/grading.json +0 -91
  224. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/timing.json +0 -5
  225. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/eval_metadata.json +0 -27
  226. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/outputs/result.md +0 -182
  227. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/grading.json +0 -95
  228. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/timing.json +0 -1
  229. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/outputs/result.md +0 -222
  230. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/grading.json +0 -88
  231. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/timing.json +0 -5
  232. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/benchmark.json +0 -298
  233. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/benchmark.md +0 -13
  234. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/eval_metadata.json +0 -27
  235. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/outputs/result.md +0 -125
  236. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/grading.json +0 -97
  237. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/timing.json +0 -5
  238. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/outputs/result.md +0 -144
  239. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/grading.json +0 -78
  240. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/timing.json +0 -5
  241. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/eval_metadata.json +0 -27
  242. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/outputs/result.md +0 -104
  243. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/grading.json +0 -91
  244. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/timing.json +0 -5
  245. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/outputs/result.md +0 -79
  246. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/grading.json +0 -82
  247. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/timing.json +0 -5
  248. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/eval_metadata.json +0 -27
  249. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase1_context.json +0 -302
  250. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase2_drift.txt +0 -33
  251. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase3_analysis.json +0 -114
  252. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase4_fix.txt +0 -118
  253. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase5_validate.txt +0 -38
  254. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/result.md +0 -158
  255. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/grading.json +0 -95
  256. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/timing.json +0 -5
  257. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/outputs/result.md +0 -71
  258. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/grading.json +0 -90
  259. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/timing.json +0 -5
  260. package/.xtrm/skills/default/test-planning/evals/evals.json +0 -23
  261. package/.xtrm/skills/default/using-specialists/SKILL.safe.md +0 -1082
  262. package/.xtrm/skills/default/using-specialists/SKILL.ultra.md +0 -1082
  263. package/.xtrm/skills/default/using-specialists/evals/evals.json +0 -68
  264. package/packages/pi-extensions/.serena/project.yml +0 -130
@@ -5,69 +5,55 @@ Bootstrap module for Service Skill Trinity.
5
5
  Provides root-discovery and registry CRUD operations shared across all
6
6
  service-skill workflow scripts. All scripts in the trinity import from here.
7
7
 
8
- Registry location: service-registry.json (preferred) or .claude/skills/service-registry.json (legacy)
9
- Skills location: .claude/skills/<service-id>/
8
+ Registry resolution order:
9
+ 1) $SERVICE_REGISTRY_PATH override
10
+ 2) <root>/service-registry.json
11
+ 3) <root>/.claude/skills/service-registry.json
12
+ 4) <root>/.xtrm/skills/user/packs/*/service-registry.json
13
+
14
+ For pack glob, first hit wins after disambiguation:
15
+ - If active pack discoverable, matching pack registry preferred
16
+ - Else lexicographically first registry used with stderr warning
17
+
18
+ Skills location: .xtrm/skills/user/packs/<pack>/<service-id>/
10
19
  """
11
20
 
12
21
  import json
13
22
  import os
23
+ import re
14
24
  import subprocess # nosec B404
15
25
  import sys
16
26
  from datetime import datetime, timezone
17
27
  from pathlib import Path
18
28
  from typing import Any
19
29
 
30
+ SERVICE_ID_PATTERN = re.compile(r"^[a-z0-9][a-z0-9-_]{0,63}$")
31
+ PACKS_ROOT_SUFFIX = Path(".xtrm") / "skills" / "user" / "packs"
20
32
 
21
- class BootstrapError(Exception):
22
- """Base exception for bootstrap operations."""
23
33
 
34
+ class BootstrapError(Exception):
24
35
  pass
25
36
 
26
37
 
27
38
  class RootResolutionError(BootstrapError):
28
- """Raised when project root cannot be determined."""
29
-
30
39
  pass
31
40
 
32
41
 
33
42
  class RegistryError(BootstrapError):
34
- """Raised when registry operations fail."""
35
-
36
43
  pass
37
44
 
38
45
 
39
46
  def get_project_root() -> str:
40
- """
41
- Resolve project root via git.
42
-
43
- Returns:
44
- Absolute path to project root
45
-
46
- Raises:
47
- RootResolutionError: If git command fails or returns invalid path
48
- """
49
47
  try:
50
- result = subprocess.run( # nosec B603 B607
51
- ["git", "rev-parse", "--show-toplevel"],
52
- capture_output=True,
53
- text=True,
54
- check=True,
55
- timeout=5,
56
- )
48
+ result = subprocess.run(["git", "rev-parse", "--show-toplevel"], capture_output=True, text=True, check=True, timeout=5) # nosec B603 B607
57
49
  root = result.stdout.strip()
58
-
59
50
  if not root:
60
51
  raise RootResolutionError("Git returned empty path")
61
-
62
52
  if not os.path.isdir(root):
63
53
  raise RootResolutionError(f"Resolved path is not a directory: {root}")
64
-
65
54
  return root
66
-
67
55
  except subprocess.CalledProcessError as e:
68
- raise RootResolutionError(
69
- f"Git root resolution failed: {e.stderr.strip() if e.stderr else str(e)}"
70
- ) from e
56
+ raise RootResolutionError(f"Git root resolution failed: {e.stderr.strip() if e.stderr else str(e)}") from e
71
57
  except subprocess.TimeoutExpired as e:
72
58
  raise RootResolutionError("Git command timed out") from e
73
59
  except FileNotFoundError as e:
@@ -75,35 +61,68 @@ def get_project_root() -> str:
75
61
 
76
62
 
77
63
  def get_skills_root(project_root: str | None = None) -> Path:
78
- """
79
- Get the .claude/skills/ directory path.
64
+ if project_root is None:
65
+ project_root = get_project_root()
66
+ return Path(project_root) / ".claude" / "skills"
80
67
 
81
- Args:
82
- project_root: Optional project root (uses get_project_root() if not provided)
83
68
 
84
- Returns:
85
- Path to .claude/skills/ directory
86
- """
69
+ def _packs_root(project_root: str | None = None) -> Path:
87
70
  if project_root is None:
88
71
  project_root = get_project_root()
89
- return Path(project_root) / ".claude" / "skills"
72
+ return Path(project_root) / PACKS_ROOT_SUFFIX
90
73
 
91
74
 
92
- def get_registry_path(project_root: str | None = None) -> Path:
93
- """
94
- Get the service-registry.json path.
75
+ def _ensure_within_root(candidate: Path, root: Path, label: str) -> Path:
76
+ resolved_root = root.resolve()
77
+ resolved_candidate = candidate.resolve(strict=False)
78
+ if resolved_root not in resolved_candidate.parents and resolved_candidate != resolved_root:
79
+ raise RootResolutionError(f"{label} must stay within {resolved_root}")
80
+ return resolved_candidate
81
+
82
+
83
+ def get_pack_path(project_root: str | None = None) -> Path | None:
84
+ if project_root is None:
85
+ env_root = os.environ.get("CLAUDE_PROJECT_DIR")
86
+ project_root = env_root or get_project_root()
87
+
88
+ root = Path(project_root)
89
+ packs_root = _packs_root(project_root)
90
+ env_pack = os.environ.get("XTRM_PACK")
91
+
92
+ if env_pack:
93
+ pack_path = Path(env_pack)
94
+ if not pack_path.is_absolute():
95
+ pack_path = packs_root / env_pack
96
+ return _ensure_within_root(pack_path, packs_root, "XTRM_PACK path")
95
97
 
96
- Resolution order:
97
- 1. SERVICE_REGISTRY_PATH env var (explicit override)
98
- 2. <project-root>/service-registry.json (preferred)
99
- 3. <project-root>/.claude/skills/service-registry.json (legacy fallback)
98
+ if not packs_root.exists():
99
+ return None
100
100
 
101
- Args:
102
- project_root: Optional project root
101
+ pack_dirs = [path for path in packs_root.iterdir() if path.is_dir()]
102
+ if len(pack_dirs) == 1:
103
+ return pack_dirs[0].resolve()
103
104
 
104
- Returns:
105
- Path to service registry
106
- """
105
+ return None
106
+
107
+
108
+ def _select_pack_registry(pack_registries: list[Path], project_root: str) -> Path:
109
+ active_pack = get_pack_path(project_root)
110
+ if active_pack is not None:
111
+ active_candidate = active_pack / "service-registry.json"
112
+ if active_candidate in pack_registries:
113
+ return active_candidate
114
+
115
+ chosen = sorted(pack_registries)[0]
116
+ if len(pack_registries) > 1:
117
+ candidates = ", ".join(str(p) for p in sorted(pack_registries))
118
+ print(
119
+ f"Warning: multiple pack registries found, using {chosen}. Candidates: {candidates}",
120
+ file=sys.stderr,
121
+ )
122
+ return chosen
123
+
124
+
125
+ def get_registry_path(project_root: str | None = None) -> Path:
107
126
  env_registry = os.environ.get("SERVICE_REGISTRY_PATH")
108
127
  if env_registry:
109
128
  return Path(env_registry)
@@ -114,32 +133,24 @@ def get_registry_path(project_root: str | None = None) -> Path:
114
133
 
115
134
  root = Path(project_root)
116
135
  preferred = root / "service-registry.json"
117
- legacy = root / ".claude" / "skills" / "service-registry.json"
118
-
119
- if preferred.exists() or not legacy.exists():
136
+ if preferred.exists():
120
137
  return preferred
121
138
 
122
- return legacy
123
-
139
+ legacy = root / ".claude" / "skills" / "service-registry.json"
140
+ if legacy.exists():
141
+ return legacy
124
142
 
125
- def load_registry(project_root: str | None = None) -> dict[str, Any]:
126
- """
127
- Load the service registry.
143
+ pack_registries = sorted(root.glob(".xtrm/skills/user/packs/*/service-registry.json"))
144
+ if pack_registries:
145
+ return _select_pack_registry(pack_registries, project_root)
128
146
 
129
- Args:
130
- project_root: Optional project root
147
+ return preferred
131
148
 
132
- Returns:
133
- Registry contents as dict
134
149
 
135
- Raises:
136
- RegistryError: If registry cannot be loaded
137
- """
150
+ def load_registry(project_root: str | None = None) -> dict[str, Any]:
138
151
  registry_path = get_registry_path(project_root)
139
-
140
152
  if not registry_path.exists():
141
153
  return {"version": "1.0", "services": {}}
142
-
143
154
  try:
144
155
  with open(registry_path, encoding="utf-8") as f:
145
156
  return json.load(f)
@@ -150,19 +161,8 @@ def load_registry(project_root: str | None = None) -> dict[str, Any]:
150
161
 
151
162
 
152
163
  def save_registry(data: dict[str, Any], project_root: str | None = None) -> None:
153
- """
154
- Save the service registry.
155
-
156
- Args:
157
- data: Registry contents
158
- project_root: Optional project root
159
-
160
- Raises:
161
- RegistryError: If registry cannot be saved
162
- """
163
164
  registry_path = get_registry_path(project_root)
164
165
  registry_path.parent.mkdir(parents=True, exist_ok=True)
165
-
166
166
  try:
167
167
  with open(registry_path, "w", encoding="utf-8") as f:
168
168
  json.dump(data, f, indent=2)
@@ -178,25 +178,9 @@ def register_service(
178
178
  description: str = "",
179
179
  project_root: str | None = None,
180
180
  ) -> None:
181
- """
182
- Register a new service in the registry.
183
-
184
- Args:
185
- service_id: Unique identifier (e.g., "db-expert")
186
- name: Display name (e.g., "Database Expert")
187
- territory: List of glob patterns for files this service owns
188
- skill_path: Path to SKILL.md relative to project root
189
- description: Optional description
190
- project_root: Optional project root
191
-
192
- Raises:
193
- RegistryError: If registration fails
194
- """
195
181
  registry = load_registry(project_root)
196
-
197
182
  if "services" not in registry:
198
183
  registry["services"] = {}
199
-
200
184
  registry["services"][service_id] = {
201
185
  "name": name,
202
186
  "territory": territory,
@@ -204,101 +188,46 @@ def register_service(
204
188
  "description": description,
205
189
  "last_sync": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
206
190
  }
207
-
208
191
  save_registry(registry, project_root)
209
192
 
210
193
 
211
194
  def unregister_service(service_id: str, project_root: str | None = None) -> bool:
212
- """
213
- Remove a service from the registry.
214
-
215
- Args:
216
- service_id: Service identifier to remove
217
- project_root: Optional project root
218
-
219
- Returns:
220
- True if service was removed, False if it didn't exist
221
- """
222
195
  registry = load_registry(project_root)
223
-
224
196
  if "services" not in registry or service_id not in registry["services"]:
225
197
  return False
226
-
227
198
  del registry["services"][service_id]
228
199
  save_registry(registry, project_root)
229
200
  return True
230
201
 
231
202
 
232
203
  def get_service(service_id: str, project_root: str | None = None) -> dict[str, Any] | None:
233
- """
234
- Get a service by ID.
235
-
236
- Args:
237
- service_id: Service identifier
238
- project_root: Optional project root
239
-
240
- Returns:
241
- Service dict or None if not found
242
- """
243
204
  registry = load_registry(project_root)
244
205
  return registry.get("services", {}).get(service_id)
245
206
 
246
207
 
247
208
  def list_services(project_root: str | None = None) -> dict[str, dict[str, Any]]:
248
- """
249
- List all registered services.
250
-
251
- Args:
252
- project_root: Optional project root
253
-
254
- Returns:
255
- Dict of service_id -> service_data
256
- """
257
209
  registry = load_registry(project_root)
258
210
  return registry.get("services", {})
259
211
 
260
212
 
261
213
  def find_service_for_path(file_path: str, project_root: str | None = None) -> str | None:
262
- """
263
- Find which service (if any) owns a given file path.
264
-
265
- Uses glob matching against territory patterns.
266
-
267
- Args:
268
- file_path: Relative path to check
269
- project_root: Optional project root
270
-
271
- Returns:
272
- Service ID or None if no match
273
- """
274
214
  registry = load_registry(project_root)
275
-
276
215
  if project_root is None:
277
216
  try:
278
217
  project_root = get_project_root()
279
218
  except RootResolutionError:
280
219
  return None
281
-
282
220
  project_root = Path(project_root)
283
221
  file_path_obj = Path(file_path)
284
-
285
- if not file_path_obj.is_absolute():
286
- test_path = project_root / file_path_obj
287
- else:
288
- test_path = file_path_obj
289
-
222
+ test_path = project_root / file_path_obj if not file_path_obj.is_absolute() else file_path_obj
290
223
  for service_id, service_data in registry.get("services", {}).items():
291
- territory = service_data.get("territory", [])
292
- for pattern in territory:
293
- # Direct glob match
224
+ for pattern in service_data.get("territory", []):
294
225
  for glob_match in Path(project_root).glob(pattern):
295
226
  if glob_match == test_path:
296
227
  return service_id
297
- # Prefix match for directory patterns
298
228
  base = pattern.replace("/**/*", "").replace("/**", "").rstrip("/")
299
229
  if str(file_path).startswith(base + "/") or str(file_path) == base:
300
230
  return service_id
301
-
302
231
  return None
303
232
 
304
233
 
@@ -307,16 +236,13 @@ if __name__ == "__main__":
307
236
  print("Usage: python bootstrap.py <command> [args...]")
308
237
  print("Commands: root, registry, list, find <path>")
309
238
  sys.exit(1)
310
-
311
239
  command = sys.argv[1]
312
-
313
240
  if command == "root":
314
241
  print(get_project_root())
315
242
  elif command == "registry":
316
243
  print(json.dumps(load_registry(), indent=2))
317
244
  elif command == "list":
318
- services = list_services()
319
- for sid, data in services.items():
245
+ for sid, data in list_services().items():
320
246
  print(f"- {sid}: {data.get('name', 'N/A')} ({data.get('description', 'N/A')})")
321
247
  elif command == "find" and len(sys.argv) > 2:
322
248
  result = find_service_for_path(sys.argv[2])