xtrm-tools 0.7.3 → 0.7.4

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 (527) hide show
  1. package/.xtrm/config/pi/extensions/xtrm-ui/format.ts +189 -0
  2. package/.xtrm/config/pi/extensions/xtrm-ui/index.ts +76 -17
  3. package/.xtrm/config/pi/extensions/xtrm-ui/package.json +16 -5
  4. package/.xtrm/hooks/specialists/specialists-complete.mjs +70 -0
  5. package/.xtrm/hooks/specialists/specialists-session-start.mjs +105 -0
  6. package/.xtrm/registry.json +397 -409
  7. package/.xtrm/skills/default/README.txt +31 -0
  8. package/.xtrm/skills/default/clean-code/SKILL.md +201 -0
  9. package/.xtrm/skills/default/creating-service-skills/SKILL.md +433 -0
  10. package/.xtrm/skills/default/creating-service-skills/references/script_quality_standards.md +425 -0
  11. package/.xtrm/skills/default/creating-service-skills/references/service_skill_system_guide.md +278 -0
  12. package/.xtrm/skills/default/creating-service-skills/scripts/bootstrap.py +326 -0
  13. package/.xtrm/skills/default/creating-service-skills/scripts/deep_dive.py +304 -0
  14. package/.xtrm/skills/default/creating-service-skills/scripts/scaffolder.py +482 -0
  15. package/.xtrm/skills/default/deepwiki/SKILL.md +50 -0
  16. package/.xtrm/skills/default/delegating/SKILL.md +196 -0
  17. package/.xtrm/skills/default/delegating/config.yaml +210 -0
  18. package/.xtrm/skills/default/delegating/references/orchestration-protocols.md +41 -0
  19. package/.xtrm/skills/default/documenting/CHANGELOG.md +23 -0
  20. package/.xtrm/skills/default/documenting/README.md +148 -0
  21. package/.xtrm/skills/default/documenting/SKILL.md +113 -0
  22. package/.xtrm/skills/default/documenting/examples/example_pattern.md +70 -0
  23. package/.xtrm/skills/default/documenting/examples/example_reference.md +70 -0
  24. package/.xtrm/skills/default/documenting/examples/example_ssot_analytics.md +64 -0
  25. package/.xtrm/skills/default/documenting/examples/example_workflow.md +141 -0
  26. package/.xtrm/skills/default/documenting/references/changelog-format.md +97 -0
  27. package/.xtrm/skills/default/documenting/references/metadata-schema.md +136 -0
  28. package/.xtrm/skills/default/documenting/references/taxonomy.md +81 -0
  29. package/.xtrm/skills/default/documenting/references/versioning-rules.md +78 -0
  30. package/.xtrm/skills/default/documenting/scripts/bump_version.sh +60 -0
  31. package/.xtrm/skills/default/documenting/scripts/changelog/__init__.py +0 -0
  32. package/.xtrm/skills/default/documenting/scripts/changelog/add_entry.py +216 -0
  33. package/.xtrm/skills/default/documenting/scripts/changelog/bump_release.py +117 -0
  34. package/.xtrm/skills/default/documenting/scripts/changelog/init_changelog.py +54 -0
  35. package/.xtrm/skills/default/documenting/scripts/changelog/validate_changelog.py +128 -0
  36. package/.xtrm/skills/default/documenting/scripts/drift_detector.py +266 -0
  37. package/.xtrm/skills/default/documenting/scripts/generate_template.py +311 -0
  38. package/.xtrm/skills/default/documenting/scripts/list_by_category.sh +84 -0
  39. package/.xtrm/skills/default/documenting/scripts/orchestrator.py +255 -0
  40. package/.xtrm/skills/default/documenting/scripts/validate_metadata.py +242 -0
  41. package/.xtrm/skills/default/documenting/templates/CHANGELOG.md.template +13 -0
  42. package/.xtrm/skills/default/find-docs/SKILL.md +175 -0
  43. package/.xtrm/skills/default/find-skills/SKILL.md +133 -0
  44. package/.xtrm/skills/default/github-search/SKILL.md +49 -0
  45. package/.xtrm/skills/default/gitnexus-debugging/SKILL.md +89 -0
  46. package/.xtrm/skills/default/gitnexus-impact-analysis/SKILL.md +97 -0
  47. package/.xtrm/skills/default/gitnexus-pr-review/SKILL.md +163 -0
  48. package/.xtrm/skills/default/gitnexus-refactoring/SKILL.md +121 -0
  49. package/.xtrm/skills/default/hook-development/SKILL.md +797 -0
  50. package/.xtrm/skills/default/hook-development/examples/load-context.sh +55 -0
  51. package/.xtrm/skills/default/hook-development/examples/quality-check.js +1168 -0
  52. package/.xtrm/skills/default/hook-development/examples/validate-bash.sh +43 -0
  53. package/.xtrm/skills/default/hook-development/examples/validate-write.sh +38 -0
  54. package/.xtrm/skills/default/hook-development/references/advanced.md +527 -0
  55. package/.xtrm/skills/default/hook-development/references/migration.md +369 -0
  56. package/.xtrm/skills/default/hook-development/references/patterns.md +412 -0
  57. package/.xtrm/skills/default/hook-development/scripts/README.md +164 -0
  58. package/.xtrm/skills/default/hook-development/scripts/hook-linter.sh +153 -0
  59. package/.xtrm/skills/default/hook-development/scripts/test-hook.sh +252 -0
  60. package/.xtrm/skills/default/hook-development/scripts/validate-hook-schema.sh +159 -0
  61. package/.xtrm/skills/default/init-session/SKILL.md +69 -0
  62. package/.xtrm/skills/default/last30days/SKILL.md +881 -0
  63. package/.xtrm/skills/default/last30days/scripts/briefing.py +260 -0
  64. package/.xtrm/skills/default/last30days/scripts/evaluate-synthesis.py +120 -0
  65. package/.xtrm/skills/default/last30days/scripts/evaluate_search_quality.py +641 -0
  66. package/.xtrm/skills/default/last30days/scripts/generate-synthesis-inputs.py +53 -0
  67. package/.xtrm/skills/default/last30days/scripts/last30days.py +2137 -0
  68. package/.xtrm/skills/default/last30days/scripts/lib/__init__.py +1 -0
  69. package/.xtrm/skills/default/last30days/scripts/lib/bird_x.py +458 -0
  70. package/.xtrm/skills/default/last30days/scripts/lib/bluesky.py +225 -0
  71. package/.xtrm/skills/default/last30days/scripts/lib/brave_search.py +329 -0
  72. package/.xtrm/skills/default/last30days/scripts/lib/cache.py +165 -0
  73. package/.xtrm/skills/default/last30days/scripts/lib/chrome_cookies.py +265 -0
  74. package/.xtrm/skills/default/last30days/scripts/lib/cookie_extract.py +295 -0
  75. package/.xtrm/skills/default/last30days/scripts/lib/dates.py +124 -0
  76. package/.xtrm/skills/default/last30days/scripts/lib/dedupe.py +290 -0
  77. package/.xtrm/skills/default/last30days/scripts/lib/entity_extract.py +127 -0
  78. package/.xtrm/skills/default/last30days/scripts/lib/env.py +807 -0
  79. package/.xtrm/skills/default/last30days/scripts/lib/exa_search.py +176 -0
  80. package/.xtrm/skills/default/last30days/scripts/lib/hackernews.py +266 -0
  81. package/.xtrm/skills/default/last30days/scripts/lib/http.py +174 -0
  82. package/.xtrm/skills/default/last30days/scripts/lib/instagram.py +365 -0
  83. package/.xtrm/skills/default/last30days/scripts/lib/models.py +221 -0
  84. package/.xtrm/skills/default/last30days/scripts/lib/normalize.py +489 -0
  85. package/.xtrm/skills/default/last30days/scripts/lib/openai_reddit.py +631 -0
  86. package/.xtrm/skills/default/last30days/scripts/lib/openrouter_search.py +216 -0
  87. package/.xtrm/skills/default/last30days/scripts/lib/parallel_search.py +139 -0
  88. package/.xtrm/skills/default/last30days/scripts/lib/polymarket.py +580 -0
  89. package/.xtrm/skills/default/last30days/scripts/lib/quality_nudge.py +201 -0
  90. package/.xtrm/skills/default/last30days/scripts/lib/query.py +117 -0
  91. package/.xtrm/skills/default/last30days/scripts/lib/query_type.py +111 -0
  92. package/.xtrm/skills/default/last30days/scripts/lib/reddit.py +617 -0
  93. package/.xtrm/skills/default/last30days/scripts/lib/reddit_enrich.py +325 -0
  94. package/.xtrm/skills/default/last30days/scripts/lib/reddit_public.py +259 -0
  95. package/.xtrm/skills/default/last30days/scripts/lib/relevance.py +148 -0
  96. package/.xtrm/skills/default/last30days/scripts/lib/render.py +1018 -0
  97. package/.xtrm/skills/default/last30days/scripts/lib/safari_cookies.py +182 -0
  98. package/.xtrm/skills/default/last30days/scripts/lib/schema.py +843 -0
  99. package/.xtrm/skills/default/last30days/scripts/lib/score.py +775 -0
  100. package/.xtrm/skills/default/last30days/scripts/lib/scrapecreators_x.py +182 -0
  101. package/.xtrm/skills/default/last30days/scripts/lib/setup_wizard.py +186 -0
  102. package/.xtrm/skills/default/last30days/scripts/lib/tiktok.py +349 -0
  103. package/.xtrm/skills/default/last30days/scripts/lib/truthsocial.py +183 -0
  104. package/.xtrm/skills/default/last30days/scripts/lib/ui.py +620 -0
  105. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/LICENSE +21 -0
  106. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/bird-search.mjs +134 -0
  107. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/cookies.js +191 -0
  108. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/features.json +17 -0
  109. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/paginate-cursor.js +37 -0
  110. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/query-ids.json +20 -0
  111. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/runtime-features.js +151 -0
  112. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/runtime-query-ids.js +264 -0
  113. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-base.js +129 -0
  114. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-constants.js +50 -0
  115. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-features.js +347 -0
  116. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-search.js +157 -0
  117. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-types.js +2 -0
  118. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-utils.js +511 -0
  119. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/LICENSE +22 -0
  120. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/README.md +29 -0
  121. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts +3 -0
  122. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts.map +1 -0
  123. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js +2 -0
  124. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js.map +1 -0
  125. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts +8 -0
  126. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts.map +1 -0
  127. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js +27 -0
  128. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js.map +1 -0
  129. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts +11 -0
  130. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts.map +1 -0
  131. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js +100 -0
  132. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js.map +1 -0
  133. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts +25 -0
  134. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts.map +1 -0
  135. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js +104 -0
  136. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js.map +1 -0
  137. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts +10 -0
  138. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts.map +1 -0
  139. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js +293 -0
  140. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js.map +1 -0
  141. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts +10 -0
  142. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts.map +1 -0
  143. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js +26 -0
  144. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js.map +1 -0
  145. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts +7 -0
  146. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts.map +1 -0
  147. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js +51 -0
  148. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js.map +1 -0
  149. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts +7 -0
  150. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts.map +1 -0
  151. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js +60 -0
  152. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js.map +1 -0
  153. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts +7 -0
  154. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts.map +1 -0
  155. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js +38 -0
  156. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js.map +1 -0
  157. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts +5 -0
  158. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts.map +1 -0
  159. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js +33 -0
  160. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js.map +1 -0
  161. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts +24 -0
  162. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts.map +1 -0
  163. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js +30 -0
  164. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js.map +1 -0
  165. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts +11 -0
  166. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts.map +1 -0
  167. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js +43 -0
  168. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js.map +1 -0
  169. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts +8 -0
  170. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts.map +1 -0
  171. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js +41 -0
  172. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js.map +1 -0
  173. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts +8 -0
  174. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts.map +1 -0
  175. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js +53 -0
  176. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js.map +1 -0
  177. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts +8 -0
  178. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts.map +1 -0
  179. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js +27 -0
  180. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js.map +1 -0
  181. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts +7 -0
  182. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts.map +1 -0
  183. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js +53 -0
  184. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js.map +1 -0
  185. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts +8 -0
  186. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts.map +1 -0
  187. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js +60 -0
  188. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js.map +1 -0
  189. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts +7 -0
  190. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts.map +1 -0
  191. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js +38 -0
  192. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js.map +1 -0
  193. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts +6 -0
  194. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts.map +1 -0
  195. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js +257 -0
  196. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js.map +1 -0
  197. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts +8 -0
  198. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts.map +1 -0
  199. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js +71 -0
  200. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js.map +1 -0
  201. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts +6 -0
  202. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts.map +1 -0
  203. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js +173 -0
  204. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js.map +1 -0
  205. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts +26 -0
  206. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts.map +1 -0
  207. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js +195 -0
  208. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js.map +1 -0
  209. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts +121 -0
  210. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts.map +1 -0
  211. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js +2 -0
  212. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js.map +1 -0
  213. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts +2 -0
  214. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts.map +1 -0
  215. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js +18 -0
  216. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js.map +1 -0
  217. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts +8 -0
  218. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts.map +1 -0
  219. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js +110 -0
  220. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js.map +1 -0
  221. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts +2 -0
  222. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts.map +1 -0
  223. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js +32 -0
  224. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js.map +1 -0
  225. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts +2 -0
  226. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts.map +1 -0
  227. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js +13 -0
  228. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js.map +1 -0
  229. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts +2 -0
  230. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts.map +1 -0
  231. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js +7 -0
  232. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js.map +1 -0
  233. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts +5 -0
  234. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts.map +1 -0
  235. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js +58 -0
  236. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js.map +1 -0
  237. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts +2 -0
  238. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts.map +1 -0
  239. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js +27 -0
  240. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js.map +1 -0
  241. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts +2 -0
  242. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts.map +1 -0
  243. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js +8 -0
  244. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js.map +1 -0
  245. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/package.json +40 -0
  246. package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/package.json +13 -0
  247. package/.xtrm/skills/default/last30days/scripts/lib/websearch.py +401 -0
  248. package/.xtrm/skills/default/last30days/scripts/lib/xai_x.py +217 -0
  249. package/.xtrm/skills/default/last30days/scripts/lib/xiaohongshu_api.py +162 -0
  250. package/.xtrm/skills/default/last30days/scripts/lib/youtube_yt.py +538 -0
  251. package/.xtrm/skills/default/last30days/scripts/store.py +654 -0
  252. package/.xtrm/skills/default/last30days/scripts/sync.sh +50 -0
  253. package/.xtrm/skills/default/last30days/scripts/test-v1-vs-v2.sh +219 -0
  254. package/.xtrm/skills/default/last30days/scripts/watchlist.py +329 -0
  255. package/.xtrm/skills/default/planning/SKILL.md +405 -0
  256. package/.xtrm/skills/default/planning/evals/evals.json +19 -0
  257. package/.xtrm/skills/default/prompt-improving/README.md +162 -0
  258. package/.xtrm/skills/default/prompt-improving/SKILL.md +74 -0
  259. package/.xtrm/skills/default/prompt-improving/references/analysis_commands.md +24 -0
  260. package/.xtrm/skills/default/prompt-improving/references/chain_of_thought.md +24 -0
  261. package/.xtrm/skills/default/prompt-improving/references/mcp_definitions.md +20 -0
  262. package/.xtrm/skills/default/prompt-improving/references/multishot.md +23 -0
  263. package/.xtrm/skills/default/prompt-improving/references/xml_core.md +60 -0
  264. package/.xtrm/skills/default/quality-gates/.claude/hooks/hook-config.json +66 -0
  265. package/.xtrm/skills/default/quality-gates/.claude/hooks/quality-check.cjs +1286 -0
  266. package/.xtrm/skills/default/quality-gates/.claude/hooks/quality-check.py +334 -0
  267. package/.xtrm/skills/default/quality-gates/.claude/settings.json +3 -0
  268. package/.xtrm/skills/default/quality-gates/.claude/skills/using-quality-gates/SKILL.md +254 -0
  269. package/.xtrm/skills/default/quality-gates/README.md +109 -0
  270. package/.xtrm/skills/default/quality-gates/evals/evals.json +181 -0
  271. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/FINAL-EVAL-SUMMARY.md +75 -0
  272. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/edge-case-auto-fix-verification/with_skill/outputs/response.md +59 -0
  273. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/edge-case-mixed-language-project/with_skill/outputs/response.md +60 -0
  274. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/eval-summary.md +105 -0
  275. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/partial-install-python-only/with_skill/outputs/response.md +93 -0
  276. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/python-refactor-request/with_skill/outputs/response.md +104 -0
  277. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/quality-gate-error-fix/with_skill/outputs/response.md +74 -0
  278. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-general-chat/with_skill/outputs/response.md +18 -0
  279. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-math-question/with_skill/outputs/response.md +18 -0
  280. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-unrelated-coding/with_skill/outputs/response.md +56 -0
  281. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/tdd-guard-blocking-confusion/with_skill/outputs/response.md +67 -0
  282. package/.xtrm/skills/default/quality-gates/workspace/iteration-1/typescript-feature-with-tests/with_skill/outputs/response.md +97 -0
  283. package/.xtrm/skills/default/scoping-service-skills/SKILL.md +231 -0
  284. package/.xtrm/skills/default/scoping-service-skills/scripts/scope.py +74 -0
  285. package/.xtrm/skills/default/service-skills-set/README.md +93 -0
  286. package/.xtrm/skills/default/service-skills-set/git-hooks/doc_reminder.py +67 -0
  287. package/.xtrm/skills/default/service-skills-set/git-hooks/skill_staleness.py +194 -0
  288. package/.xtrm/skills/default/service-skills-set/install-service-skills.py +193 -0
  289. package/.xtrm/skills/default/service-skills-set/service-registry.json +4 -0
  290. package/.xtrm/skills/default/service-skills-set/service-skills-readme.md +236 -0
  291. package/.xtrm/skills/default/service-skills-set/settings.json +37 -0
  292. package/.xtrm/skills/default/session-close-report/SKILL.md +131 -0
  293. package/.xtrm/skills/default/skill-creator/LICENSE.txt +202 -0
  294. package/.xtrm/skills/default/skill-creator/SKILL.md +479 -0
  295. package/.xtrm/skills/default/skill-creator/agents/analyzer.md +274 -0
  296. package/.xtrm/skills/default/skill-creator/agents/comparator.md +202 -0
  297. package/.xtrm/skills/default/skill-creator/agents/grader.md +223 -0
  298. package/.xtrm/skills/default/skill-creator/assets/eval_review.html +146 -0
  299. package/.xtrm/skills/default/skill-creator/eval-viewer/generate_review.py +471 -0
  300. package/.xtrm/skills/default/skill-creator/eval-viewer/viewer.html +1325 -0
  301. package/.xtrm/skills/default/skill-creator/references/schemas.md +430 -0
  302. package/.xtrm/skills/default/skill-creator/scripts/__init__.py +0 -0
  303. package/.xtrm/skills/default/skill-creator/scripts/aggregate_benchmark.py +401 -0
  304. package/.xtrm/skills/default/skill-creator/scripts/generate_report.py +326 -0
  305. package/.xtrm/skills/default/skill-creator/scripts/improve_description.py +248 -0
  306. package/.xtrm/skills/default/skill-creator/scripts/package_skill.py +136 -0
  307. package/.xtrm/skills/default/skill-creator/scripts/quick_validate.py +103 -0
  308. package/.xtrm/skills/default/skill-creator/scripts/run_eval.py +310 -0
  309. package/.xtrm/skills/default/skill-creator/scripts/run_loop.py +332 -0
  310. package/.xtrm/skills/default/skill-creator/scripts/utils.py +47 -0
  311. package/.xtrm/skills/default/specialists-creator/SKILL.md +705 -0
  312. package/.xtrm/skills/default/specialists-creator/scripts/validate-specialist.ts +41 -0
  313. package/.xtrm/skills/default/sync-docs/SKILL.md +262 -0
  314. package/.xtrm/skills/default/sync-docs/evals/evals.json +89 -0
  315. package/.xtrm/skills/default/sync-docs/references/doc-structure.md +99 -0
  316. package/.xtrm/skills/default/sync-docs/references/schema.md +103 -0
  317. package/.xtrm/skills/default/sync-docs/scripts/changelog/add_entry.py +216 -0
  318. package/.xtrm/skills/default/sync-docs/scripts/context_gatherer.py +405 -0
  319. package/.xtrm/skills/default/sync-docs/scripts/doc_structure_analyzer.py +495 -0
  320. package/.xtrm/skills/default/sync-docs/scripts/drift_detector.py +563 -0
  321. package/.xtrm/skills/default/sync-docs/scripts/validate_doc.py +365 -0
  322. package/.xtrm/skills/default/sync-docs/scripts/validate_metadata.py +185 -0
  323. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/benchmark.json +293 -0
  324. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/benchmark.md +13 -0
  325. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/eval_metadata.json +27 -0
  326. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/outputs/result.md +210 -0
  327. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/grading.json +28 -0
  328. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/timing.json +1 -0
  329. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/outputs/result.md +101 -0
  330. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/grading.json +28 -0
  331. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/timing.json +5 -0
  332. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/timing.json +5 -0
  333. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/eval_metadata.json +27 -0
  334. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/outputs/result.md +198 -0
  335. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/grading.json +28 -0
  336. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/timing.json +1 -0
  337. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/outputs/result.md +94 -0
  338. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/grading.json +28 -0
  339. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/timing.json +1 -0
  340. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/eval_metadata.json +27 -0
  341. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/outputs/result.md +237 -0
  342. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/grading.json +28 -0
  343. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
  344. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/outputs/result.md +134 -0
  345. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/grading.json +28 -0
  346. package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/timing.json +1 -0
  347. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/benchmark.json +297 -0
  348. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/benchmark.md +13 -0
  349. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/eval_metadata.json +27 -0
  350. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/outputs/result.md +137 -0
  351. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/grading.json +92 -0
  352. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/timing.json +1 -0
  353. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/outputs/result.md +134 -0
  354. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/grading.json +86 -0
  355. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/timing.json +1 -0
  356. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/eval_metadata.json +27 -0
  357. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/outputs/result.md +193 -0
  358. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/grading.json +72 -0
  359. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/timing.json +1 -0
  360. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/outputs/result.md +211 -0
  361. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/grading.json +91 -0
  362. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/timing.json +5 -0
  363. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/eval_metadata.json +27 -0
  364. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/outputs/result.md +182 -0
  365. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
  366. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
  367. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/outputs/result.md +222 -0
  368. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/grading.json +88 -0
  369. package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
  370. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/benchmark.json +298 -0
  371. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/benchmark.md +13 -0
  372. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/eval_metadata.json +27 -0
  373. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/outputs/result.md +125 -0
  374. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/grading.json +97 -0
  375. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/timing.json +5 -0
  376. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/outputs/result.md +144 -0
  377. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/grading.json +78 -0
  378. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/timing.json +5 -0
  379. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/eval_metadata.json +27 -0
  380. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/outputs/result.md +104 -0
  381. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/grading.json +91 -0
  382. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/timing.json +5 -0
  383. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/outputs/result.md +79 -0
  384. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/grading.json +82 -0
  385. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/timing.json +5 -0
  386. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/eval_metadata.json +27 -0
  387. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase1_context.json +302 -0
  388. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase2_drift.txt +33 -0
  389. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase3_analysis.json +114 -0
  390. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase4_fix.txt +118 -0
  391. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase5_validate.txt +38 -0
  392. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/result.md +158 -0
  393. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
  394. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/timing.json +5 -0
  395. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/outputs/result.md +71 -0
  396. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/grading.json +90 -0
  397. package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
  398. package/.xtrm/skills/default/test-planning/SKILL.md +465 -0
  399. package/.xtrm/skills/default/test-planning/evals/evals.json +23 -0
  400. package/.xtrm/skills/default/updating-service-skills/SKILL.md +136 -0
  401. package/.xtrm/skills/default/updating-service-skills/scripts/drift_detector.py +222 -0
  402. package/.xtrm/skills/default/using-nodes/SKILL.md +333 -0
  403. package/.xtrm/skills/default/using-quality-gates/SKILL.md +254 -0
  404. package/.xtrm/skills/default/using-service-skills/SKILL.md +108 -0
  405. package/.xtrm/skills/default/using-service-skills/scripts/cataloger.py +74 -0
  406. package/.xtrm/skills/default/using-service-skills/scripts/skill_activator.py +152 -0
  407. package/.xtrm/skills/default/using-specialists/SKILL.md +848 -0
  408. package/.xtrm/skills/default/using-specialists/evals/evals.json +68 -0
  409. package/.xtrm/skills/default/using-tdd/SKILL.md +410 -0
  410. package/.xtrm/skills/default/using-xtrm/SKILL.md +127 -0
  411. package/.xtrm/skills/default/xt-debugging/SKILL.md +149 -0
  412. package/.xtrm/skills/default/xt-end/SKILL.md +297 -0
  413. package/.xtrm/skills/default/xt-merge/SKILL.md +326 -0
  414. package/.xtrm/skills/optional/README.txt +2 -0
  415. package/.xtrm/skills/optional/architecture-design/PACK.json +11 -0
  416. package/.xtrm/skills/optional/architecture-design/architecture-patterns/SKILL.md +494 -0
  417. package/.xtrm/skills/optional/architecture-design/architecture-patterns/references/advanced-patterns.md +391 -0
  418. package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/SKILL.md +473 -0
  419. package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/assets/few-shot-examples.json +106 -0
  420. package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/assets/prompt-template-library.md +264 -0
  421. package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/chain-of-thought.md +412 -0
  422. package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/few-shot-learning.md +386 -0
  423. package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/prompt-optimization.md +428 -0
  424. package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/prompt-templates.md +484 -0
  425. package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/system-prompts.md +195 -0
  426. package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
  427. package/.xtrm/skills/optional/architecture-design/subagent-driven-development/SKILL.md +277 -0
  428. package/.xtrm/skills/optional/architecture-design/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
  429. package/.xtrm/skills/optional/architecture-design/subagent-driven-development/implementer-prompt.md +113 -0
  430. package/.xtrm/skills/optional/architecture-design/subagent-driven-development/spec-reviewer-prompt.md +61 -0
  431. package/.xtrm/skills/optional/code-quality/PACK.json +12 -0
  432. package/.xtrm/skills/optional/code-quality/code-review-excellence/SKILL.md +529 -0
  433. package/.xtrm/skills/optional/code-quality/multi-reviewer-patterns/SKILL.md +127 -0
  434. package/.xtrm/skills/optional/code-quality/systematic-debugging/SKILL.md +296 -0
  435. package/.xtrm/skills/optional/code-quality/verification-before-completion/SKILL.md +139 -0
  436. package/.xtrm/skills/optional/data-engineering/PACK.json +9 -0
  437. package/.xtrm/skills/optional/data-engineering/data-analyst/SKILL.md +57 -0
  438. package/.xtrm/skills/optional/research-methods/PACK.json +12 -0
  439. package/.xtrm/skills/optional/research-methods/academic-researcher/SKILL.md +269 -0
  440. package/.xtrm/skills/optional/research-methods/brainstorming/SKILL.md +164 -0
  441. package/.xtrm/skills/optional/research-methods/brainstorming/scripts/frame-template.html +214 -0
  442. package/.xtrm/skills/optional/research-methods/brainstorming/scripts/helper.js +88 -0
  443. package/.xtrm/skills/optional/research-methods/brainstorming/scripts/server.cjs +354 -0
  444. package/.xtrm/skills/optional/research-methods/brainstorming/scripts/start-server.sh +148 -0
  445. package/.xtrm/skills/optional/research-methods/brainstorming/scripts/stop-server.sh +56 -0
  446. package/.xtrm/skills/optional/research-methods/brainstorming/spec-document-reviewer-prompt.md +49 -0
  447. package/.xtrm/skills/optional/research-methods/brainstorming/visual-companion.md +287 -0
  448. package/.xtrm/skills/optional/research-methods/deep-research/SKILL.md +192 -0
  449. package/.xtrm/skills/optional/research-methods/fact-checker/SKILL.md +182 -0
  450. package/.xtrm/skills/optional/security-ops/PACK.json +9 -0
  451. package/.xtrm/skills/optional/security-ops/security-auditor/SKILL.md +165 -0
  452. package/.xtrm/skills/optional/xt-optional/PACK.json +16 -0
  453. package/.xtrm/skills/optional/xt-optional/docker-expert/SKILL.md +409 -0
  454. package/.xtrm/skills/optional/xt-optional/obsidian-cli/SKILL.md +106 -0
  455. package/.xtrm/skills/optional/xt-optional/python-testing/SKILL.md +815 -0
  456. package/.xtrm/skills/optional/xt-optional/senior-backend/SKILL.md +209 -0
  457. package/.xtrm/skills/optional/xt-optional/senior-backend/references/api_design_patterns.md +103 -0
  458. package/.xtrm/skills/optional/xt-optional/senior-backend/references/backend_security_practices.md +103 -0
  459. package/.xtrm/skills/optional/xt-optional/senior-backend/references/database_optimization_guide.md +103 -0
  460. package/.xtrm/skills/optional/xt-optional/senior-backend/scripts/api_load_tester.py +114 -0
  461. package/.xtrm/skills/optional/xt-optional/senior-backend/scripts/api_scaffolder.py +114 -0
  462. package/.xtrm/skills/optional/xt-optional/senior-backend/scripts/database_migration_tool.py +114 -0
  463. package/.xtrm/skills/optional/xt-optional/senior-data-scientist/SKILL.md +226 -0
  464. package/.xtrm/skills/optional/xt-optional/senior-data-scientist/references/experiment_design_frameworks.md +80 -0
  465. package/.xtrm/skills/optional/xt-optional/senior-data-scientist/references/feature_engineering_patterns.md +80 -0
  466. package/.xtrm/skills/optional/xt-optional/senior-data-scientist/references/statistical_methods_advanced.md +80 -0
  467. package/.xtrm/skills/optional/xt-optional/senior-data-scientist/scripts/experiment_designer.py +100 -0
  468. package/.xtrm/skills/optional/xt-optional/senior-data-scientist/scripts/feature_engineering_pipeline.py +100 -0
  469. package/.xtrm/skills/optional/xt-optional/senior-data-scientist/scripts/model_evaluation_suite.py +100 -0
  470. package/.xtrm/skills/optional/xt-optional/senior-devops/SKILL.md +209 -0
  471. package/.xtrm/skills/optional/xt-optional/senior-devops/references/cicd_pipeline_guide.md +103 -0
  472. package/.xtrm/skills/optional/xt-optional/senior-devops/references/deployment_strategies.md +103 -0
  473. package/.xtrm/skills/optional/xt-optional/senior-devops/references/infrastructure_as_code.md +103 -0
  474. package/.xtrm/skills/optional/xt-optional/senior-devops/scripts/deployment_manager.py +114 -0
  475. package/.xtrm/skills/optional/xt-optional/senior-devops/scripts/pipeline_generator.py +114 -0
  476. package/.xtrm/skills/optional/xt-optional/senior-devops/scripts/terraform_scaffolder.py +114 -0
  477. package/.xtrm/skills/optional/xt-optional/senior-security/SKILL.md +209 -0
  478. package/.xtrm/skills/optional/xt-optional/senior-security/references/cryptography_implementation.md +103 -0
  479. package/.xtrm/skills/optional/xt-optional/senior-security/references/penetration_testing_guide.md +103 -0
  480. package/.xtrm/skills/optional/xt-optional/senior-security/references/security_architecture_patterns.md +103 -0
  481. package/.xtrm/skills/optional/xt-optional/senior-security/scripts/pentest_automator.py +114 -0
  482. package/.xtrm/skills/optional/xt-optional/senior-security/scripts/security_auditor.py +114 -0
  483. package/.xtrm/skills/optional/xt-optional/senior-security/scripts/threat_modeler.py +114 -0
  484. package/CHANGELOG.md +16 -0
  485. package/README.md +5 -0
  486. package/cli/dist/index.cjs +798 -612
  487. package/cli/dist/index.cjs.map +1 -1
  488. package/cli/package.json +1 -1
  489. package/package.json +3 -1
  490. package/.xtrm/extensions/auto-session-name/index.ts +0 -29
  491. package/.xtrm/extensions/auto-session-name/package.json +0 -16
  492. package/.xtrm/extensions/auto-update/index.ts +0 -71
  493. package/.xtrm/extensions/auto-update/package.json +0 -16
  494. package/.xtrm/extensions/beads/index.ts +0 -232
  495. package/.xtrm/extensions/beads/package.json +0 -19
  496. package/.xtrm/extensions/compact-header/index.ts +0 -69
  497. package/.xtrm/extensions/compact-header/package.json +0 -16
  498. package/.xtrm/extensions/core/adapter.ts +0 -52
  499. package/.xtrm/extensions/core/guard-rules.ts +0 -100
  500. package/.xtrm/extensions/core/lib.ts +0 -3
  501. package/.xtrm/extensions/core/logger.ts +0 -45
  502. package/.xtrm/extensions/core/package.json +0 -18
  503. package/.xtrm/extensions/core/runner.ts +0 -71
  504. package/.xtrm/extensions/core/session-state.ts +0 -59
  505. package/.xtrm/extensions/custom-footer/index.ts +0 -398
  506. package/.xtrm/extensions/custom-footer/package.json +0 -19
  507. package/.xtrm/extensions/custom-provider-qwen-cli/index.ts +0 -363
  508. package/.xtrm/extensions/custom-provider-qwen-cli/package.json +0 -1
  509. package/.xtrm/extensions/git-checkpoint/index.ts +0 -53
  510. package/.xtrm/extensions/git-checkpoint/package.json +0 -16
  511. package/.xtrm/extensions/lsp-bootstrap/index.ts +0 -134
  512. package/.xtrm/extensions/lsp-bootstrap/package.json +0 -17
  513. package/.xtrm/extensions/pi-serena-compact/index.ts +0 -121
  514. package/.xtrm/extensions/pi-serena-compact/package.json +0 -16
  515. package/.xtrm/extensions/quality-gates/index.ts +0 -66
  516. package/.xtrm/extensions/quality-gates/package.json +0 -19
  517. package/.xtrm/extensions/service-skills/index.ts +0 -108
  518. package/.xtrm/extensions/service-skills/package.json +0 -19
  519. package/.xtrm/extensions/session-flow/index.ts +0 -96
  520. package/.xtrm/extensions/session-flow/package.json +0 -19
  521. package/.xtrm/extensions/xtrm-loader/index.ts +0 -152
  522. package/.xtrm/extensions/xtrm-loader/package.json +0 -19
  523. package/.xtrm/extensions/xtrm-ui/format.ts +0 -93
  524. package/.xtrm/extensions/xtrm-ui/index.ts +0 -1053
  525. package/.xtrm/extensions/xtrm-ui/package.json +0 -10
  526. package/.xtrm/extensions/xtrm-ui/themes/pidex-dark.json +0 -85
  527. package/.xtrm/extensions/xtrm-ui/themes/pidex-light.json +0 -85
