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,807 @@
1
+ """Environment and API key management for last30days skill."""
2
+
3
+ import base64
4
+ import json
5
+ import logging
6
+ import os
7
+ import time
8
+ from dataclasses import dataclass
9
+ from pathlib import Path
10
+ from typing import Optional, Dict, Any, List, Literal
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ # ---------------------------------------------------------------------------
15
+ # Cookie domain registry: maps source names to browser cookie extraction params.
16
+ # Each entry: (domain, cookie_names, config_key_mapping)
17
+ # config_key_mapping: {cookie_name: config_key} so we know which config key
18
+ # each extracted cookie should populate.
19
+ # ---------------------------------------------------------------------------
20
+ COOKIE_DOMAINS: Dict[str, Dict[str, Any]] = {
21
+ "x": {
22
+ "domain": ".x.com",
23
+ "cookies": ["auth_token", "ct0"],
24
+ "mapping": {
25
+ "auth_token": "AUTH_TOKEN",
26
+ "ct0": "CT0",
27
+ },
28
+ },
29
+ "truthsocial": {
30
+ "domain": ".truthsocial.com",
31
+ "cookies": ["_session_id"],
32
+ "mapping": {
33
+ "_session_id": "TRUTHSOCIAL_TOKEN",
34
+ },
35
+ },
36
+ }
37
+
38
+ # Allow override via environment variable for testing
39
+ # Set LAST30DAYS_CONFIG_DIR="" for clean/no-config mode
40
+ # Set LAST30DAYS_CONFIG_DIR="/path/to/dir" for custom config location
41
+ _config_override = os.environ.get('LAST30DAYS_CONFIG_DIR')
42
+ if _config_override == "":
43
+ # Empty string = no config file (clean mode)
44
+ CONFIG_DIR = None
45
+ CONFIG_FILE = None
46
+ elif _config_override:
47
+ CONFIG_DIR = Path(_config_override)
48
+ CONFIG_FILE = CONFIG_DIR / ".env"
49
+ else:
50
+ CONFIG_DIR = Path.home() / ".config" / "last30days"
51
+ CONFIG_FILE = CONFIG_DIR / ".env"
52
+
53
+ CODEX_AUTH_FILE = Path(os.environ.get("CODEX_AUTH_FILE", str(Path.home() / ".codex" / "auth.json")))
54
+
55
+ AuthSource = Literal["api_key", "codex", "none"]
56
+ AuthStatus = Literal["ok", "missing", "expired", "missing_account_id"]
57
+
58
+ AUTH_SOURCE_API_KEY: AuthSource = "api_key"
59
+ AUTH_SOURCE_CODEX: AuthSource = "codex"
60
+ AUTH_SOURCE_NONE: AuthSource = "none"
61
+
62
+ AUTH_STATUS_OK: AuthStatus = "ok"
63
+ AUTH_STATUS_MISSING: AuthStatus = "missing"
64
+ AUTH_STATUS_EXPIRED: AuthStatus = "expired"
65
+ AUTH_STATUS_MISSING_ACCOUNT_ID: AuthStatus = "missing_account_id"
66
+
67
+
68
+ @dataclass(frozen=True)
69
+ class OpenAIAuth:
70
+ token: Optional[str]
71
+ source: AuthSource
72
+ status: AuthStatus
73
+ account_id: Optional[str]
74
+ codex_auth_file: str
75
+
76
+
77
+ def _check_file_permissions(path: Path) -> None:
78
+ """Warn to stderr if a secrets file has overly permissive permissions."""
79
+ try:
80
+ mode = path.stat().st_mode
81
+ # Check if group or other can read (bits 0o044)
82
+ if mode & 0o044:
83
+ import sys
84
+ sys.stderr.write(
85
+ f"[last30days] WARNING: {path} is readable by other users. "
86
+ f"Run: chmod 600 {path}\n"
87
+ )
88
+ sys.stderr.flush()
89
+ except OSError:
90
+ pass
91
+
92
+
93
+ def load_env_file(path: Path) -> Dict[str, str]:
94
+ """Load environment variables from a file."""
95
+ env = {}
96
+ if not path or not path.exists():
97
+ return env
98
+ _check_file_permissions(path)
99
+
100
+ with open(path, 'r') as f:
101
+ for line in f:
102
+ line = line.strip()
103
+ if not line or line.startswith('#'):
104
+ continue
105
+ if '=' in line:
106
+ key, _, value = line.partition('=')
107
+ key = key.strip()
108
+ value = value.strip()
109
+ # Remove quotes if present
110
+ if value and value[0] in ('"', "'") and value[-1] == value[0]:
111
+ value = value[1:-1]
112
+ if key and value:
113
+ env[key] = value
114
+ return env
115
+
116
+
117
+ def _decode_jwt_payload(token: str) -> Optional[Dict[str, Any]]:
118
+ """Decode JWT payload without verification."""
119
+ try:
120
+ parts = token.split(".")
121
+ if len(parts) < 2:
122
+ return None
123
+ payload_b64 = parts[1]
124
+ pad = "=" * (-len(payload_b64) % 4)
125
+ decoded = base64.urlsafe_b64decode(payload_b64 + pad)
126
+ return json.loads(decoded.decode("utf-8"))
127
+ except Exception:
128
+ return None
129
+
130
+
131
+ def _token_expired(token: str, leeway_seconds: int = 60) -> bool:
132
+ """Check if JWT token is expired."""
133
+ payload = _decode_jwt_payload(token)
134
+ if not payload:
135
+ return False
136
+ exp = payload.get("exp")
137
+ if not exp:
138
+ return False
139
+ return exp <= (time.time() + leeway_seconds)
140
+
141
+
142
+ def extract_chatgpt_account_id(access_token: str) -> Optional[str]:
143
+ """Extract chatgpt_account_id from JWT token."""
144
+ payload = _decode_jwt_payload(access_token)
145
+ if not payload:
146
+ return None
147
+ auth_claim = payload.get("https://api.openai.com/auth", {})
148
+ if isinstance(auth_claim, dict):
149
+ return auth_claim.get("chatgpt_account_id")
150
+ return None
151
+
152
+
153
+ def load_codex_auth(path: Path = CODEX_AUTH_FILE) -> Dict[str, Any]:
154
+ """Load Codex auth JSON."""
155
+ if not path.exists():
156
+ return {}
157
+ try:
158
+ with open(path, "r") as f:
159
+ return json.load(f)
160
+ except Exception:
161
+ return {}
162
+
163
+
164
+ def get_codex_access_token() -> tuple[Optional[str], str]:
165
+ """Get Codex access token from auth.json.
166
+
167
+ Returns:
168
+ (token, status) where status is 'ok', 'missing', or 'expired'
169
+ """
170
+ auth = load_codex_auth()
171
+ token = None
172
+ if isinstance(auth, dict):
173
+ tokens = auth.get("tokens") or {}
174
+ if isinstance(tokens, dict):
175
+ token = tokens.get("access_token")
176
+ if not token:
177
+ token = auth.get("access_token")
178
+ if not token:
179
+ return None, AUTH_STATUS_MISSING
180
+ if _token_expired(token):
181
+ return None, AUTH_STATUS_EXPIRED
182
+ return token, AUTH_STATUS_OK
183
+
184
+
185
+ def get_openai_auth(file_env: Dict[str, str]) -> OpenAIAuth:
186
+ """Resolve OpenAI auth from API key or Codex login."""
187
+ api_key = os.environ.get('OPENAI_API_KEY') or file_env.get('OPENAI_API_KEY')
188
+ if api_key:
189
+ return OpenAIAuth(
190
+ token=api_key,
191
+ source=AUTH_SOURCE_API_KEY,
192
+ status=AUTH_STATUS_OK,
193
+ account_id=None,
194
+ codex_auth_file=str(CODEX_AUTH_FILE),
195
+ )
196
+
197
+ codex_token, codex_status = get_codex_access_token()
198
+ if codex_token:
199
+ account_id = extract_chatgpt_account_id(codex_token)
200
+ if account_id:
201
+ return OpenAIAuth(
202
+ token=codex_token,
203
+ source=AUTH_SOURCE_CODEX,
204
+ status=AUTH_STATUS_OK,
205
+ account_id=account_id,
206
+ codex_auth_file=str(CODEX_AUTH_FILE),
207
+ )
208
+ return OpenAIAuth(
209
+ token=None,
210
+ source=AUTH_SOURCE_CODEX,
211
+ status=AUTH_STATUS_MISSING_ACCOUNT_ID,
212
+ account_id=None,
213
+ codex_auth_file=str(CODEX_AUTH_FILE),
214
+ )
215
+
216
+ return OpenAIAuth(
217
+ token=None,
218
+ source=AUTH_SOURCE_NONE,
219
+ status=codex_status,
220
+ account_id=None,
221
+ codex_auth_file=str(CODEX_AUTH_FILE),
222
+ )
223
+
224
+
225
+ def _find_project_env() -> Optional[Path]:
226
+ """Find per-project .env by walking up from cwd.
227
+
228
+ Searches for .claude/last30days.env in each parent directory,
229
+ stopping at the user's home directory or filesystem root.
230
+ """
231
+ cwd = Path.cwd()
232
+ for parent in [cwd, *cwd.parents]:
233
+ candidate = parent / '.claude' / 'last30days.env'
234
+ if candidate.exists():
235
+ return candidate
236
+ # Stop at filesystem root or home
237
+ if parent == Path.home() or parent == parent.parent:
238
+ break
239
+ return None
240
+
241
+
242
+ def extract_browser_credentials(config: Dict[str, Any]) -> Dict[str, str]:
243
+ """Extract credentials from browser cookies for sources that need them.
244
+
245
+ Checks the FROM_BROWSER config key to decide whether/how to extract:
246
+ - 'auto': try browsers in platform order
247
+ - 'firefox', 'chrome', 'safari': try only that browser
248
+ - 'off': skip extraction entirely
249
+
250
+ If SETUP_COMPLETE is not set AND FROM_BROWSER is not explicitly set,
251
+ defaults to 'off' (wizard hasn't run yet — no extraction without consent).
252
+ If SETUP_COMPLETE is set and FROM_BROWSER is not set, defaults to 'auto'.
253
+
254
+ Explicit env var/config values always take priority over extracted cookies.
255
+
256
+ Returns:
257
+ Dict of {config_key: value} for credentials discovered from cookies.
258
+ """
259
+ setup_complete = config.get("SETUP_COMPLETE")
260
+ from_browser = config.get("FROM_BROWSER")
261
+
262
+ # Determine effective browser setting
263
+ if from_browser is None:
264
+ if setup_complete:
265
+ from_browser = "auto"
266
+ else:
267
+ from_browser = "off"
268
+
269
+ from_browser = from_browser.lower().strip() if isinstance(from_browser, str) else "off"
270
+
271
+ if from_browser == "off":
272
+ return {}
273
+
274
+ # Lazy import to avoid loading cookie_extract at module level
275
+ try:
276
+ from . import cookie_extract
277
+ except Exception:
278
+ logger.debug("cookie_extract module not available")
279
+ return {}
280
+
281
+ credentials: Dict[str, str] = {}
282
+
283
+ for source_name, spec in COOKIE_DOMAINS.items():
284
+ domain = spec["domain"]
285
+ cookie_names: List[str] = spec["cookies"]
286
+ mapping: Dict[str, str] = spec["mapping"]
287
+
288
+ # Skip if ALL mapped config keys already have values
289
+ all_present = all(config.get(config_key) for config_key in mapping.values())
290
+ if all_present:
291
+ logger.debug(
292
+ "Skipping cookie extraction for %s: credentials already set",
293
+ source_name,
294
+ )
295
+ continue
296
+
297
+ try:
298
+ result = cookie_extract.extract_cookies_with_source(from_browser, domain, cookie_names)
299
+ except Exception as exc:
300
+ logger.debug(
301
+ "Cookie extraction failed for %s: %s", source_name, exc
302
+ )
303
+ continue
304
+
305
+ if result is None:
306
+ continue
307
+
308
+ cookies, browser_name = result
309
+ filled_any = False
310
+ for cookie_name, config_key in mapping.items():
311
+ # Only fill in keys not already present
312
+ if not config.get(config_key) and cookie_name in cookies:
313
+ credentials[config_key] = cookies[cookie_name]
314
+ filled_any = True
315
+
316
+ # Track which browser provided the credentials for this source
317
+ if filled_any:
318
+ credentials[f"__{source_name.upper()}_BROWSER"] = browser_name
319
+
320
+ return credentials
321
+
322
+
323
+ def get_config() -> Dict[str, Any]:
324
+ """Load configuration from multiple sources.
325
+
326
+ Priority (highest wins):
327
+ 1. Environment variables (os.environ)
328
+ 2. .claude/last30days.env (per-project config)
329
+ 3. ~/.config/last30days/.env (global config)
330
+ 4. Browser cookies (only fills in missing keys)
331
+ """
332
+ # Load from global config file
333
+ file_env = load_env_file(CONFIG_FILE) if CONFIG_FILE else {}
334
+
335
+ # Load from per-project config (overrides global)
336
+ project_env_path = _find_project_env()
337
+ project_env = load_env_file(project_env_path) if project_env_path else {}
338
+
339
+ # Merge: project overrides global
340
+ merged_env = {**file_env, **project_env}
341
+
342
+ openai_auth = get_openai_auth(merged_env)
343
+
344
+ # Build config: Codex/OpenAI auth + process.env > project .env > global .env
345
+ config = {
346
+ 'OPENAI_API_KEY': openai_auth.token,
347
+ 'OPENAI_AUTH_SOURCE': openai_auth.source,
348
+ 'OPENAI_AUTH_STATUS': openai_auth.status,
349
+ 'OPENAI_CHATGPT_ACCOUNT_ID': openai_auth.account_id,
350
+ 'CODEX_AUTH_FILE': openai_auth.codex_auth_file,
351
+ }
352
+
353
+ keys = [
354
+ ('XAI_API_KEY', None),
355
+ ('GOOGLE_API_KEY', None),
356
+ ('GEMINI_API_KEY', None),
357
+ ('GOOGLE_GENAI_API_KEY', None),
358
+ ('OPENROUTER_API_KEY', None),
359
+ ('PARALLEL_API_KEY', None),
360
+ ('BRAVE_API_KEY', None),
361
+ ('EXA_API_KEY', None),
362
+ ('XIAOHONGSHU_API_BASE', None),
363
+ ('GEMINI_MODEL', None),
364
+ ('OPENAI_MODEL_POLICY', 'auto'),
365
+ ('OPENAI_MODEL_PIN', None),
366
+ ('XAI_MODEL_POLICY', 'latest'),
367
+ ('XAI_MODEL_PIN', None),
368
+ ('SCRAPECREATORS_API_KEY', None),
369
+ ('APIFY_API_TOKEN', None),
370
+ ('AUTH_TOKEN', None),
371
+ ('CT0', None),
372
+ ('BSKY_HANDLE', None),
373
+ ('BSKY_APP_PASSWORD', None),
374
+ ('TRUTHSOCIAL_TOKEN', None),
375
+ ('FROM_BROWSER', None),
376
+ ('SETUP_COMPLETE', None),
377
+ ('INCLUDE_SOURCES', None),
378
+ ]
379
+
380
+ for key, default in keys:
381
+ config[key] = os.environ.get(key) or merged_env.get(key, default)
382
+
383
+ # Inject browser cookies for any credentials not already set
384
+ browser_creds = extract_browser_credentials(config)
385
+ for key, value in browser_creds.items():
386
+ if not config.get(key):
387
+ config[key] = value
388
+
389
+ # Track AUTH_TOKEN source for status reporting
390
+ if config.get('AUTH_TOKEN'):
391
+ if os.environ.get('AUTH_TOKEN') or merged_env.get('AUTH_TOKEN'):
392
+ config['_AUTH_TOKEN_SOURCE'] = 'env'
393
+ elif browser_creds.get('AUTH_TOKEN'):
394
+ browser_name = browser_creds.get('__X_BROWSER', 'unknown')
395
+ config['_AUTH_TOKEN_SOURCE'] = f'browser-{browser_name}'
396
+ else:
397
+ config['_AUTH_TOKEN_SOURCE'] = 'env' # fallback
398
+ else:
399
+ config['_AUTH_TOKEN_SOURCE'] = None
400
+
401
+ # Track which config source was used
402
+ if project_env_path:
403
+ config['_CONFIG_SOURCE'] = f'project:{project_env_path}'
404
+ elif CONFIG_FILE and CONFIG_FILE.exists():
405
+ config['_CONFIG_SOURCE'] = f'global:{CONFIG_FILE}'
406
+ else:
407
+ config['_CONFIG_SOURCE'] = 'env_only'
408
+
409
+ return config
410
+
411
+
412
+ def config_exists() -> bool:
413
+ """Check if any configuration source exists."""
414
+ if _find_project_env():
415
+ return True
416
+ if CONFIG_FILE:
417
+ return CONFIG_FILE.exists()
418
+ return False
419
+
420
+
421
+ def is_reddit_available(config: Dict[str, Any]) -> bool:
422
+ """Check if Reddit search is available.
423
+
424
+ Reddit can use either ScrapeCreators (preferred) or OpenAI.
425
+ """
426
+ has_sc = bool(config.get('SCRAPECREATORS_API_KEY'))
427
+ has_openai = bool(config.get('OPENAI_API_KEY')) and config.get('OPENAI_AUTH_STATUS') == AUTH_STATUS_OK
428
+ return has_sc or has_openai
429
+
430
+
431
+ def get_reddit_source(config: Dict[str, Any]) -> Optional[str]:
432
+ """Determine which Reddit backend to use.
433
+
434
+ Priority: ScrapeCreators (cheaper, faster) > OpenAI (legacy)
435
+
436
+ Returns: 'scrapecreators', 'openai', or None
437
+ """
438
+ if config.get('SCRAPECREATORS_API_KEY'):
439
+ return 'scrapecreators'
440
+ if config.get('OPENAI_API_KEY') and config.get('OPENAI_AUTH_STATUS') == AUTH_STATUS_OK:
441
+ return 'openai'
442
+ return None
443
+
444
+
445
+ def get_available_sources(config: Dict[str, Any]) -> str:
446
+ """Determine which sources are available.
447
+
448
+ X is available if ANY auth method works: AUTH_TOKEN/CT0 (env or cookies),
449
+ XAI_API_KEY, or Bird installed+authenticated.
450
+ Reddit is always available (public JSON fallback).
451
+ HN and Polymarket are always available.
452
+ YouTube available if yt-dlp installed.
453
+
454
+ Returns: 'all', 'both', 'reddit', 'reddit-web', 'x', 'x-web', 'web', or 'none'
455
+ """
456
+ has_reddit = True
457
+ has_x = get_x_source(config) is not None
458
+ has_web = has_web_search_keys(config)
459
+
460
+ if has_reddit and has_x:
461
+ return 'all' if has_web else 'both'
462
+ elif has_reddit:
463
+ return 'reddit-web' if has_web else 'reddit'
464
+ return 'web' if has_web else 'none'
465
+
466
+
467
+ def has_web_search_keys(config: Dict[str, Any]) -> bool:
468
+ """Check if any web search API keys are configured."""
469
+ return bool(config.get('EXA_API_KEY') or config.get('OPENROUTER_API_KEY') or config.get('PARALLEL_API_KEY') or config.get('BRAVE_API_KEY'))
470
+
471
+
472
+ def get_web_search_source(config: Dict[str, Any]) -> Optional[str]:
473
+ """Determine the best available web search backend.
474
+
475
+ Priority: Exa (free) > Parallel AI > Brave > OpenRouter/Sonar Pro
476
+
477
+ Returns: 'exa', 'parallel', 'brave', 'openrouter', or None
478
+ """
479
+ if config.get('EXA_API_KEY'):
480
+ return 'exa'
481
+ if config.get('PARALLEL_API_KEY'):
482
+ return 'parallel'
483
+ if config.get('BRAVE_API_KEY'):
484
+ return 'brave'
485
+ if config.get('OPENROUTER_API_KEY'):
486
+ return 'openrouter'
487
+ return None
488
+
489
+
490
+ def get_missing_keys(config: Dict[str, Any]) -> str:
491
+ """Determine which sources are missing (accounting for Bird).
492
+
493
+ Returns: 'all', 'both', 'reddit', 'x', 'web', or 'none'
494
+ """
495
+ has_reddit = True
496
+ has_xai = bool(config.get('XAI_API_KEY'))
497
+ has_web = has_web_search_keys(config)
498
+
499
+ # Check if Bird provides X access (import here to avoid circular dependency)
500
+ from . import bird_x
501
+ has_bird = bird_x.is_bird_installed() and bird_x.is_bird_authenticated()
502
+
503
+ has_x = has_xai or has_bird
504
+
505
+ if has_reddit and has_x and has_web:
506
+ return 'none'
507
+ elif has_reddit and has_x:
508
+ return 'web' # Missing web search keys
509
+ elif has_reddit and has_web:
510
+ return 'x' # Missing X source
511
+ elif has_reddit:
512
+ return 'x' # Missing X source (and possibly web)
513
+ return 'all'
514
+
515
+
516
+ def validate_sources(requested: str, available: str, include_web: bool = False) -> tuple[str, Optional[str]]:
517
+ """Validate requested sources against available keys.
518
+
519
+ Args:
520
+ requested: 'auto', 'reddit', 'x', 'both', or 'web'
521
+ available: Result from get_available_sources()
522
+ include_web: If True, add WebSearch to available sources
523
+
524
+ Returns:
525
+ Tuple of (effective_sources, error_message)
526
+ """
527
+ has_reddit = available in ('reddit', 'both', 'reddit-web', 'all')
528
+ has_x = available in ('x', 'both', 'x-web', 'all')
529
+ has_web = available in ('web', 'reddit-web', 'x-web', 'all')
530
+
531
+ if requested == 'auto':
532
+ if has_reddit and has_x:
533
+ base = 'both'
534
+ elif has_reddit:
535
+ base = 'reddit'
536
+ elif has_x:
537
+ base = 'x'
538
+ elif has_web:
539
+ base = 'web'
540
+ else:
541
+ return 'none', "No sources are available."
542
+
543
+ if include_web:
544
+ if base == 'both':
545
+ return 'all', None
546
+ if base == 'reddit':
547
+ return 'reddit-web', None
548
+ if base == 'x':
549
+ return 'x-web', None
550
+ return base, None
551
+
552
+ if requested == 'web':
553
+ return 'web', None
554
+
555
+ if requested == 'both':
556
+ if not (has_reddit and has_x):
557
+ return 'none', "Requested both sources but X source is missing."
558
+ if include_web:
559
+ return 'all', None
560
+ return 'both', None
561
+
562
+ if requested == 'reddit':
563
+ if not has_reddit:
564
+ return 'none', "Requested Reddit but only xAI key is available."
565
+ if include_web:
566
+ return 'reddit-web', None
567
+ return 'reddit', None
568
+
569
+ if requested == 'x':
570
+ if not has_x:
571
+ return 'none', "Requested X but no X source is available (need Bird auth or XAI_API_KEY)."
572
+ if include_web:
573
+ return 'x-web', None
574
+ return 'x', None
575
+
576
+ return requested, None
577
+
578
+
579
+ def get_x_source(config: Dict[str, Any]) -> Optional[str]:
580
+ """Determine the best available X/Twitter source.
581
+
582
+ Priority chain:
583
+ 1. AUTH_TOKEN/CT0 from env var or .env file → Bird with method "env"
584
+ 2. AUTH_TOKEN/CT0 from browser cookie extraction → Bird with method "browser-{browser}"
585
+ 3. XAI_API_KEY → xAI with method "api"
586
+ 4. None
587
+
588
+ Use get_x_source_with_method() to also get the method string.
589
+
590
+ Args:
591
+ config: Configuration dict from get_config()
592
+
593
+ Returns:
594
+ 'bird' if Bird is installed and authenticated,
595
+ 'xai' if XAI_API_KEY is configured,
596
+ None if no X source available.
597
+ """
598
+ source, _method = get_x_source_with_method(config)
599
+ return source
600
+
601
+
602
+ def get_x_source_with_method(config: Dict[str, Any]) -> tuple[Optional[str], Optional[str]]:
603
+ """Determine the best available X/Twitter source and auth method.
604
+
605
+ Priority chain:
606
+ 1. AUTH_TOKEN/CT0 (env var or .env) → Bird with method "env"
607
+ 2. AUTH_TOKEN/CT0 (browser cookies) → Bird with method "browser-{browser}"
608
+ 3. XAI_API_KEY → xAI with method "api"
609
+ 4. None
610
+
611
+ Args:
612
+ config: Configuration dict from get_config()
613
+
614
+ Returns:
615
+ Tuple of (source, method) where source is 'bird', 'xai', or None
616
+ and method is 'env', 'browser-chrome', 'browser-firefox', 'browser-safari', 'api', or None.
617
+ """
618
+ from . import bird_x
619
+
620
+ setup_complete = config.get('SETUP_COMPLETE')
621
+
622
+ # Check Bird first (free option — uses AUTH_TOKEN/CT0 from any source)
623
+ if bird_x.is_bird_installed():
624
+ auth_source = config.get('_AUTH_TOKEN_SOURCE')
625
+
626
+ # If SETUP_COMPLETE is not set, only allow explicit env var credentials.
627
+ # Do NOT call is_bird_authenticated() for browser-cookie probing —
628
+ # that requires user consent via the setup wizard.
629
+ if not setup_complete:
630
+ # Explicit AUTH_TOKEN from env var / .env file is always allowed
631
+ if auth_source == 'env' and config.get('AUTH_TOKEN'):
632
+ username = bird_x.is_bird_authenticated()
633
+ if username:
634
+ return 'bird', 'env'
635
+ else:
636
+ # SETUP_COMPLETE is set — normal flow, probe cookies if needed
637
+ username = bird_x.is_bird_authenticated()
638
+ if username:
639
+ if auth_source and auth_source.startswith('browser-'):
640
+ method = auth_source # e.g. "browser-firefox"
641
+ else:
642
+ method = 'env'
643
+ return 'bird', method
644
+
645
+ # Fall back to xAI if key exists
646
+ if config.get('XAI_API_KEY'):
647
+ return 'xai', 'api'
648
+
649
+ return None, None
650
+
651
+
652
+ def is_ytdlp_available() -> bool:
653
+ """Check if yt-dlp is installed for YouTube search."""
654
+ from . import youtube_yt
655
+ return youtube_yt.is_ytdlp_installed()
656
+
657
+
658
+ def is_hackernews_available() -> bool:
659
+ """Check if Hacker News source is available.
660
+
661
+ Always returns True - HN uses free Algolia API, no key needed.
662
+ """
663
+ return True
664
+
665
+
666
+ def is_bluesky_available(config: Dict[str, Any]) -> bool:
667
+ """Check if Bluesky source is available.
668
+
669
+ Requires BSKY_HANDLE and BSKY_APP_PASSWORD (app password from bsky.app/settings).
670
+ """
671
+ return bool(config.get('BSKY_HANDLE') and config.get('BSKY_APP_PASSWORD'))
672
+
673
+
674
+ def is_truthsocial_available(config: Dict[str, Any]) -> bool:
675
+ """Check if Truth Social source is available.
676
+
677
+ Requires TRUTHSOCIAL_TOKEN (bearer token from browser dev tools).
678
+ """
679
+ return bool(config.get('TRUTHSOCIAL_TOKEN'))
680
+
681
+
682
+ def is_polymarket_available() -> bool:
683
+ """Check if Polymarket source is available.
684
+
685
+ Always returns True - Gamma API is free, no key needed.
686
+ """
687
+ return True
688
+
689
+
690
+ def is_tiktok_available(config: Dict[str, Any]) -> bool:
691
+ """Check if TikTok source is available (ScrapeCreators or legacy Apify).
692
+
693
+ Returns True if SCRAPECREATORS_API_KEY or APIFY_API_TOKEN is set.
694
+ """
695
+ return bool(config.get('SCRAPECREATORS_API_KEY') or config.get('APIFY_API_TOKEN'))
696
+
697
+
698
+ def get_tiktok_token(config: Dict[str, Any]) -> str:
699
+ """Get TikTok API token, preferring ScrapeCreators over legacy Apify."""
700
+ return config.get('SCRAPECREATORS_API_KEY') or config.get('APIFY_API_TOKEN') or ''
701
+
702
+
703
+ def is_instagram_available(config: Dict[str, Any]) -> bool:
704
+ """Check if Instagram source is available (ScrapeCreators).
705
+
706
+ Returns True if SCRAPECREATORS_API_KEY is set.
707
+ Instagram uses the same key as TikTok.
708
+ """
709
+ return bool(config.get('SCRAPECREATORS_API_KEY'))
710
+
711
+
712
+ def get_instagram_token(config: Dict[str, Any]) -> str:
713
+ """Get Instagram API token (same ScrapeCreators key as TikTok)."""
714
+ return config.get('SCRAPECREATORS_API_KEY') or ''
715
+
716
+
717
+ def get_xiaohongshu_api_base(config: Dict[str, Any]) -> str:
718
+ """Get Xiaohongshu HTTP API base URL.
719
+
720
+ Defaults to host.docker.internal so OpenClaw Docker can reach host service.
721
+ """
722
+ return (config.get('XIAOHONGSHU_API_BASE') or "http://host.docker.internal:18060").rstrip("/")
723
+
724
+
725
+ def is_xiaohongshu_available(config: Dict[str, Any]) -> bool:
726
+ """Check whether Xiaohongshu HTTP API is reachable and logged in."""
727
+ # Import here to avoid heavy imports at module load.
728
+ from . import http
729
+
730
+ base = get_xiaohongshu_api_base(config)
731
+ try:
732
+ # Keep health probe snappy, but allow one retry for transient hiccups.
733
+ health = http.get(f"{base}/health", timeout=3, retries=2)
734
+ if not isinstance(health, dict):
735
+ return False
736
+ if not health.get("success"):
737
+ return False
738
+
739
+ # Login probe can be slower on some deployments (browser/session checks),
740
+ # so use a slightly longer timeout to avoid false negatives.
741
+ login = http.get(f"{base}/api/v1/login/status", timeout=8, retries=2)
742
+ is_logged_in = (
743
+ login.get("data", {}).get("is_logged_in")
744
+ if isinstance(login, dict) else False
745
+ )
746
+ return bool(is_logged_in)
747
+ except Exception:
748
+ return False
749
+
750
+
751
+ # Backward compat alias
752
+ is_apify_available = is_tiktok_available
753
+
754
+
755
+ def get_x_source_status(config: Dict[str, Any]) -> Dict[str, Any]:
756
+ """Get detailed X source status for UI decisions.
757
+
758
+ Returns:
759
+ Dict with keys: source, method, bird_installed, bird_authenticated,
760
+ bird_username, xai_available, can_install_bird
761
+
762
+ The ``method`` field indicates HOW the active source is authenticated:
763
+ - "env" — AUTH_TOKEN came from an env var or .env file
764
+ - "browser-chrome", "browser-firefox", "browser-safari" — from cookie extraction
765
+ - "api" — using xAI API key
766
+ - None — no X source available
767
+ """
768
+ from . import bird_x
769
+
770
+ setup_complete = config.get('SETUP_COMPLETE')
771
+ xai_available = bool(config.get('XAI_API_KEY'))
772
+
773
+ if not setup_complete:
774
+ # Before consent: do NOT call get_bird_status() which probes cookies.
775
+ # Only check if Bird is installed (no cookie probing) and use the
776
+ # gated get_x_source_with_method() which blocks cookie detection.
777
+ bird_installed = bird_x.is_bird_installed()
778
+ source, method = get_x_source_with_method(config)
779
+
780
+ # Bird "authenticated" only if get_x_source_with_method found explicit creds
781
+ bird_authenticated = (source == 'bird')
782
+
783
+ return {
784
+ "source": source,
785
+ "method": method,
786
+ "bird_installed": bird_installed,
787
+ "bird_authenticated": bird_authenticated,
788
+ "bird_username": None if not bird_authenticated else "env AUTH_TOKEN",
789
+ "xai_available": xai_available,
790
+ "can_install_bird": True,
791
+ }
792
+
793
+ # SETUP_COMPLETE is set — normal flow
794
+ bird_status = bird_x.get_bird_status()
795
+
796
+ # Use the unified resolution function for source + method
797
+ source, method = get_x_source_with_method(config)
798
+
799
+ return {
800
+ "source": source,
801
+ "method": method,
802
+ "bird_installed": bird_status["installed"],
803
+ "bird_authenticated": bird_status["authenticated"],
804
+ "bird_username": bird_status["username"],
805
+ "xai_available": xai_available,
806
+ "can_install_bird": bird_status["can_install"],
807
+ }