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.
- package/.xtrm/config/pi/extensions/xtrm-ui/format.ts +189 -0
- package/.xtrm/config/pi/extensions/xtrm-ui/index.ts +76 -17
- package/.xtrm/config/pi/extensions/xtrm-ui/package.json +16 -5
- package/.xtrm/hooks/specialists/specialists-complete.mjs +70 -0
- package/.xtrm/hooks/specialists/specialists-session-start.mjs +105 -0
- package/.xtrm/registry.json +397 -409
- package/.xtrm/skills/default/README.txt +31 -0
- package/.xtrm/skills/default/clean-code/SKILL.md +201 -0
- package/.xtrm/skills/default/creating-service-skills/SKILL.md +433 -0
- package/.xtrm/skills/default/creating-service-skills/references/script_quality_standards.md +425 -0
- package/.xtrm/skills/default/creating-service-skills/references/service_skill_system_guide.md +278 -0
- package/.xtrm/skills/default/creating-service-skills/scripts/bootstrap.py +326 -0
- package/.xtrm/skills/default/creating-service-skills/scripts/deep_dive.py +304 -0
- package/.xtrm/skills/default/creating-service-skills/scripts/scaffolder.py +482 -0
- package/.xtrm/skills/default/deepwiki/SKILL.md +50 -0
- package/.xtrm/skills/default/delegating/SKILL.md +196 -0
- package/.xtrm/skills/default/delegating/config.yaml +210 -0
- package/.xtrm/skills/default/delegating/references/orchestration-protocols.md +41 -0
- package/.xtrm/skills/default/documenting/CHANGELOG.md +23 -0
- package/.xtrm/skills/default/documenting/README.md +148 -0
- package/.xtrm/skills/default/documenting/SKILL.md +113 -0
- package/.xtrm/skills/default/documenting/examples/example_pattern.md +70 -0
- package/.xtrm/skills/default/documenting/examples/example_reference.md +70 -0
- package/.xtrm/skills/default/documenting/examples/example_ssot_analytics.md +64 -0
- package/.xtrm/skills/default/documenting/examples/example_workflow.md +141 -0
- package/.xtrm/skills/default/documenting/references/changelog-format.md +97 -0
- package/.xtrm/skills/default/documenting/references/metadata-schema.md +136 -0
- package/.xtrm/skills/default/documenting/references/taxonomy.md +81 -0
- package/.xtrm/skills/default/documenting/references/versioning-rules.md +78 -0
- package/.xtrm/skills/default/documenting/scripts/bump_version.sh +60 -0
- package/.xtrm/skills/default/documenting/scripts/changelog/__init__.py +0 -0
- package/.xtrm/skills/default/documenting/scripts/changelog/add_entry.py +216 -0
- package/.xtrm/skills/default/documenting/scripts/changelog/bump_release.py +117 -0
- package/.xtrm/skills/default/documenting/scripts/changelog/init_changelog.py +54 -0
- package/.xtrm/skills/default/documenting/scripts/changelog/validate_changelog.py +128 -0
- package/.xtrm/skills/default/documenting/scripts/drift_detector.py +266 -0
- package/.xtrm/skills/default/documenting/scripts/generate_template.py +311 -0
- package/.xtrm/skills/default/documenting/scripts/list_by_category.sh +84 -0
- package/.xtrm/skills/default/documenting/scripts/orchestrator.py +255 -0
- package/.xtrm/skills/default/documenting/scripts/validate_metadata.py +242 -0
- package/.xtrm/skills/default/documenting/templates/CHANGELOG.md.template +13 -0
- package/.xtrm/skills/default/find-docs/SKILL.md +175 -0
- package/.xtrm/skills/default/find-skills/SKILL.md +133 -0
- package/.xtrm/skills/default/github-search/SKILL.md +49 -0
- package/.xtrm/skills/default/gitnexus-debugging/SKILL.md +89 -0
- package/.xtrm/skills/default/gitnexus-impact-analysis/SKILL.md +97 -0
- package/.xtrm/skills/default/gitnexus-pr-review/SKILL.md +163 -0
- package/.xtrm/skills/default/gitnexus-refactoring/SKILL.md +121 -0
- package/.xtrm/skills/default/hook-development/SKILL.md +797 -0
- package/.xtrm/skills/default/hook-development/examples/load-context.sh +55 -0
- package/.xtrm/skills/default/hook-development/examples/quality-check.js +1168 -0
- package/.xtrm/skills/default/hook-development/examples/validate-bash.sh +43 -0
- package/.xtrm/skills/default/hook-development/examples/validate-write.sh +38 -0
- package/.xtrm/skills/default/hook-development/references/advanced.md +527 -0
- package/.xtrm/skills/default/hook-development/references/migration.md +369 -0
- package/.xtrm/skills/default/hook-development/references/patterns.md +412 -0
- package/.xtrm/skills/default/hook-development/scripts/README.md +164 -0
- package/.xtrm/skills/default/hook-development/scripts/hook-linter.sh +153 -0
- package/.xtrm/skills/default/hook-development/scripts/test-hook.sh +252 -0
- package/.xtrm/skills/default/hook-development/scripts/validate-hook-schema.sh +159 -0
- package/.xtrm/skills/default/init-session/SKILL.md +69 -0
- package/.xtrm/skills/default/last30days/SKILL.md +881 -0
- package/.xtrm/skills/default/last30days/scripts/briefing.py +260 -0
- package/.xtrm/skills/default/last30days/scripts/evaluate-synthesis.py +120 -0
- package/.xtrm/skills/default/last30days/scripts/evaluate_search_quality.py +641 -0
- package/.xtrm/skills/default/last30days/scripts/generate-synthesis-inputs.py +53 -0
- package/.xtrm/skills/default/last30days/scripts/last30days.py +2137 -0
- package/.xtrm/skills/default/last30days/scripts/lib/__init__.py +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/bird_x.py +458 -0
- package/.xtrm/skills/default/last30days/scripts/lib/bluesky.py +225 -0
- package/.xtrm/skills/default/last30days/scripts/lib/brave_search.py +329 -0
- package/.xtrm/skills/default/last30days/scripts/lib/cache.py +165 -0
- package/.xtrm/skills/default/last30days/scripts/lib/chrome_cookies.py +265 -0
- package/.xtrm/skills/default/last30days/scripts/lib/cookie_extract.py +295 -0
- package/.xtrm/skills/default/last30days/scripts/lib/dates.py +124 -0
- package/.xtrm/skills/default/last30days/scripts/lib/dedupe.py +290 -0
- package/.xtrm/skills/default/last30days/scripts/lib/entity_extract.py +127 -0
- package/.xtrm/skills/default/last30days/scripts/lib/env.py +807 -0
- package/.xtrm/skills/default/last30days/scripts/lib/exa_search.py +176 -0
- package/.xtrm/skills/default/last30days/scripts/lib/hackernews.py +266 -0
- package/.xtrm/skills/default/last30days/scripts/lib/http.py +174 -0
- package/.xtrm/skills/default/last30days/scripts/lib/instagram.py +365 -0
- package/.xtrm/skills/default/last30days/scripts/lib/models.py +221 -0
- package/.xtrm/skills/default/last30days/scripts/lib/normalize.py +489 -0
- package/.xtrm/skills/default/last30days/scripts/lib/openai_reddit.py +631 -0
- package/.xtrm/skills/default/last30days/scripts/lib/openrouter_search.py +216 -0
- package/.xtrm/skills/default/last30days/scripts/lib/parallel_search.py +139 -0
- package/.xtrm/skills/default/last30days/scripts/lib/polymarket.py +580 -0
- package/.xtrm/skills/default/last30days/scripts/lib/quality_nudge.py +201 -0
- package/.xtrm/skills/default/last30days/scripts/lib/query.py +117 -0
- package/.xtrm/skills/default/last30days/scripts/lib/query_type.py +111 -0
- package/.xtrm/skills/default/last30days/scripts/lib/reddit.py +617 -0
- package/.xtrm/skills/default/last30days/scripts/lib/reddit_enrich.py +325 -0
- package/.xtrm/skills/default/last30days/scripts/lib/reddit_public.py +259 -0
- package/.xtrm/skills/default/last30days/scripts/lib/relevance.py +148 -0
- package/.xtrm/skills/default/last30days/scripts/lib/render.py +1018 -0
- package/.xtrm/skills/default/last30days/scripts/lib/safari_cookies.py +182 -0
- package/.xtrm/skills/default/last30days/scripts/lib/schema.py +843 -0
- package/.xtrm/skills/default/last30days/scripts/lib/score.py +775 -0
- package/.xtrm/skills/default/last30days/scripts/lib/scrapecreators_x.py +182 -0
- package/.xtrm/skills/default/last30days/scripts/lib/setup_wizard.py +186 -0
- package/.xtrm/skills/default/last30days/scripts/lib/tiktok.py +349 -0
- package/.xtrm/skills/default/last30days/scripts/lib/truthsocial.py +183 -0
- package/.xtrm/skills/default/last30days/scripts/lib/ui.py +620 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/LICENSE +21 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/bird-search.mjs +134 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/cookies.js +191 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/features.json +17 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/paginate-cursor.js +37 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/query-ids.json +20 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/runtime-features.js +151 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/runtime-query-ids.js +264 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-base.js +129 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-constants.js +50 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-features.js +347 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-search.js +157 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-types.js +2 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/lib/twitter-client-utils.js +511 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/LICENSE +22 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/README.md +29 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts +3 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js +2 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts +8 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js +27 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts +11 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js +100 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts +25 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js +104 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts +10 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js +293 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts +10 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js +26 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts +7 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js +51 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts +7 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js +60 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts +7 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js +38 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts +5 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js +33 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts +24 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js +30 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts +11 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js +43 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts +8 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js +41 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts +8 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js +53 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts +8 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js +27 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts +7 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js +53 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts +8 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js +60 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts +7 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js +38 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts +6 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js +257 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts +8 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js +71 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts +6 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js +173 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts +26 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js +195 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts +121 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js +2 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts +2 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js +18 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts +8 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js +110 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts +2 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js +32 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts +2 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js +13 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts +2 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js +7 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts +5 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js +58 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts +2 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js +27 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts +2 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js +8 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js.map +1 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/package.json +40 -0
- package/.xtrm/skills/default/last30days/scripts/lib/vendor/bird-search/package.json +13 -0
- package/.xtrm/skills/default/last30days/scripts/lib/websearch.py +401 -0
- package/.xtrm/skills/default/last30days/scripts/lib/xai_x.py +217 -0
- package/.xtrm/skills/default/last30days/scripts/lib/xiaohongshu_api.py +162 -0
- package/.xtrm/skills/default/last30days/scripts/lib/youtube_yt.py +538 -0
- package/.xtrm/skills/default/last30days/scripts/store.py +654 -0
- package/.xtrm/skills/default/last30days/scripts/sync.sh +50 -0
- package/.xtrm/skills/default/last30days/scripts/test-v1-vs-v2.sh +219 -0
- package/.xtrm/skills/default/last30days/scripts/watchlist.py +329 -0
- package/.xtrm/skills/default/planning/SKILL.md +405 -0
- package/.xtrm/skills/default/planning/evals/evals.json +19 -0
- package/.xtrm/skills/default/prompt-improving/README.md +162 -0
- package/.xtrm/skills/default/prompt-improving/SKILL.md +74 -0
- package/.xtrm/skills/default/prompt-improving/references/analysis_commands.md +24 -0
- package/.xtrm/skills/default/prompt-improving/references/chain_of_thought.md +24 -0
- package/.xtrm/skills/default/prompt-improving/references/mcp_definitions.md +20 -0
- package/.xtrm/skills/default/prompt-improving/references/multishot.md +23 -0
- package/.xtrm/skills/default/prompt-improving/references/xml_core.md +60 -0
- package/.xtrm/skills/default/quality-gates/.claude/hooks/hook-config.json +66 -0
- package/.xtrm/skills/default/quality-gates/.claude/hooks/quality-check.cjs +1286 -0
- package/.xtrm/skills/default/quality-gates/.claude/hooks/quality-check.py +334 -0
- package/.xtrm/skills/default/quality-gates/.claude/settings.json +3 -0
- package/.xtrm/skills/default/quality-gates/.claude/skills/using-quality-gates/SKILL.md +254 -0
- package/.xtrm/skills/default/quality-gates/README.md +109 -0
- package/.xtrm/skills/default/quality-gates/evals/evals.json +181 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/FINAL-EVAL-SUMMARY.md +75 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/edge-case-auto-fix-verification/with_skill/outputs/response.md +59 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/edge-case-mixed-language-project/with_skill/outputs/response.md +60 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/eval-summary.md +105 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/partial-install-python-only/with_skill/outputs/response.md +93 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/python-refactor-request/with_skill/outputs/response.md +104 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/quality-gate-error-fix/with_skill/outputs/response.md +74 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-general-chat/with_skill/outputs/response.md +18 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-math-question/with_skill/outputs/response.md +18 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/should-not-trigger-unrelated-coding/with_skill/outputs/response.md +56 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/tdd-guard-blocking-confusion/with_skill/outputs/response.md +67 -0
- package/.xtrm/skills/default/quality-gates/workspace/iteration-1/typescript-feature-with-tests/with_skill/outputs/response.md +97 -0
- package/.xtrm/skills/default/scoping-service-skills/SKILL.md +231 -0
- package/.xtrm/skills/default/scoping-service-skills/scripts/scope.py +74 -0
- package/.xtrm/skills/default/service-skills-set/README.md +93 -0
- package/.xtrm/skills/default/service-skills-set/git-hooks/doc_reminder.py +67 -0
- package/.xtrm/skills/default/service-skills-set/git-hooks/skill_staleness.py +194 -0
- package/.xtrm/skills/default/service-skills-set/install-service-skills.py +193 -0
- package/.xtrm/skills/default/service-skills-set/service-registry.json +4 -0
- package/.xtrm/skills/default/service-skills-set/service-skills-readme.md +236 -0
- package/.xtrm/skills/default/service-skills-set/settings.json +37 -0
- package/.xtrm/skills/default/session-close-report/SKILL.md +131 -0
- package/.xtrm/skills/default/skill-creator/LICENSE.txt +202 -0
- package/.xtrm/skills/default/skill-creator/SKILL.md +479 -0
- package/.xtrm/skills/default/skill-creator/agents/analyzer.md +274 -0
- package/.xtrm/skills/default/skill-creator/agents/comparator.md +202 -0
- package/.xtrm/skills/default/skill-creator/agents/grader.md +223 -0
- package/.xtrm/skills/default/skill-creator/assets/eval_review.html +146 -0
- package/.xtrm/skills/default/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.xtrm/skills/default/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.xtrm/skills/default/skill-creator/references/schemas.md +430 -0
- package/.xtrm/skills/default/skill-creator/scripts/__init__.py +0 -0
- package/.xtrm/skills/default/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.xtrm/skills/default/skill-creator/scripts/generate_report.py +326 -0
- package/.xtrm/skills/default/skill-creator/scripts/improve_description.py +248 -0
- package/.xtrm/skills/default/skill-creator/scripts/package_skill.py +136 -0
- package/.xtrm/skills/default/skill-creator/scripts/quick_validate.py +103 -0
- package/.xtrm/skills/default/skill-creator/scripts/run_eval.py +310 -0
- package/.xtrm/skills/default/skill-creator/scripts/run_loop.py +332 -0
- package/.xtrm/skills/default/skill-creator/scripts/utils.py +47 -0
- package/.xtrm/skills/default/specialists-creator/SKILL.md +705 -0
- package/.xtrm/skills/default/specialists-creator/scripts/validate-specialist.ts +41 -0
- package/.xtrm/skills/default/sync-docs/SKILL.md +262 -0
- package/.xtrm/skills/default/sync-docs/evals/evals.json +89 -0
- package/.xtrm/skills/default/sync-docs/references/doc-structure.md +99 -0
- package/.xtrm/skills/default/sync-docs/references/schema.md +103 -0
- package/.xtrm/skills/default/sync-docs/scripts/changelog/add_entry.py +216 -0
- package/.xtrm/skills/default/sync-docs/scripts/context_gatherer.py +405 -0
- package/.xtrm/skills/default/sync-docs/scripts/doc_structure_analyzer.py +495 -0
- package/.xtrm/skills/default/sync-docs/scripts/drift_detector.py +563 -0
- package/.xtrm/skills/default/sync-docs/scripts/validate_doc.py +365 -0
- package/.xtrm/skills/default/sync-docs/scripts/validate_metadata.py +185 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/benchmark.json +293 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/benchmark.md +13 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/eval_metadata.json +27 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/outputs/result.md +210 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/grading.json +28 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/timing.json +1 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/outputs/result.md +101 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/grading.json +28 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/timing.json +5 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/timing.json +5 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/eval_metadata.json +27 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/outputs/result.md +198 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/grading.json +28 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/timing.json +1 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/outputs/result.md +94 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/grading.json +28 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/timing.json +1 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/eval_metadata.json +27 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/outputs/result.md +237 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/grading.json +28 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/outputs/result.md +134 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/grading.json +28 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/timing.json +1 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/benchmark.json +297 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/benchmark.md +13 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/eval_metadata.json +27 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/outputs/result.md +137 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/grading.json +92 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/timing.json +1 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/outputs/result.md +134 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/grading.json +86 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/timing.json +1 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/eval_metadata.json +27 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/outputs/result.md +193 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/grading.json +72 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/timing.json +1 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/outputs/result.md +211 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/grading.json +91 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/timing.json +5 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/eval_metadata.json +27 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/outputs/result.md +182 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/outputs/result.md +222 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/grading.json +88 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/benchmark.json +298 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/benchmark.md +13 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/eval_metadata.json +27 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/outputs/result.md +125 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/grading.json +97 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/timing.json +5 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/outputs/result.md +144 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/grading.json +78 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/timing.json +5 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/eval_metadata.json +27 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/outputs/result.md +104 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/grading.json +91 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/timing.json +5 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/outputs/result.md +79 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/grading.json +82 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/timing.json +5 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/eval_metadata.json +27 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase1_context.json +302 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase2_drift.txt +33 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase3_analysis.json +114 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase4_fix.txt +118 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase5_validate.txt +38 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/result.md +158 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/timing.json +5 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/outputs/result.md +71 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/grading.json +90 -0
- package/.xtrm/skills/default/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
- package/.xtrm/skills/default/test-planning/SKILL.md +465 -0
- package/.xtrm/skills/default/test-planning/evals/evals.json +23 -0
- package/.xtrm/skills/default/updating-service-skills/SKILL.md +136 -0
- package/.xtrm/skills/default/updating-service-skills/scripts/drift_detector.py +222 -0
- package/.xtrm/skills/default/using-nodes/SKILL.md +333 -0
- package/.xtrm/skills/default/using-quality-gates/SKILL.md +254 -0
- package/.xtrm/skills/default/using-service-skills/SKILL.md +108 -0
- package/.xtrm/skills/default/using-service-skills/scripts/cataloger.py +74 -0
- package/.xtrm/skills/default/using-service-skills/scripts/skill_activator.py +152 -0
- package/.xtrm/skills/default/using-specialists/SKILL.md +848 -0
- package/.xtrm/skills/default/using-specialists/evals/evals.json +68 -0
- package/.xtrm/skills/default/using-tdd/SKILL.md +410 -0
- package/.xtrm/skills/default/using-xtrm/SKILL.md +127 -0
- package/.xtrm/skills/default/xt-debugging/SKILL.md +149 -0
- package/.xtrm/skills/default/xt-end/SKILL.md +297 -0
- package/.xtrm/skills/default/xt-merge/SKILL.md +326 -0
- package/.xtrm/skills/optional/README.txt +2 -0
- package/.xtrm/skills/optional/architecture-design/PACK.json +11 -0
- package/.xtrm/skills/optional/architecture-design/architecture-patterns/SKILL.md +494 -0
- package/.xtrm/skills/optional/architecture-design/architecture-patterns/references/advanced-patterns.md +391 -0
- package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/SKILL.md +473 -0
- package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/assets/few-shot-examples.json +106 -0
- package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/assets/prompt-template-library.md +264 -0
- package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/chain-of-thought.md +412 -0
- package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/few-shot-learning.md +386 -0
- package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/prompt-optimization.md +428 -0
- package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/prompt-templates.md +484 -0
- package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/references/system-prompts.md +195 -0
- package/.xtrm/skills/optional/architecture-design/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
- package/.xtrm/skills/optional/architecture-design/subagent-driven-development/SKILL.md +277 -0
- package/.xtrm/skills/optional/architecture-design/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/.xtrm/skills/optional/architecture-design/subagent-driven-development/implementer-prompt.md +113 -0
- package/.xtrm/skills/optional/architecture-design/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/.xtrm/skills/optional/code-quality/PACK.json +12 -0
- package/.xtrm/skills/optional/code-quality/code-review-excellence/SKILL.md +529 -0
- package/.xtrm/skills/optional/code-quality/multi-reviewer-patterns/SKILL.md +127 -0
- package/.xtrm/skills/optional/code-quality/systematic-debugging/SKILL.md +296 -0
- package/.xtrm/skills/optional/code-quality/verification-before-completion/SKILL.md +139 -0
- package/.xtrm/skills/optional/data-engineering/PACK.json +9 -0
- package/.xtrm/skills/optional/data-engineering/data-analyst/SKILL.md +57 -0
- package/.xtrm/skills/optional/research-methods/PACK.json +12 -0
- package/.xtrm/skills/optional/research-methods/academic-researcher/SKILL.md +269 -0
- package/.xtrm/skills/optional/research-methods/brainstorming/SKILL.md +164 -0
- package/.xtrm/skills/optional/research-methods/brainstorming/scripts/frame-template.html +214 -0
- package/.xtrm/skills/optional/research-methods/brainstorming/scripts/helper.js +88 -0
- package/.xtrm/skills/optional/research-methods/brainstorming/scripts/server.cjs +354 -0
- package/.xtrm/skills/optional/research-methods/brainstorming/scripts/start-server.sh +148 -0
- package/.xtrm/skills/optional/research-methods/brainstorming/scripts/stop-server.sh +56 -0
- package/.xtrm/skills/optional/research-methods/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/.xtrm/skills/optional/research-methods/brainstorming/visual-companion.md +287 -0
- package/.xtrm/skills/optional/research-methods/deep-research/SKILL.md +192 -0
- package/.xtrm/skills/optional/research-methods/fact-checker/SKILL.md +182 -0
- package/.xtrm/skills/optional/security-ops/PACK.json +9 -0
- package/.xtrm/skills/optional/security-ops/security-auditor/SKILL.md +165 -0
- package/.xtrm/skills/optional/xt-optional/PACK.json +16 -0
- package/.xtrm/skills/optional/xt-optional/docker-expert/SKILL.md +409 -0
- package/.xtrm/skills/optional/xt-optional/obsidian-cli/SKILL.md +106 -0
- package/.xtrm/skills/optional/xt-optional/python-testing/SKILL.md +815 -0
- package/.xtrm/skills/optional/xt-optional/senior-backend/SKILL.md +209 -0
- package/.xtrm/skills/optional/xt-optional/senior-backend/references/api_design_patterns.md +103 -0
- package/.xtrm/skills/optional/xt-optional/senior-backend/references/backend_security_practices.md +103 -0
- package/.xtrm/skills/optional/xt-optional/senior-backend/references/database_optimization_guide.md +103 -0
- package/.xtrm/skills/optional/xt-optional/senior-backend/scripts/api_load_tester.py +114 -0
- package/.xtrm/skills/optional/xt-optional/senior-backend/scripts/api_scaffolder.py +114 -0
- package/.xtrm/skills/optional/xt-optional/senior-backend/scripts/database_migration_tool.py +114 -0
- package/.xtrm/skills/optional/xt-optional/senior-data-scientist/SKILL.md +226 -0
- package/.xtrm/skills/optional/xt-optional/senior-data-scientist/references/experiment_design_frameworks.md +80 -0
- package/.xtrm/skills/optional/xt-optional/senior-data-scientist/references/feature_engineering_patterns.md +80 -0
- package/.xtrm/skills/optional/xt-optional/senior-data-scientist/references/statistical_methods_advanced.md +80 -0
- package/.xtrm/skills/optional/xt-optional/senior-data-scientist/scripts/experiment_designer.py +100 -0
- package/.xtrm/skills/optional/xt-optional/senior-data-scientist/scripts/feature_engineering_pipeline.py +100 -0
- package/.xtrm/skills/optional/xt-optional/senior-data-scientist/scripts/model_evaluation_suite.py +100 -0
- package/.xtrm/skills/optional/xt-optional/senior-devops/SKILL.md +209 -0
- package/.xtrm/skills/optional/xt-optional/senior-devops/references/cicd_pipeline_guide.md +103 -0
- package/.xtrm/skills/optional/xt-optional/senior-devops/references/deployment_strategies.md +103 -0
- package/.xtrm/skills/optional/xt-optional/senior-devops/references/infrastructure_as_code.md +103 -0
- package/.xtrm/skills/optional/xt-optional/senior-devops/scripts/deployment_manager.py +114 -0
- package/.xtrm/skills/optional/xt-optional/senior-devops/scripts/pipeline_generator.py +114 -0
- package/.xtrm/skills/optional/xt-optional/senior-devops/scripts/terraform_scaffolder.py +114 -0
- package/.xtrm/skills/optional/xt-optional/senior-security/SKILL.md +209 -0
- package/.xtrm/skills/optional/xt-optional/senior-security/references/cryptography_implementation.md +103 -0
- package/.xtrm/skills/optional/xt-optional/senior-security/references/penetration_testing_guide.md +103 -0
- package/.xtrm/skills/optional/xt-optional/senior-security/references/security_architecture_patterns.md +103 -0
- package/.xtrm/skills/optional/xt-optional/senior-security/scripts/pentest_automator.py +114 -0
- package/.xtrm/skills/optional/xt-optional/senior-security/scripts/security_auditor.py +114 -0
- package/.xtrm/skills/optional/xt-optional/senior-security/scripts/threat_modeler.py +114 -0
- package/CHANGELOG.md +16 -0
- package/README.md +5 -0
- package/cli/dist/index.cjs +798 -612
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/package.json +3 -1
- package/.xtrm/extensions/auto-session-name/index.ts +0 -29
- package/.xtrm/extensions/auto-session-name/package.json +0 -16
- package/.xtrm/extensions/auto-update/index.ts +0 -71
- package/.xtrm/extensions/auto-update/package.json +0 -16
- package/.xtrm/extensions/beads/index.ts +0 -232
- package/.xtrm/extensions/beads/package.json +0 -19
- package/.xtrm/extensions/compact-header/index.ts +0 -69
- package/.xtrm/extensions/compact-header/package.json +0 -16
- package/.xtrm/extensions/core/adapter.ts +0 -52
- package/.xtrm/extensions/core/guard-rules.ts +0 -100
- package/.xtrm/extensions/core/lib.ts +0 -3
- package/.xtrm/extensions/core/logger.ts +0 -45
- package/.xtrm/extensions/core/package.json +0 -18
- package/.xtrm/extensions/core/runner.ts +0 -71
- package/.xtrm/extensions/core/session-state.ts +0 -59
- package/.xtrm/extensions/custom-footer/index.ts +0 -398
- package/.xtrm/extensions/custom-footer/package.json +0 -19
- package/.xtrm/extensions/custom-provider-qwen-cli/index.ts +0 -363
- package/.xtrm/extensions/custom-provider-qwen-cli/package.json +0 -1
- package/.xtrm/extensions/git-checkpoint/index.ts +0 -53
- package/.xtrm/extensions/git-checkpoint/package.json +0 -16
- package/.xtrm/extensions/lsp-bootstrap/index.ts +0 -134
- package/.xtrm/extensions/lsp-bootstrap/package.json +0 -17
- package/.xtrm/extensions/pi-serena-compact/index.ts +0 -121
- package/.xtrm/extensions/pi-serena-compact/package.json +0 -16
- package/.xtrm/extensions/quality-gates/index.ts +0 -66
- package/.xtrm/extensions/quality-gates/package.json +0 -19
- package/.xtrm/extensions/service-skills/index.ts +0 -108
- package/.xtrm/extensions/service-skills/package.json +0 -19
- package/.xtrm/extensions/session-flow/index.ts +0 -96
- package/.xtrm/extensions/session-flow/package.json +0 -19
- package/.xtrm/extensions/xtrm-loader/index.ts +0 -152
- package/.xtrm/extensions/xtrm-loader/package.json +0 -19
- package/.xtrm/extensions/xtrm-ui/format.ts +0 -93
- package/.xtrm/extensions/xtrm-ui/index.ts +0 -1053
- package/.xtrm/extensions/xtrm-ui/package.json +0 -10
- package/.xtrm/extensions/xtrm-ui/themes/pidex-dark.json +0 -85
- package/.xtrm/extensions/xtrm-ui/themes/pidex-light.json +0 -85
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""Chrome cookie extraction for macOS.
|
|
2
|
+
|
|
3
|
+
Extracts cookies from Chrome's encrypted SQLite database using only stdlib
|
|
4
|
+
modules and the system openssl CLI (ships with macOS). Zero pip dependencies.
|
|
5
|
+
|
|
6
|
+
Chrome on macOS uses v10 encryption (AES-128-CBC with Keychain-stored key).
|
|
7
|
+
This is NOT affected by Windows App-Bound Encryption (v20).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import hashlib
|
|
11
|
+
import logging
|
|
12
|
+
import shutil
|
|
13
|
+
import sqlite3
|
|
14
|
+
import subprocess
|
|
15
|
+
import tempfile
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Optional
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
# Chrome cookie DB location on macOS
|
|
22
|
+
CHROME_COOKIES_DB = Path.home() / "Library" / "Application Support" / "Google" / "Chrome" / "Default" / "Cookies"
|
|
23
|
+
|
|
24
|
+
# Chrome v10 encryption constants
|
|
25
|
+
CHROME_SALT = b"saltysalt"
|
|
26
|
+
CHROME_PBKDF2_ITERATIONS = 1003
|
|
27
|
+
CHROME_KEY_LENGTH = 16
|
|
28
|
+
# IV is 16 space characters (0x20)
|
|
29
|
+
CHROME_IV_HEX = "20" * 16
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _get_chrome_encryption_key() -> Optional[bytes]:
|
|
33
|
+
"""Retrieve Chrome's encryption passphrase from macOS Keychain.
|
|
34
|
+
|
|
35
|
+
Calls `security find-generic-password` which may trigger a system dialog
|
|
36
|
+
on first access.
|
|
37
|
+
|
|
38
|
+
Returns the raw passphrase bytes, or None on failure.
|
|
39
|
+
"""
|
|
40
|
+
try:
|
|
41
|
+
result = subprocess.run(
|
|
42
|
+
["security", "find-generic-password", "-w", "-s", "Chrome Safe Storage"],
|
|
43
|
+
capture_output=True,
|
|
44
|
+
text=True,
|
|
45
|
+
timeout=10,
|
|
46
|
+
)
|
|
47
|
+
if result.returncode != 0:
|
|
48
|
+
logger.info("Chrome Keychain access denied or Chrome not installed: %s", result.stderr.strip())
|
|
49
|
+
return None
|
|
50
|
+
passphrase = result.stdout.strip()
|
|
51
|
+
if not passphrase:
|
|
52
|
+
logger.info("Chrome Keychain returned empty passphrase")
|
|
53
|
+
return None
|
|
54
|
+
return passphrase.encode("utf-8")
|
|
55
|
+
except FileNotFoundError:
|
|
56
|
+
logger.info("'security' command not found — not on macOS?")
|
|
57
|
+
return None
|
|
58
|
+
except subprocess.TimeoutExpired:
|
|
59
|
+
logger.info("Chrome Keychain access timed out")
|
|
60
|
+
return None
|
|
61
|
+
except Exception as e:
|
|
62
|
+
logger.info("Failed to get Chrome encryption key: %s", e)
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _derive_aes_key(passphrase: bytes) -> bytes:
|
|
67
|
+
"""Derive 16-byte AES key from Chrome's Keychain passphrase via PBKDF2."""
|
|
68
|
+
return hashlib.pbkdf2_hmac(
|
|
69
|
+
"sha1",
|
|
70
|
+
passphrase,
|
|
71
|
+
CHROME_SALT,
|
|
72
|
+
CHROME_PBKDF2_ITERATIONS,
|
|
73
|
+
dklen=CHROME_KEY_LENGTH,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _decrypt_v10_value(encrypted_value: bytes, aes_key: bytes, db_version: int) -> Optional[str]:
|
|
78
|
+
"""Decrypt a Chrome v10-encrypted cookie value.
|
|
79
|
+
|
|
80
|
+
Uses system openssl CLI for AES-128-CBC decryption (zero pip deps).
|
|
81
|
+
For Chrome 130+ (db_version >= 24), strips 32-byte SHA-256 prefix after decryption.
|
|
82
|
+
|
|
83
|
+
Returns decrypted string or None on failure.
|
|
84
|
+
"""
|
|
85
|
+
# Strip the 'v10' prefix
|
|
86
|
+
ciphertext = encrypted_value[3:]
|
|
87
|
+
if not ciphertext:
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
hex_key = aes_key.hex()
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
result = subprocess.run(
|
|
94
|
+
[
|
|
95
|
+
"openssl", "enc", "-aes-128-cbc", "-d",
|
|
96
|
+
"-K", hex_key,
|
|
97
|
+
"-iv", CHROME_IV_HEX,
|
|
98
|
+
"-nopad",
|
|
99
|
+
],
|
|
100
|
+
input=ciphertext,
|
|
101
|
+
capture_output=True,
|
|
102
|
+
timeout=5,
|
|
103
|
+
)
|
|
104
|
+
if result.returncode != 0:
|
|
105
|
+
logger.debug("openssl decryption failed: %s", result.stderr.decode(errors="replace").strip())
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
decrypted = result.stdout
|
|
109
|
+
if not decrypted:
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
# Remove PKCS7 padding
|
|
113
|
+
decrypted = _remove_pkcs7_padding(decrypted)
|
|
114
|
+
if decrypted is None:
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
# Chrome 130+ (db version >= 24): strip 32-byte SHA-256 prefix
|
|
118
|
+
if db_version >= 24 and len(decrypted) > 32:
|
|
119
|
+
decrypted = decrypted[32:]
|
|
120
|
+
|
|
121
|
+
return decrypted.decode("utf-8", errors="replace")
|
|
122
|
+
|
|
123
|
+
except FileNotFoundError:
|
|
124
|
+
logger.info("openssl not found — cannot decrypt Chrome cookies")
|
|
125
|
+
return None
|
|
126
|
+
except subprocess.TimeoutExpired:
|
|
127
|
+
logger.info("openssl decryption timed out")
|
|
128
|
+
return None
|
|
129
|
+
except Exception as e:
|
|
130
|
+
logger.debug("Chrome cookie decryption error: %s", e)
|
|
131
|
+
return None
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _remove_pkcs7_padding(data: bytes) -> Optional[bytes]:
|
|
135
|
+
"""Remove PKCS7 padding from decrypted data.
|
|
136
|
+
|
|
137
|
+
The last byte indicates the number of padding bytes added.
|
|
138
|
+
All padding bytes must have the same value.
|
|
139
|
+
|
|
140
|
+
Returns unpadded data or None if padding is invalid.
|
|
141
|
+
"""
|
|
142
|
+
if not data:
|
|
143
|
+
return None
|
|
144
|
+
pad_len = data[-1]
|
|
145
|
+
if pad_len < 1 or pad_len > 16:
|
|
146
|
+
return None
|
|
147
|
+
# Verify all padding bytes match
|
|
148
|
+
if data[-pad_len:] != bytes([pad_len]) * pad_len:
|
|
149
|
+
return None
|
|
150
|
+
return data[:-pad_len]
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _get_db_version(cursor: sqlite3.Cursor) -> int:
|
|
154
|
+
"""Get Chrome cookie database version from the meta table.
|
|
155
|
+
|
|
156
|
+
Returns 0 if meta table doesn't exist or version can't be read.
|
|
157
|
+
"""
|
|
158
|
+
try:
|
|
159
|
+
cursor.execute("SELECT value FROM meta WHERE key = 'version'")
|
|
160
|
+
row = cursor.fetchone()
|
|
161
|
+
if row:
|
|
162
|
+
return int(row[0])
|
|
163
|
+
except Exception:
|
|
164
|
+
pass
|
|
165
|
+
return 0
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def extract_chrome_cookies_macos(domain: str, cookie_names: list[str]) -> Optional[dict[str, str]]:
|
|
169
|
+
"""Extract cookies from Chrome on macOS.
|
|
170
|
+
|
|
171
|
+
Copies the locked Cookies database to a temp file, reads specified cookies,
|
|
172
|
+
and decrypts v10-encrypted values using the Keychain-stored key.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
domain: Cookie domain to match (e.g., ".twitter.com", ".x.com")
|
|
176
|
+
cookie_names: List of cookie names to extract
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
Dict mapping cookie name to decrypted value, or None on failure.
|
|
180
|
+
Only includes cookies that were successfully found and decrypted.
|
|
181
|
+
"""
|
|
182
|
+
if not CHROME_COOKIES_DB.exists():
|
|
183
|
+
logger.info("Chrome cookies database not found at %s", CHROME_COOKIES_DB)
|
|
184
|
+
return None
|
|
185
|
+
|
|
186
|
+
# Get encryption key from Keychain
|
|
187
|
+
passphrase = _get_chrome_encryption_key()
|
|
188
|
+
aes_key = _derive_aes_key(passphrase) if passphrase else None
|
|
189
|
+
|
|
190
|
+
# Copy DB to temp file (Chrome locks the original)
|
|
191
|
+
tmp_fd = None
|
|
192
|
+
tmp_path = None
|
|
193
|
+
try:
|
|
194
|
+
tmp_fd, tmp_path = tempfile.mkstemp(suffix=".sqlite")
|
|
195
|
+
shutil.copy2(str(CHROME_COOKIES_DB), tmp_path)
|
|
196
|
+
except Exception as e:
|
|
197
|
+
logger.info("Failed to copy Chrome cookies database: %s", e)
|
|
198
|
+
if tmp_path:
|
|
199
|
+
try:
|
|
200
|
+
Path(tmp_path).unlink(missing_ok=True)
|
|
201
|
+
except Exception:
|
|
202
|
+
pass
|
|
203
|
+
return None
|
|
204
|
+
finally:
|
|
205
|
+
if tmp_fd is not None:
|
|
206
|
+
import os
|
|
207
|
+
os.close(tmp_fd)
|
|
208
|
+
|
|
209
|
+
try:
|
|
210
|
+
conn = sqlite3.connect(tmp_path)
|
|
211
|
+
cursor = conn.cursor()
|
|
212
|
+
|
|
213
|
+
db_version = _get_db_version(cursor)
|
|
214
|
+
logger.debug("Chrome cookie DB version: %d", db_version)
|
|
215
|
+
|
|
216
|
+
# Build query with placeholders for cookie names
|
|
217
|
+
placeholders = ",".join("?" for _ in cookie_names)
|
|
218
|
+
query = (
|
|
219
|
+
f"SELECT name, value, encrypted_value FROM cookies "
|
|
220
|
+
f"WHERE host_key LIKE ? AND name IN ({placeholders})"
|
|
221
|
+
)
|
|
222
|
+
# Use LIKE for domain matching (e.g., %.twitter.com matches .twitter.com)
|
|
223
|
+
params = [f"%{domain}"] + list(cookie_names)
|
|
224
|
+
cursor.execute(query, params)
|
|
225
|
+
|
|
226
|
+
results: dict[str, str] = {}
|
|
227
|
+
for name, value, encrypted_value in cursor.fetchall():
|
|
228
|
+
# Prefer unencrypted value if present
|
|
229
|
+
if value:
|
|
230
|
+
results[name] = value
|
|
231
|
+
continue
|
|
232
|
+
|
|
233
|
+
# Handle encrypted value
|
|
234
|
+
if encrypted_value and encrypted_value[:3] == b"v10":
|
|
235
|
+
if aes_key is None:
|
|
236
|
+
logger.debug("Skipping encrypted cookie %s — no Keychain access", name)
|
|
237
|
+
continue
|
|
238
|
+
decrypted = _decrypt_v10_value(encrypted_value, aes_key, db_version)
|
|
239
|
+
if decrypted:
|
|
240
|
+
results[name] = decrypted
|
|
241
|
+
else:
|
|
242
|
+
logger.debug("Failed to decrypt cookie %s", name)
|
|
243
|
+
elif encrypted_value:
|
|
244
|
+
# Unknown encryption version
|
|
245
|
+
logger.debug("Unknown encryption for cookie %s (prefix: %r)", name, encrypted_value[:3])
|
|
246
|
+
|
|
247
|
+
conn.close()
|
|
248
|
+
|
|
249
|
+
if not results:
|
|
250
|
+
logger.info("No matching cookies found in Chrome for domain %s", domain)
|
|
251
|
+
return None
|
|
252
|
+
|
|
253
|
+
return results
|
|
254
|
+
|
|
255
|
+
except sqlite3.Error as e:
|
|
256
|
+
logger.info("Failed to read Chrome cookies database: %s", e)
|
|
257
|
+
return None
|
|
258
|
+
except Exception as e:
|
|
259
|
+
logger.info("Unexpected error reading Chrome cookies: %s", e)
|
|
260
|
+
return None
|
|
261
|
+
finally:
|
|
262
|
+
try:
|
|
263
|
+
Path(tmp_path).unlink(missing_ok=True)
|
|
264
|
+
except Exception:
|
|
265
|
+
pass
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"""Browser cookie extraction for last30days.
|
|
2
|
+
|
|
3
|
+
Extracts cookies from local browser databases (Firefox, Chrome, Safari)
|
|
4
|
+
to enable zero-config authentication for services like X/Twitter.
|
|
5
|
+
|
|
6
|
+
Only uses Python stdlib — no external dependencies.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import configparser
|
|
10
|
+
import logging
|
|
11
|
+
import platform
|
|
12
|
+
import shutil
|
|
13
|
+
import sqlite3
|
|
14
|
+
import tempfile
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Dict, List, Optional
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _get_firefox_profiles_dir() -> Optional[Path]:
|
|
22
|
+
"""Return the Firefox profiles directory for the current platform, or None."""
|
|
23
|
+
system = platform.system()
|
|
24
|
+
if system == "Darwin":
|
|
25
|
+
path = Path.home() / "Library" / "Application Support" / "Firefox"
|
|
26
|
+
elif system == "Linux":
|
|
27
|
+
path = Path.home() / ".mozilla" / "firefox"
|
|
28
|
+
else:
|
|
29
|
+
# Windows: %APPDATA%\Mozilla\Firefox — best-effort
|
|
30
|
+
appdata = Path.home() / "AppData" / "Roaming" / "Mozilla" / "Firefox"
|
|
31
|
+
path = appdata
|
|
32
|
+
return path if path.is_dir() else None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _find_default_profile(profiles_dir: Path) -> Optional[Path]:
|
|
36
|
+
"""Parse profiles.ini to find the default profile directory.
|
|
37
|
+
|
|
38
|
+
Looks for a section with Default=1. Falls back to the first profile
|
|
39
|
+
directory found on disk if profiles.ini is missing or malformed.
|
|
40
|
+
"""
|
|
41
|
+
ini_path = profiles_dir / "profiles.ini"
|
|
42
|
+
|
|
43
|
+
if ini_path.is_file():
|
|
44
|
+
try:
|
|
45
|
+
config = configparser.ConfigParser()
|
|
46
|
+
config.read(str(ini_path), encoding="utf-8")
|
|
47
|
+
|
|
48
|
+
# First pass: look for Default=1
|
|
49
|
+
for section in config.sections():
|
|
50
|
+
if config.has_option(section, "Default") and config.get(section, "Default") == "1":
|
|
51
|
+
return _resolve_profile_path(profiles_dir, config, section)
|
|
52
|
+
|
|
53
|
+
# Second pass: first Install* section with Default key (Firefox >= 67 format)
|
|
54
|
+
for section in config.sections():
|
|
55
|
+
if section.startswith("Install") and config.has_option(section, "Default"):
|
|
56
|
+
raw = config.get(section, "Default")
|
|
57
|
+
candidate = profiles_dir / raw
|
|
58
|
+
if candidate.is_dir():
|
|
59
|
+
return candidate
|
|
60
|
+
|
|
61
|
+
# Third pass: first Profile section that exists on disk
|
|
62
|
+
for section in config.sections():
|
|
63
|
+
if section.startswith("Profile"):
|
|
64
|
+
resolved = _resolve_profile_path(profiles_dir, config, section)
|
|
65
|
+
if resolved and resolved.is_dir():
|
|
66
|
+
return resolved
|
|
67
|
+
except (configparser.Error, OSError) as exc:
|
|
68
|
+
logger.debug("Failed to parse profiles.ini: %s", exc)
|
|
69
|
+
|
|
70
|
+
# Fallback: scan directory for anything that looks like a profile
|
|
71
|
+
return _fallback_find_profile(profiles_dir)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _resolve_profile_path(
|
|
75
|
+
profiles_dir: Path, config: configparser.ConfigParser, section: str
|
|
76
|
+
) -> Optional[Path]:
|
|
77
|
+
"""Resolve a profile path from a ConfigParser section."""
|
|
78
|
+
if not config.has_option(section, "Path"):
|
|
79
|
+
return None
|
|
80
|
+
raw_path = config.get(section, "Path")
|
|
81
|
+
is_relative = config.has_option(section, "IsRelative") and config.get(section, "IsRelative") == "1"
|
|
82
|
+
if is_relative:
|
|
83
|
+
candidate = profiles_dir / raw_path
|
|
84
|
+
else:
|
|
85
|
+
candidate = Path(raw_path)
|
|
86
|
+
return candidate if candidate.is_dir() else None
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _fallback_find_profile(profiles_dir: Path) -> Optional[Path]:
|
|
90
|
+
"""Find the first directory that contains cookies.sqlite."""
|
|
91
|
+
try:
|
|
92
|
+
for child in sorted(profiles_dir.iterdir()):
|
|
93
|
+
if child.is_dir() and (child / "cookies.sqlite").is_file():
|
|
94
|
+
return child
|
|
95
|
+
except OSError:
|
|
96
|
+
pass
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _query_cookies_db(
|
|
101
|
+
db_path: Path, domain: str, cookie_names: List[str]
|
|
102
|
+
) -> Optional[Dict[str, str]]:
|
|
103
|
+
"""Copy the cookies database to a temp file and query it.
|
|
104
|
+
|
|
105
|
+
Firefox locks cookies.sqlite while running, so we copy first.
|
|
106
|
+
Returns {name: value} dict or None if no matching cookies found.
|
|
107
|
+
"""
|
|
108
|
+
if not db_path.is_file():
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
tmp_fd = None
|
|
112
|
+
tmp_path = None
|
|
113
|
+
try:
|
|
114
|
+
tmp_fd, tmp_path = tempfile.mkstemp(suffix=".sqlite")
|
|
115
|
+
shutil.copy2(str(db_path), tmp_path)
|
|
116
|
+
|
|
117
|
+
conn = sqlite3.connect(tmp_path)
|
|
118
|
+
try:
|
|
119
|
+
# Build parameterized query — SQLite doesn't support array params,
|
|
120
|
+
# so we build the IN clause with individual placeholders.
|
|
121
|
+
placeholders = ",".join("?" for _ in cookie_names)
|
|
122
|
+
query = (
|
|
123
|
+
f"SELECT name, value FROM moz_cookies "
|
|
124
|
+
f"WHERE host LIKE ? AND name IN ({placeholders})"
|
|
125
|
+
)
|
|
126
|
+
# domain pattern: match .x.com, x.com, etc.
|
|
127
|
+
domain_pattern = f"%{domain}"
|
|
128
|
+
params = [domain_pattern] + list(cookie_names)
|
|
129
|
+
|
|
130
|
+
cursor = conn.execute(query, params)
|
|
131
|
+
rows = cursor.fetchall()
|
|
132
|
+
finally:
|
|
133
|
+
conn.close()
|
|
134
|
+
|
|
135
|
+
if not rows:
|
|
136
|
+
return None
|
|
137
|
+
return {name: value for name, value in rows}
|
|
138
|
+
|
|
139
|
+
except (sqlite3.Error, OSError) as exc:
|
|
140
|
+
logger.debug("Failed to query cookies database %s: %s", db_path, exc)
|
|
141
|
+
return None
|
|
142
|
+
finally:
|
|
143
|
+
if tmp_path:
|
|
144
|
+
try:
|
|
145
|
+
Path(tmp_path).unlink(missing_ok=True)
|
|
146
|
+
except OSError:
|
|
147
|
+
pass
|
|
148
|
+
if tmp_fd is not None:
|
|
149
|
+
try:
|
|
150
|
+
import os
|
|
151
|
+
os.close(tmp_fd)
|
|
152
|
+
except OSError:
|
|
153
|
+
pass
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def extract_firefox_cookies(
|
|
157
|
+
domain: str, cookie_names: List[str]
|
|
158
|
+
) -> Optional[Dict[str, str]]:
|
|
159
|
+
"""Extract cookies from Firefox for the given domain and cookie names.
|
|
160
|
+
|
|
161
|
+
Finds the default Firefox profile, copies cookies.sqlite to a temp file
|
|
162
|
+
(to avoid lock conflicts), and queries for the requested cookies.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
domain: The cookie domain to match (e.g. ".x.com"). Matched with LIKE %domain.
|
|
166
|
+
cookie_names: List of cookie names to extract (e.g. ["auth_token", "ct0"]).
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
Dict of {cookie_name: cookie_value} or None if extraction fails.
|
|
170
|
+
"""
|
|
171
|
+
profiles_dir = _get_firefox_profiles_dir()
|
|
172
|
+
if profiles_dir is None:
|
|
173
|
+
logger.debug("Firefox profiles directory not found")
|
|
174
|
+
return None
|
|
175
|
+
|
|
176
|
+
profile_path = _find_default_profile(profiles_dir)
|
|
177
|
+
if profile_path is None:
|
|
178
|
+
logger.debug("No Firefox profile found in %s", profiles_dir)
|
|
179
|
+
return None
|
|
180
|
+
|
|
181
|
+
db_path = profile_path / "cookies.sqlite"
|
|
182
|
+
return _query_cookies_db(db_path, domain, cookie_names)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def extract_chrome_cookies(
|
|
186
|
+
domain: str, cookie_names: List[str]
|
|
187
|
+
) -> Optional[Dict[str, str]]:
|
|
188
|
+
"""Extract cookies from Chrome for the given domain and cookie names.
|
|
189
|
+
|
|
190
|
+
macOS only — uses Keychain + system openssl for AES-128-CBC decryption.
|
|
191
|
+
Linux/Windows not supported (Chrome uses platform-specific encryption).
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
Dict of {cookie_name: cookie_value} or None if extraction fails.
|
|
195
|
+
"""
|
|
196
|
+
if platform.system() != "Darwin":
|
|
197
|
+
logger.debug("Chrome cookie extraction only supported on macOS")
|
|
198
|
+
return None
|
|
199
|
+
try:
|
|
200
|
+
from .chrome_cookies import extract_chrome_cookies_macos
|
|
201
|
+
return extract_chrome_cookies_macos(domain, cookie_names)
|
|
202
|
+
except Exception as exc:
|
|
203
|
+
logger.debug("Chrome cookie extraction failed: %s", exc)
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def extract_safari_cookies(
|
|
208
|
+
domain: str, cookie_names: List[str]
|
|
209
|
+
) -> Optional[Dict[str, str]]:
|
|
210
|
+
"""Extract cookies from Safari for the given domain and cookie names.
|
|
211
|
+
|
|
212
|
+
macOS only — parses the unencrypted binary cookie file.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
Dict of {cookie_name: cookie_value} or None if extraction fails.
|
|
216
|
+
"""
|
|
217
|
+
if platform.system() != "Darwin":
|
|
218
|
+
logger.debug("Safari cookie extraction only supported on macOS")
|
|
219
|
+
return None
|
|
220
|
+
try:
|
|
221
|
+
from .safari_cookies import extract_safari_cookies_macos
|
|
222
|
+
return extract_safari_cookies_macos(domain, cookie_names)
|
|
223
|
+
except Exception as exc:
|
|
224
|
+
logger.debug("Safari cookie extraction failed: %s", exc)
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def extract_cookies(
|
|
229
|
+
browser: str, domain: str, cookie_names: list[str]
|
|
230
|
+
) -> Optional[dict[str, str]]:
|
|
231
|
+
"""Extract cookies from the specified browser.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
browser: One of 'firefox', 'chrome', 'safari', or 'auto'.
|
|
235
|
+
'auto' tries browsers in platform-appropriate order:
|
|
236
|
+
- macOS: Chrome -> Firefox -> Safari
|
|
237
|
+
- Linux: Firefox only
|
|
238
|
+
domain: The cookie domain to match (e.g. ".x.com").
|
|
239
|
+
cookie_names: List of cookie names to extract.
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Dict of {cookie_name: cookie_value} or None if extraction fails.
|
|
243
|
+
"""
|
|
244
|
+
result = extract_cookies_with_source(browser, domain, cookie_names)
|
|
245
|
+
if result is None:
|
|
246
|
+
return None
|
|
247
|
+
cookies, _browser_name = result
|
|
248
|
+
return cookies
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def extract_cookies_with_source(
|
|
252
|
+
browser: str, domain: str, cookie_names: list[str]
|
|
253
|
+
) -> Optional[tuple[dict[str, str], str]]:
|
|
254
|
+
"""Extract cookies and report which browser they came from.
|
|
255
|
+
|
|
256
|
+
Same as extract_cookies() but returns a (cookies, browser_name) tuple
|
|
257
|
+
so callers can track the source.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
browser: One of 'firefox', 'chrome', 'safari', or 'auto'.
|
|
261
|
+
domain: The cookie domain to match (e.g. ".x.com").
|
|
262
|
+
cookie_names: List of cookie names to extract.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
Tuple of ({cookie_name: cookie_value}, browser_name) or None.
|
|
266
|
+
"""
|
|
267
|
+
extractors = {
|
|
268
|
+
"firefox": extract_firefox_cookies,
|
|
269
|
+
"chrome": extract_chrome_cookies,
|
|
270
|
+
"safari": extract_safari_cookies,
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if browser != "auto":
|
|
274
|
+
extractor = extractors.get(browser)
|
|
275
|
+
if extractor is None:
|
|
276
|
+
logger.warning("Unknown browser: %s", browser)
|
|
277
|
+
return None
|
|
278
|
+
result = extractor(domain, cookie_names)
|
|
279
|
+
return (result, browser) if result is not None else None
|
|
280
|
+
|
|
281
|
+
# Auto mode: try browsers in platform-appropriate order
|
|
282
|
+
system = platform.system()
|
|
283
|
+
if system == "Darwin":
|
|
284
|
+
order = ["chrome", "firefox", "safari"]
|
|
285
|
+
elif system == "Linux":
|
|
286
|
+
order = ["firefox"]
|
|
287
|
+
else:
|
|
288
|
+
order = ["firefox"]
|
|
289
|
+
|
|
290
|
+
for name in order:
|
|
291
|
+
result = extractors[name](domain, cookie_names)
|
|
292
|
+
if result is not None:
|
|
293
|
+
return (result, name)
|
|
294
|
+
|
|
295
|
+
return None
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""Date utilities for last30days skill."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime, timedelta, timezone
|
|
4
|
+
from typing import Optional, Tuple
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_date_range(days: int = 30) -> Tuple[str, str]:
|
|
8
|
+
"""Get the date range for the last N days.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
Tuple of (from_date, to_date) as YYYY-MM-DD strings
|
|
12
|
+
"""
|
|
13
|
+
today = datetime.now(timezone.utc).date()
|
|
14
|
+
from_date = today - timedelta(days=days)
|
|
15
|
+
return from_date.isoformat(), today.isoformat()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def parse_date(date_str: Optional[str]) -> Optional[datetime]:
|
|
19
|
+
"""Parse a date string in various formats.
|
|
20
|
+
|
|
21
|
+
Supports: YYYY-MM-DD, ISO 8601, Unix timestamp
|
|
22
|
+
"""
|
|
23
|
+
if not date_str:
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
# Try Unix timestamp (from Reddit)
|
|
27
|
+
try:
|
|
28
|
+
ts = float(date_str)
|
|
29
|
+
return datetime.fromtimestamp(ts, tz=timezone.utc)
|
|
30
|
+
except (ValueError, TypeError):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
# Try ISO formats
|
|
34
|
+
formats = [
|
|
35
|
+
"%Y-%m-%d",
|
|
36
|
+
"%Y-%m-%dT%H:%M:%S",
|
|
37
|
+
"%Y-%m-%dT%H:%M:%SZ",
|
|
38
|
+
"%Y-%m-%dT%H:%M:%S%z",
|
|
39
|
+
"%Y-%m-%dT%H:%M:%S.%f%z",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
for fmt in formats:
|
|
43
|
+
try:
|
|
44
|
+
return datetime.strptime(date_str, fmt).replace(tzinfo=timezone.utc)
|
|
45
|
+
except ValueError:
|
|
46
|
+
continue
|
|
47
|
+
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def timestamp_to_date(ts: Optional[float]) -> Optional[str]:
|
|
52
|
+
"""Convert Unix timestamp to YYYY-MM-DD string."""
|
|
53
|
+
if ts is None:
|
|
54
|
+
return None
|
|
55
|
+
try:
|
|
56
|
+
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
|
|
57
|
+
return dt.date().isoformat()
|
|
58
|
+
except (ValueError, TypeError, OSError):
|
|
59
|
+
return None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_date_confidence(date_str: Optional[str], from_date: str, to_date: str) -> str:
|
|
63
|
+
"""Determine confidence level for a date.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
date_str: The date to check (YYYY-MM-DD or None)
|
|
67
|
+
from_date: Start of valid range (YYYY-MM-DD)
|
|
68
|
+
to_date: End of valid range (YYYY-MM-DD)
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
'high', 'med', or 'low'
|
|
72
|
+
"""
|
|
73
|
+
if not date_str:
|
|
74
|
+
return 'low'
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
dt = datetime.strptime(date_str, "%Y-%m-%d").date()
|
|
78
|
+
start = datetime.strptime(from_date, "%Y-%m-%d").date()
|
|
79
|
+
end = datetime.strptime(to_date, "%Y-%m-%d").date()
|
|
80
|
+
|
|
81
|
+
if start <= dt <= end:
|
|
82
|
+
return 'high'
|
|
83
|
+
elif dt < start:
|
|
84
|
+
# Older than range
|
|
85
|
+
return 'low'
|
|
86
|
+
else:
|
|
87
|
+
# Future date (suspicious)
|
|
88
|
+
return 'low'
|
|
89
|
+
except ValueError:
|
|
90
|
+
return 'low'
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def days_ago(date_str: Optional[str]) -> Optional[int]:
|
|
94
|
+
"""Calculate how many days ago a date is.
|
|
95
|
+
|
|
96
|
+
Returns None if date is invalid or missing.
|
|
97
|
+
"""
|
|
98
|
+
if not date_str:
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
dt = datetime.strptime(date_str, "%Y-%m-%d").date()
|
|
103
|
+
today = datetime.now(timezone.utc).date()
|
|
104
|
+
delta = today - dt
|
|
105
|
+
return delta.days
|
|
106
|
+
except ValueError:
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def recency_score(date_str: Optional[str], max_days: int = 30) -> int:
|
|
111
|
+
"""Calculate recency score (0-100).
|
|
112
|
+
|
|
113
|
+
0 days ago = 100, max_days ago = 0, clamped.
|
|
114
|
+
"""
|
|
115
|
+
age = days_ago(date_str)
|
|
116
|
+
if age is None:
|
|
117
|
+
return 0 # Unknown date gets worst score
|
|
118
|
+
|
|
119
|
+
if age < 0:
|
|
120
|
+
return 100 # Future date (treat as today)
|
|
121
|
+
if age >= max_days:
|
|
122
|
+
return 0
|
|
123
|
+
|
|
124
|
+
return int(100 * (1 - age / max_days))
|