@@ -0,0 +1,641 @@
1
+ #!/usr/bin/env python3
2
+ """Run local search-quality evaluations across fixed topics.
3
+
4
+ This is an optional local gate, not a required CI job. It compares a baseline
5
+ revision against a candidate checkout, computes deterministic regression
6
+ metrics, and optionally calls Gemini as a judge for graded relevance labels.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import json
13
+ import math
14
+ import os
15
+ import shlex
16
+ import shutil
17
+ import subprocess
18
+ import sys
19
+ import tempfile
20
+ import textwrap
21
+ from datetime import datetime
22
+ from pathlib import Path
23
+ from typing import Any, Dict, Iterable, List, Optional, Tuple
24
+ from urllib.error import HTTPError, URLError
25
+ from urllib.request import Request, urlopen
26
+
27
+ sys.path.insert(0, str(Path(__file__).parent))
28
+
29
+ from lib import env as envlib
30
+
31
+
32
+ REPO_ROOT = Path(__file__).resolve().parent.parent
33
+ DEFAULT_TOPICS: List[Tuple[str, str]] = [
34
+ ("nano banana pro prompting", "product"),
35
+ ("codex vs claude code", "comparison"),
36
+ ("anthropic odds", "prediction"),
37
+ ("kanye west", "breaking_news"),
38
+ ("remotion animations for Claude Code", "how_to"),
39
+ ]
40
+ DEFAULT_SEARCH = "reddit,x,youtube,hn,polymarket"
41
+ SOURCE_KEYS = [
42
+ "reddit",
43
+ "x",
44
+ "youtube",
45
+ "tiktok",
46
+ "instagram",
47
+ "hackernews",
48
+ "bluesky",
49
+ "truthsocial",
50
+ "polymarket",
51
+ "websearch",
52
+ ]
53
+ DEFAULT_JUDGE_MODEL = "gemini-3-pro-preview"
54
+ GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent?key={api_key}"
55
+
56
+
57
+ def slugify(topic: str) -> str:
58
+ return "".join(c.lower() if c.isalnum() else "-" for c in topic).strip("-")
59
+
60
+
61
+ def path_without_node(path_value: str) -> str:
62
+ parts = []
63
+ for entry in path_value.split(os.pathsep):
64
+ if not entry:
65
+ continue
66
+ if (Path(entry) / "node").exists():
67
+ continue
68
+ parts.append(entry)
69
+ return os.pathsep.join(parts)
70
+
71
+
72
+ def write_exec_wrapper(path: Path, target: str, fixed_args: List[str]) -> None:
73
+ quoted_target = shlex.quote(target)
74
+ quoted_args = " ".join(shlex.quote(arg) for arg in fixed_args)
75
+ path.write_text(f"#!/bin/sh\nexec {quoted_target} {quoted_args} \"$@\"\n")
76
+ path.chmod(0o755)
77
+
78
+
79
+ def create_eval_tool_path(eval_home: Path, base_path: str) -> str:
80
+ """Create safe wrapper binaries for local evaluation subprocesses."""
81
+ bin_dir = eval_home / "bin"
82
+ bin_dir.mkdir(parents=True, exist_ok=True)
83
+
84
+ real_ytdlp = shutil.which("yt-dlp")
85
+ if real_ytdlp:
86
+ write_exec_wrapper(
87
+ bin_dir / "yt-dlp",
88
+ real_ytdlp,
89
+ ["--ignore-config", "--no-cookies-from-browser"],
90
+ )
91
+
92
+ if not base_path:
93
+ return str(bin_dir)
94
+ return os.pathsep.join([str(bin_dir), base_path])
95
+
96
+
97
+ def stable_item_key(source: str, item: Dict[str, Any]) -> str:
98
+ url = str(item.get("url") or "").strip()
99
+ if url:
100
+ return url
101
+ item_id = str(item.get("id") or "").strip()
102
+ text = item_text(source, item)
103
+ return f"{source}:{item_id}:{text[:120]}"
104
+
105
+
106
+ def item_text(source: str, item: Dict[str, Any]) -> str:
107
+ if source in {"x", "bluesky", "truthsocial"}:
108
+ return str(item.get("text") or "").strip()
109
+ if source == "polymarket":
110
+ return str(item.get("question") or item.get("title") or "").strip()
111
+ return str(item.get("title") or "").strip()
112
+
113
+
114
+ def build_ranked_items(report: Dict[str, Any], per_source_limit: int) -> List[Dict[str, Any]]:
115
+ ranked: List[Dict[str, Any]] = []
116
+ for source in SOURCE_KEYS:
117
+ items = list(report.get(source) or [])[:per_source_limit]
118
+ for item in items:
119
+ ranked.append({
120
+ "source": source,
121
+ "key": stable_item_key(source, item),
122
+ "url": str(item.get("url") or "").strip(),
123
+ "text": item_text(source, item),
124
+ "score": float(item.get("score") or 0),
125
+ "relevance": float(item.get("relevance") or 0),
126
+ "date": item.get("date"),
127
+ })
128
+ ranked.sort(key=lambda item: (-item["score"], item["source"], item["key"]))
129
+ return ranked
130
+
131
+
132
+ def url_sets_by_source(report: Dict[str, Any]) -> Dict[str, set[str]]:
133
+ result: Dict[str, set[str]] = {}
134
+ for source in SOURCE_KEYS:
135
+ items = report.get(source) or []
136
+ urls = {
137
+ stable_item_key(source, item)
138
+ for item in items
139
+ }
140
+ result[source] = urls
141
+ return result
142
+
143
+
144
+ def jaccard(left: Iterable[str], right: Iterable[str]) -> float:
145
+ left_set = set(left)
146
+ right_set = set(right)
147
+ if not left_set and not right_set:
148
+ return 1.0
149
+ union = left_set | right_set
150
+ if not union:
151
+ return 1.0
152
+ return len(left_set & right_set) / len(union)
153
+
154
+
155
+ def retention(left: Iterable[str], right: Iterable[str]) -> float:
156
+ left_set = set(left)
157
+ right_set = set(right)
158
+ if not left_set:
159
+ return 1.0
160
+ return len(left_set & right_set) / len(left_set)
161
+
162
+
163
+ def precision_at_k(ranking: List[Dict[str, Any]], judgments: Dict[str, int], k: int) -> float:
164
+ top = ranking[:k]
165
+ if not top:
166
+ return 0.0
167
+ hits = sum(1 for item in top if judgments.get(item["key"], 0) >= 2)
168
+ return hits / len(top)
169
+
170
+
171
+ def ndcg_at_k(
172
+ ranking: List[Dict[str, Any]],
173
+ judgments: Dict[str, int],
174
+ k: int,
175
+ judged_pool: Optional[List[Dict[str, Any]]] = None,
176
+ ) -> float:
177
+ top = ranking[:k]
178
+ if not top:
179
+ return 0.0
180
+
181
+ def dcg(grades: List[int]) -> float:
182
+ total = 0.0
183
+ for index, grade in enumerate(grades, start=1):
184
+ total += (2**grade - 1) / math.log2(index + 1)
185
+ return total
186
+
187
+ actual = [judgments.get(item["key"], 0) for item in top]
188
+ ideal_candidates = judged_pool or ranking
189
+ ideal = sorted(
190
+ (judgments.get(item["key"], 0) for item in ideal_candidates),
191
+ reverse=True,
192
+ )[:len(top)]
193
+ ideal_score = dcg(ideal)
194
+ if ideal_score == 0:
195
+ return 0.0
196
+ return dcg(actual) / ideal_score
197
+
198
+
199
+ def source_coverage_recall(
200
+ ranking: List[Dict[str, Any]],
201
+ judged_pool: List[Dict[str, Any]],
202
+ judgments: Dict[str, int],
203
+ ) -> float:
204
+ good_sources = {item["source"] for item in judged_pool if judgments.get(item["key"], 0) >= 2}
205
+ if not good_sources:
206
+ return 1.0
207
+ hit_sources = {
208
+ item["source"]
209
+ for item in ranking
210
+ if judgments.get(item["key"], 0) >= 2
211
+ }
212
+ return len(hit_sources & good_sources) / len(good_sources)
213
+
214
+
215
+ def create_eval_env(include_web: bool) -> Tuple[Dict[str, str], Path]:
216
+ config = envlib.get_config()
217
+ eval_home = Path(tempfile.mkdtemp(prefix="last30days-eval-home-"))
218
+ (eval_home / ".config").mkdir(parents=True, exist_ok=True)
219
+ safe_path = create_eval_tool_path(
220
+ eval_home,
221
+ path_without_node(os.environ.get("PATH", "")),
222
+ )
223
+ passthrough = {
224
+ "HOME": str(eval_home),
225
+ "XDG_CONFIG_HOME": str(eval_home / ".config"),
226
+ "PATH": safe_path,
227
+ "LANG": os.environ.get("LANG", "en_US.UTF-8"),
228
+ "LC_ALL": os.environ.get("LC_ALL", ""),
229
+ "TMPDIR": os.environ.get("TMPDIR", ""),
230
+ "PYTHONUTF8": "1",
231
+ "LAST30DAYS_CONFIG_DIR": "",
232
+ "BIRD_DISABLE_BROWSER_COOKIES": "1",
233
+ "LAST30DAYS_DISABLE_BROWSER_COOKIES": "1",
234
+ }
235
+ for key in ("OPENAI_API_KEY", "XAI_API_KEY", "SCRAPECREATORS_API_KEY"):
236
+ value = config.get(key)
237
+ if value:
238
+ passthrough[key] = value
239
+ if include_web:
240
+ for key in ("PARALLEL_API_KEY", "BRAVE_API_KEY", "OPENROUTER_API_KEY"):
241
+ value = config.get(key)
242
+ if value:
243
+ passthrough[key] = value
244
+ return passthrough, eval_home
245
+
246
+
247
+ def run_last30days(
248
+ repo_dir: Path,
249
+ topic: str,
250
+ *,
251
+ search: str,
252
+ timeout_seconds: int,
253
+ include_web: bool,
254
+ env: Dict[str, str],
255
+ ) -> Tuple[Dict[str, Any], str]:
256
+ cmd = [
257
+ sys.executable,
258
+ "scripts/last30days.py",
259
+ topic,
260
+ "--emit",
261
+ "json",
262
+ "--search",
263
+ search,
264
+ "--timeout",
265
+ str(timeout_seconds),
266
+ ]
267
+ if not include_web:
268
+ cmd.append("--no-native-web")
269
+ result = subprocess.run(
270
+ cmd,
271
+ cwd=repo_dir,
272
+ env=env,
273
+ capture_output=True,
274
+ text=True,
275
+ timeout=timeout_seconds + 30,
276
+ check=False,
277
+ )
278
+ if result.returncode != 0:
279
+ raise RuntimeError(
280
+ f"{repo_dir.name} failed for '{topic}' with exit {result.returncode}\n{result.stderr.strip()}"
281
+ )
282
+ return json.loads(result.stdout), result.stderr
283
+
284
+
285
+ def create_worktree(rev: str) -> Path:
286
+ worktree_dir = Path(tempfile.mkdtemp(prefix="last30days-eval-"))
287
+ subprocess.run(
288
+ ["git", "worktree", "add", "--detach", str(worktree_dir), rev],
289
+ cwd=REPO_ROOT,
290
+ check=True,
291
+ capture_output=True,
292
+ text=True,
293
+ )
294
+ return worktree_dir
295
+
296
+
297
+ def remove_worktree(path: Path) -> None:
298
+ subprocess.run(
299
+ ["git", "worktree", "remove", "--force", str(path)],
300
+ cwd=REPO_ROOT,
301
+ check=False,
302
+ capture_output=True,
303
+ text=True,
304
+ )
305
+ shutil.rmtree(path, ignore_errors=True)
306
+
307
+
308
+ def extract_gemini_text(payload: Dict[str, Any]) -> str:
309
+ for candidate in payload.get("candidates", []):
310
+ content = candidate.get("content") or {}
311
+ for part in content.get("parts", []):
312
+ text = part.get("text")
313
+ if text:
314
+ return text
315
+ raise ValueError("Gemini response did not contain text")
316
+
317
+
318
+ def resolve_google_judge_api_key(config: Dict[str, Any]) -> Optional[str]:
319
+ """Resolve the local canonical Google API key name.
320
+
321
+ This workspace conventionally uses GOOGLE_API_KEY. We also accept the
322
+ more Gemini-specific aliases for portability.
323
+ """
324
+ return (
325
+ os.environ.get("GOOGLE_API_KEY")
326
+ or config.get("GOOGLE_API_KEY")
327
+ or os.environ.get("GEMINI_API_KEY")
328
+ or config.get("GEMINI_API_KEY")
329
+ or os.environ.get("GOOGLE_GENAI_API_KEY")
330
+ or config.get("GOOGLE_GENAI_API_KEY")
331
+ )
332
+
333
+
334
+ def call_gemini_judge(api_key: str, model: str, prompt: str) -> Dict[str, Any]:
335
+ body = {
336
+ "contents": [{"parts": [{"text": prompt}]}],
337
+ "generationConfig": {
338
+ "temperature": 0,
339
+ "responseMimeType": "application/json",
340
+ },
341
+ }
342
+ url = GEMINI_API_URL.format(model=model, api_key=api_key)
343
+ request = Request(
344
+ url,
345
+ data=json.dumps(body).encode("utf-8"),
346
+ headers={"Content-Type": "application/json"},
347
+ method="POST",
348
+ )
349
+ try:
350
+ with urlopen(request, timeout=120) as response:
351
+ payload = json.loads(response.read().decode("utf-8"))
352
+ except HTTPError as exc:
353
+ detail = exc.read().decode("utf-8", errors="replace")
354
+ raise RuntimeError(f"Gemini HTTP {exc.code}: {detail}") from exc
355
+ except URLError as exc:
356
+ raise RuntimeError(f"Gemini request failed: {exc}") from exc
357
+ return json.loads(extract_gemini_text(payload))
358
+
359
+
360
+ def build_judge_prompt(
361
+ *,
362
+ topic: str,
363
+ query_type: str,
364
+ items: List[Dict[str, Any]],
365
+ ) -> str:
366
+ item_lines = []
367
+ for item in items:
368
+ item_lines.append(
369
+ "\n".join([
370
+ f"- id: {item['key']}",
371
+ f" source: {item['source']}",
372
+ f" title: {item['text'][:220]}",
373
+ f" url: {item['url']}",
374
+ f" date: {item.get('date') or 'unknown'}",
375
+ ])
376
+ )
377
+ joined = "\n".join(item_lines)
378
+ return textwrap.dedent(
379
+ f"""
380
+ Judge search-result relevance for a last-30-days research tool.
381
+
382
+ Topic: {topic}
383
+ Query type: {query_type}
384
+
385
+ Score each item on this 0-3 scale:
386
+ - 0 = off-topic or clearly bad
387
+ - 1 = weak or tangential
388
+ - 2 = relevant and useful
389
+ - 3 = highly relevant, one of the best results
390
+
391
+ Focus on actual user intent, not just token overlap. Penalize items that
392
+ only match generic words like "odds", "review", or "tips" without
393
+ matching the real entity or subject. Favor items that would genuinely
394
+ help answer the topic in the context of recent discussion.
395
+
396
+ Return strict JSON with this shape:
397
+ {{
398
+ "judgments": [
399
+ {{"id": "ITEM_ID", "grade": 0, "reason": "short reason"}}
400
+ ]
401
+ }}
402
+
403
+ Items:
404
+ {joined}
405
+ """
406
+ ).strip()
407
+
408
+
409
+ def get_judgments(
410
+ *,
411
+ output_dir: Path,
412
+ slug: str,
413
+ topic: str,
414
+ query_type: str,
415
+ items: List[Dict[str, Any]],
416
+ judge_model: str,
417
+ gemini_api_key: Optional[str],
418
+ ) -> Dict[str, int]:
419
+ cache_file = output_dir / "judgments" / f"{slug}.json"
420
+ cache_file.parent.mkdir(parents=True, exist_ok=True)
421
+ if cache_file.exists():
422
+ cached = json.loads(cache_file.read_text())
423
+ return {entry["id"]: int(entry["grade"]) for entry in cached.get("judgments", [])}
424
+
425
+ if not gemini_api_key:
426
+ return {}
427
+
428
+ prompt = build_judge_prompt(topic=topic, query_type=query_type, items=items)
429
+ payload = call_gemini_judge(gemini_api_key, judge_model, prompt)
430
+ cache_file.write_text(json.dumps(payload, indent=2))
431
+ return {entry["id"]: int(entry["grade"]) for entry in payload.get("judgments", [])}
432
+
433
+
434
+ def summarize_topic(
435
+ *,
436
+ topic: str,
437
+ query_type: str,
438
+ baseline_report: Dict[str, Any],
439
+ candidate_report: Dict[str, Any],
440
+ judged_pool: List[Dict[str, Any]],
441
+ judgments: Dict[str, int],
442
+ per_source_limit: int,
443
+ ) -> Dict[str, Any]:
444
+ baseline_ranked = build_ranked_items(baseline_report, per_source_limit)
445
+ candidate_ranked = build_ranked_items(candidate_report, per_source_limit)
446
+
447
+ baseline_sets = url_sets_by_source(baseline_report)
448
+ candidate_sets = url_sets_by_source(candidate_report)
449
+
450
+ metrics = {
451
+ "topic": topic,
452
+ "query_type": query_type,
453
+ "baseline": {
454
+ "precision_at_5": precision_at_k(baseline_ranked, judgments, 5),
455
+ "ndcg_at_5": ndcg_at_k(baseline_ranked, judgments, 5, judged_pool),
456
+ "source_coverage_recall": source_coverage_recall(baseline_ranked, judged_pool, judgments),
457
+ },
458
+ "candidate": {
459
+ "precision_at_5": precision_at_k(candidate_ranked, judgments, 5),
460
+ "ndcg_at_5": ndcg_at_k(candidate_ranked, judgments, 5, judged_pool),
461
+ "source_coverage_recall": source_coverage_recall(candidate_ranked, judged_pool, judgments),
462
+ },
463
+ "stability": {
464
+ "overall_jaccard": jaccard(
465
+ set().union(*baseline_sets.values()),
466
+ set().union(*candidate_sets.values()),
467
+ ),
468
+ "overall_retention_vs_baseline": retention(
469
+ set().union(*baseline_sets.values()),
470
+ set().union(*candidate_sets.values()),
471
+ ),
472
+ "per_source": {
473
+ source: {
474
+ "baseline_count": len(baseline_sets[source]),
475
+ "candidate_count": len(candidate_sets[source]),
476
+ "jaccard": jaccard(baseline_sets[source], candidate_sets[source]),
477
+ "retention_vs_baseline": retention(baseline_sets[source], candidate_sets[source]),
478
+ }
479
+ for source in SOURCE_KEYS
480
+ },
481
+ },
482
+ }
483
+ return metrics
484
+
485
+
486
+ def write_markdown_summary(
487
+ output_dir: Path,
488
+ baseline_label: str,
489
+ candidate_label: str,
490
+ topic_summaries: List[Dict[str, Any]],
491
+ ) -> None:
492
+ lines = [
493
+ f"# Search Quality Evaluation",
494
+ "",
495
+ f"- Baseline: `{baseline_label}`",
496
+ f"- Candidate: `{candidate_label}`",
497
+ f"- Generated: {datetime.now().isoformat(timespec='seconds')}",
498
+ "",
499
+ "## Topic Metrics",
500
+ "",
501
+ "| Topic | Base P@5 | Cand P@5 | Base nDCG@5 | Cand nDCG@5 | Jaccard | Retention |",
502
+ "|---|---:|---:|---:|---:|---:|---:|",
503
+ ]
504
+ for summary in topic_summaries:
505
+ lines.append(
506
+ "| {topic} | {bp:.2f} | {cp:.2f} | {bn:.2f} | {cn:.2f} | {jac:.2f} | {ret:.2f} |".format(
507
+ topic=summary["topic"],
508
+ bp=summary["baseline"]["precision_at_5"],
509
+ cp=summary["candidate"]["precision_at_5"],
510
+ bn=summary["baseline"]["ndcg_at_5"],
511
+ cn=summary["candidate"]["ndcg_at_5"],
512
+ jac=summary["stability"]["overall_jaccard"],
513
+ ret=summary["stability"]["overall_retention_vs_baseline"],
514
+ )
515
+ )
516
+ lines.append("")
517
+ lines.append("## Notes")
518
+ lines.append("")
519
+ lines.append("- `Precision@5` and `nDCG@5` depend on the judged union pool, not a full gold corpus.")
520
+ lines.append("- `Source coverage recall` measures whether a run surfaced at least one judged-good result from the good sources in the judged pool.")
521
+ lines.append("- `Jaccard` and `retention` are stability guards against baseline drift, not truth metrics.")
522
+ (output_dir / "summary.md").write_text("\n".join(lines))
523
+
524
+
525
+ def parse_args() -> argparse.Namespace:
526
+ parser = argparse.ArgumentParser(description="Evaluate last30days search quality locally")
527
+ parser.add_argument("--baseline-rev", default="origin/main", help="Git revision for the baseline run")
528
+ parser.add_argument("--candidate-rev", default=None, help="Optional git revision for the candidate run")
529
+ parser.add_argument("--no-default-topics", action="store_true", help="Do not include the built-in 5-topic suite")
530
+ parser.add_argument("--topic", action="append", default=[], help="Extra topic to evaluate (repeatable)")
531
+ parser.add_argument("--search", default=DEFAULT_SEARCH, help="Comma-separated sources passed to --search")
532
+ parser.add_argument("--timeout", type=int, default=180, help="Per-topic timeout passed to last30days")
533
+ parser.add_argument("--per-source-limit", type=int, default=5, help="Items per source to judge")
534
+ parser.add_argument("--include-web", action="store_true", help="Include web-search keys and native web backends")
535
+ parser.add_argument("--judge-model", default=None, help="Gemini judge model override")
536
+ parser.add_argument("--judge-provider", choices=["auto", "gemini", "none"], default="auto")
537
+ parser.add_argument("--keep-worktrees", action="store_true", help="Leave temporary baseline/candidate worktrees on disk")
538
+ parser.add_argument("--output-dir", default=None, help="Output directory (default: docs/test-results/search-quality-<timestamp>)")
539
+ return parser.parse_args()
540
+
541
+
542
+ def main() -> int:
543
+ args = parse_args()
544
+ timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
545
+ output_dir = Path(args.output_dir) if args.output_dir else REPO_ROOT / "docs" / "test-results" / f"search-quality-{timestamp}"
546
+ output_dir.mkdir(parents=True, exist_ok=True)
547
+
548
+ topics = [] if args.no_default_topics else list(DEFAULT_TOPICS)
549
+ topics.extend((topic, "custom") for topic in args.topic)
550
+ if not topics:
551
+ raise SystemExit("No topics configured. Use the default suite or pass --topic.")
552
+
553
+ judge_config = envlib.get_config()
554
+ judge_provider = args.judge_provider
555
+ gemini_api_key = resolve_google_judge_api_key(judge_config)
556
+ judge_model = args.judge_model or judge_config.get("GEMINI_MODEL") or DEFAULT_JUDGE_MODEL
557
+ if judge_provider == "auto":
558
+ judge_provider = "gemini" if gemini_api_key else "none"
559
+ if judge_provider == "none":
560
+ gemini_api_key = None
561
+
562
+ eval_env, eval_home = create_eval_env(include_web=args.include_web)
563
+ baseline_dir = create_worktree(args.baseline_rev)
564
+ candidate_dir = create_worktree(args.candidate_rev) if args.candidate_rev else REPO_ROOT
565
+
566
+ baseline_label = args.baseline_rev
567
+ candidate_label = args.candidate_rev or "working-tree"
568
+ topic_summaries: List[Dict[str, Any]] = []
569
+
570
+ try:
571
+ for topic, query_type in topics:
572
+ slug = slugify(topic)
573
+ baseline_report, baseline_stderr = run_last30days(
574
+ baseline_dir,
575
+ topic,
576
+ search=args.search,
577
+ timeout_seconds=args.timeout,
578
+ include_web=args.include_web,
579
+ env=eval_env,
580
+ )
581
+ candidate_report, candidate_stderr = run_last30days(
582
+ candidate_dir,
583
+ topic,
584
+ search=args.search,
585
+ timeout_seconds=args.timeout,
586
+ include_web=args.include_web,
587
+ env=eval_env,
588
+ )
589
+
590
+ topic_dir = output_dir / slug
591
+ topic_dir.mkdir(parents=True, exist_ok=True)
592
+ (topic_dir / "baseline.json").write_text(json.dumps(baseline_report, indent=2))
593
+ (topic_dir / "candidate.json").write_text(json.dumps(candidate_report, indent=2))
594
+ (topic_dir / "baseline.stderr.txt").write_text(baseline_stderr)
595
+ (topic_dir / "candidate.stderr.txt").write_text(candidate_stderr)
596
+
597
+ baseline_ranked = build_ranked_items(baseline_report, args.per_source_limit)
598
+ candidate_ranked = build_ranked_items(candidate_report, args.per_source_limit)
599
+ union_map = {item["key"]: item for item in baseline_ranked + candidate_ranked}
600
+ judgments = get_judgments(
601
+ output_dir=output_dir,
602
+ slug=slug,
603
+ topic=topic,
604
+ query_type=query_type,
605
+ items=list(union_map.values()),
606
+ judge_model=judge_model,
607
+ gemini_api_key=gemini_api_key,
608
+ )
609
+
610
+ summary = summarize_topic(
611
+ topic=topic,
612
+ query_type=query_type,
613
+ baseline_report=baseline_report,
614
+ candidate_report=candidate_report,
615
+ judged_pool=list(union_map.values()),
616
+ judgments=judgments,
617
+ per_source_limit=args.per_source_limit,
618
+ )
619
+ topic_summaries.append(summary)
620
+
621
+ payload = {
622
+ "baseline": baseline_label,
623
+ "candidate": candidate_label,
624
+ "judge_provider": judge_provider,
625
+ "judge_model": judge_model if gemini_api_key else None,
626
+ "topics": topic_summaries,
627
+ }
628
+ (output_dir / "summary.json").write_text(json.dumps(payload, indent=2))
629
+ write_markdown_summary(output_dir, baseline_label, candidate_label, topic_summaries)
630
+ print(output_dir)
631
+ return 0
632
+ finally:
633
+ if not args.keep_worktrees:
634
+ remove_worktree(baseline_dir)
635
+ if args.candidate_rev:
636
+ remove_worktree(candidate_dir)
637
+ shutil.rmtree(eval_home, ignore_errors=True)
638
+
639
+
640
+ if __name__ == "__main__":
641
+ raise SystemExit(main())
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env python3
2
+ """Convert JSON result files to compact markdown using render_compact().
3
+
4
+ Reads from docs/comparison-results/json/, writes to docs/comparison-results/compact/.
5
+ Uses the current checkout's render_compact() - since version differences are in the
6
+ DATA (cross_refs, HN items, YouTube relevance), not in the render function.
7
+ """
8
+ import json
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ # Add scripts/ to path so we can import lib
13
+ sys.path.insert(0, str(Path(__file__).parent))
14
+
15
+ from lib.schema import Report
16
+ from lib.render import render_compact, render_source_status
17
+
18
+ JSON_DIR = Path(__file__).parent.parent / "docs" / "comparison-results" / "json"
19
+ COMPACT_DIR = Path(__file__).parent.parent / "docs" / "comparison-results" / "compact"
20
+ COMPACT_DIR.mkdir(parents=True, exist_ok=True)
21
+
22
+ files = sorted(JSON_DIR.glob("*.json"))
23
+ files = [f for f in files if f.name != "diagnose-baseline.json"]
24
+
25
+ print(f"Converting {len(files)} JSON files to compact markdown...\n")
26
+
27
+ for json_file in files:
28
+ with open(json_file) as f:
29
+ data = json.load(f)
30
+
31
+ report = Report.from_dict(data)
32
+ compact = render_compact(report)
33
+ source_status = render_source_status(report)
34
+ full_output = compact + "\n" + source_status
35
+
36
+ md_file = COMPACT_DIR / json_file.name.replace(".json", ".md")
37
+ md_file.write_text(full_output)
38
+
39
+ # Summary stats
40
+ n_reddit = len(report.reddit)
41
+ n_x = len(report.x)
42
+ n_yt = len(report.youtube)
43
+ n_hn = len(report.hackernews)
44
+ n_web = len(report.web)
45
+ xrefs = sum(1 for r in report.reddit if r.cross_refs)
46
+ xrefs += sum(1 for x in report.x if x.cross_refs)
47
+ xrefs += sum(1 for y in report.youtube if y.cross_refs)
48
+ xrefs += sum(1 for h in report.hackernews if h.cross_refs)
49
+
50
+ print(f" {json_file.name:40s} -> {len(full_output):5d} chars "
51
+ f"(R:{n_reddit} X:{n_x} YT:{n_yt} HN:{n_hn} W:{n_web} xref:{xrefs})")
52
+
53
+ print(f"\nDone. {len(files)} compact files written to {COMPACT_DIR}")