thoughtleaders-cli 0.9.8__tar.gz → 0.9.9__tar.gz

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 (164) hide show
  1. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/.claude-plugin/plugin.json +1 -1
  2. thoughtleaders_cli-0.9.9/.github/workflows/ci.yml +66 -0
  3. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/PKG-INFO +20 -1
  4. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/README.md +19 -0
  5. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/pyproject.toml +1 -1
  6. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/__init__.py +1 -1
  7. thoughtleaders_cli-0.9.9/src/tl_cli/__main__.py +13 -0
  8. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/setup.py +71 -0
  9. thoughtleaders_cli-0.9.8/.github/workflows/ci.yml +0 -38
  10. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/.claude-plugin/marketplace.json +0 -0
  11. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/.github/dependabot.yml +0 -0
  12. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/.github/workflows/cli-integration.yml +0 -0
  13. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/.github/workflows/python-publish.yml +0 -0
  14. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/.gitignore +0 -0
  15. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/AGENTS.md +0 -0
  16. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/API.md +0 -0
  17. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/CLAUDE.md +0 -0
  18. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/LICENSE +0 -0
  19. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/agents/keyword-context-classifier.md +0 -0
  20. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/agents/keyword-entity-resolver.md +0 -0
  21. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/agents/keyword-relevance-validator.md +0 -0
  22. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/agents/tl-analyst.md +0 -0
  23. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/agents/youtube-comment-classifier.md +0 -0
  24. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/hooks/hooks.json +0 -0
  25. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/hooks/scripts/load-tl-skill.mjs +0 -0
  26. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/hooks/scripts/post-usage.sh +0 -0
  27. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/hooks/scripts/pre-check.sh +0 -0
  28. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl/SKILL.md +0 -0
  29. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl/references/business-glossary.md +0 -0
  30. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl/references/elasticsearch-schema.md +0 -0
  31. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl/references/firebolt-schema.md +0 -0
  32. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl/references/postgres-schema.md +0 -0
  33. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/.gitignore +0 -0
  34. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/SKILL.md +0 -0
  35. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/references/comment-patterns.md +0 -0
  36. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/references/peer-cohort.md +0 -0
  37. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/references/red-flags.md +0 -0
  38. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/references/scoring.md +0 -0
  39. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/_io_utf8.py +0 -0
  40. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/analyze_channel.py +0 -0
  41. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/anomaly_detector.py +0 -0
  42. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/comment_analyzer.py +0 -0
  43. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/comment_scraper.py +0 -0
  44. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/engagement_ratios.py +0 -0
  45. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/peer_cohort.py +0 -0
  46. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/report.py +0 -0
  47. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/resolve_channel.py +0 -0
  48. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/score.py +0 -0
  49. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/tl_cli.py +0 -0
  50. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/video_integrity.py +0 -0
  51. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-channel-authenticity/scripts/view_curves.py +0 -0
  52. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-create-workflow/SKILL.md +0 -0
  53. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-create-workflow/references/creating-in-app.md +0 -0
  54. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-create-workflow/references/methodology.md +0 -0
  55. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-create-workflow/references/pitfalls.md +0 -0
  56. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-create-workflow/references/workflow-model.md +0 -0
  57. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/SKILL.md +0 -0
  58. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/references/elasticsearch-content-search.md +0 -0
  59. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/references/help.md +0 -0
  60. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/scripts/build_report.py +0 -0
  61. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/scripts/expand_entities.py +0 -0
  62. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/scripts/fetch_context.py +0 -0
  63. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/scripts/probe.py +0 -0
  64. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/scripts/search_channels.py +0 -0
  65. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/scripts/search_videos.py +0 -0
  66. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-keyword-research/scripts/select_keywords.py +0 -0
  67. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/SKILL.md +0 -0
  68. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/columns_brands.md +0 -0
  69. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/columns_channels.md +0 -0
  70. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/columns_content.md +0 -0
  71. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/columns_sponsorships.md +0 -0
  72. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/intelligence_filterset_schema.json +0 -0
  73. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/intelligence_widget_schema.json +0 -0
  74. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/report_glossary.md +0 -0
  75. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/sortable_columns.json +0 -0
  76. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/sponsorship_filterset_schema.json +0 -0
  77. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/sponsorship_widget_schema.json +0 -0
  78. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-save-report/references/widgets.md +0 -0
  79. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-top-partnerships/SKILL.md +0 -0
  80. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-top-partnerships/scripts/top_partnerships.py +0 -0
  81. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-views-guarantee/SKILL.md +0 -0
  82. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/skills/tl-views-guarantee/scripts/vg.py +0 -0
  83. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/_completions.py +0 -0
  84. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/_typer_utils.py +0 -0
  85. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/auth/__init__.py +0 -0
  86. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/auth/commands.py +0 -0
  87. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/auth/login.py +0 -0
  88. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/auth/pkce.py +0 -0
  89. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/auth/token_store.py +0 -0
  90. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/client/__init__.py +0 -0
  91. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/client/errors.py +0 -0
  92. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/client/http.py +0 -0
  93. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/__init__.py +0 -0
  94. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/_comments_common.py +0 -0
  95. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/balance.py +0 -0
  96. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/brands.py +0 -0
  97. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/bulk_import.py +0 -0
  98. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/changelog.py +0 -0
  99. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/channels.py +0 -0
  100. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/credits.py +0 -0
  101. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/db.py +0 -0
  102. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/deals.py +0 -0
  103. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/describe.py +0 -0
  104. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/doctor.py +0 -0
  105. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/matches.py +0 -0
  106. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/memory.py +0 -0
  107. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/profiles.py +0 -0
  108. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/proposals.py +0 -0
  109. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/recommender.py +0 -0
  110. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/reports.py +0 -0
  111. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/schema.py +0 -0
  112. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/skills.py +0 -0
  113. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/snapshots.py +0 -0
  114. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/sponsorships.py +0 -0
  115. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/uploads.py +0 -0
  116. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/whoami.py +0 -0
  117. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/commands/workflows.py +0 -0
  118. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/config.py +0 -0
  119. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/filters.py +0 -0
  120. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/hints.py +0 -0
  121. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/main.py +0 -0
  122. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/output/__init__.py +0 -0
  123. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/output/formatter.py +0 -0
  124. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/query_history.py +0 -0
  125. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/self_update.py +0 -0
  126. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/src/tl_cli/skill_registry.py +0 -0
  127. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/__init__.py +0 -0
  128. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_auth.py +0 -0
  129. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_brands_winner_channels.py +0 -0
  130. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_build_report.py +0 -0
  131. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_channels_lookalike.py +0 -0
  132. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_db_repeat_warning.py +0 -0
  133. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_describe.py +0 -0
  134. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_error_hints.py +0 -0
  135. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_expand_entities.py +0 -0
  136. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_filters.py +0 -0
  137. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_http_auth.py +0 -0
  138. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_memory.py +0 -0
  139. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_output.py +0 -0
  140. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_probe.py +0 -0
  141. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_profiles.py +0 -0
  142. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_quota_refusal_message.py +0 -0
  143. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_refusal_rendering.py +0 -0
  144. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_reports.py +0 -0
  145. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_scripts_executable.py +0 -0
  146. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_search_channels.py +0 -0
  147. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_search_videos.py +0 -0
  148. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_select_keywords.py +0 -0
  149. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_setup.py +0 -0
  150. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_setup_marker_respect.py +0 -0
  151. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_skill_registry.py +0 -0
  152. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_skills_command.py +0 -0
  153. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_sponsorships.py +0 -0
  154. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_whoami_newsletter.py +0 -0
  155. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests/test_workflows.py +0 -0
  156. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests_cli/AGENTS.md +0 -0
  157. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests_cli/conftest.py +0 -0
  158. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests_cli/test_balance.py +0 -0
  159. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests_cli/test_db_es.py +0 -0
  160. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests_cli/test_db_fb.py +0 -0
  161. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests_cli/test_db_pg.py +0 -0
  162. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests_cli/test_schema.py +0 -0
  163. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/tests_cli/test_whoami.py +0 -0
  164. {thoughtleaders_cli-0.9.8 → thoughtleaders_cli-0.9.9}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tl-cli",
3
- "version": "0.9.8",
3
+ "version": "0.9.9",
4
4
  "description": "ThoughtLeaders CLI — query sponsorship deals, channels, brands, uploads, and intelligence from the terminal",
5
5
  "author": {
6
6
  "name": "ThoughtLeaders",
@@ -0,0 +1,66 @@
1
+ name: CI
2
+
3
+ # Fast, hermetic checks on every push to main and every PR. These run the
4
+ # mocked unit suite under tests/ — no live API, no credits, fully
5
+ # deterministic. The live CLI tests live in cli-integration.yml.
6
+
7
+ on:
8
+ push:
9
+ branches: [main]
10
+ pull_request:
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ concurrency:
16
+ group: ci-${{ github.workflow }}-${{ github.ref }}
17
+ cancel-in-progress: true
18
+
19
+ jobs:
20
+ unit-tests:
21
+ name: Unit tests (mocked) · py${{ matrix.python-version }}
22
+ runs-on: ubuntu-latest
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ # Matches `requires-python = ">=3.12"`.
27
+ python-version: ["3.12", "3.13", "3.14"]
28
+ steps:
29
+ - uses: actions/checkout@v7
30
+ - uses: astral-sh/setup-uv@v7
31
+ with:
32
+ enable-cache: true
33
+ - name: Sync locked dependencies
34
+ run: uv sync --frozen --python ${{ matrix.python-version }}
35
+ - name: Run unit tests
36
+ # tests/ mock the HTTP client (CliRunner + fake get_client), so there
37
+ # is no network, no API key, and no credit spend.
38
+ run: uv run --python ${{ matrix.python-version }} --with pytest pytest tests/ -v
39
+
40
+ windows-launcher:
41
+ name: Windows launcher (tl setup windows)
42
+ # `tl setup windows` writes a tl.cmd that runs the CLI through the signed
43
+ # python.exe, so the unsigned pipx stub can't be blocked by Smart App
44
+ # Control. This job proves the wrapper is written and actually launches the
45
+ # CLI. NOTE: GitHub runners don't have SAC in enforcement, so this verifies
46
+ # the mechanism, not the block itself — real SAC validation needs a SAC/WDAC
47
+ # machine. Hermetic: a uv project install is a dev install, so the CLI's
48
+ # auto-updater no-ops (no network).
49
+ runs-on: windows-latest
50
+ steps:
51
+ - uses: actions/checkout@v7
52
+ - uses: astral-sh/setup-uv@v7
53
+ with:
54
+ enable-cache: true
55
+ - name: Sync locked dependencies
56
+ run: uv sync --frozen
57
+ - name: Install the launcher wrapper
58
+ run: uv run tl setup windows
59
+ - name: Wrapper exists and launches the CLI through python
60
+ shell: pwsh
61
+ run: |
62
+ $cmd = "$env:LOCALAPPDATA\Programs\tl-cli\tl.cmd"
63
+ if (-not (Test-Path $cmd)) { throw "wrapper not written at $cmd" }
64
+ Get-Content $cmd
65
+ & $cmd --version
66
+ if ($LASTEXITCODE -ne 0) { throw "wrapper failed to launch the CLI (exit $LASTEXITCODE)" }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: thoughtleaders-cli
3
- Version: 0.9.8
3
+ Version: 0.9.9
4
4
  Summary: ThoughtLeaders CLI — query sponsorship data, channels, brands, and intelligence
5
5
  Project-URL: Homepage, https://thoughtleaders.io
6
6
  Project-URL: Repository, https://github.com/ThoughtLeaders-io/thoughtleaders-cli
@@ -92,6 +92,25 @@ uv tool install thoughtleaders-cli
92
92
  pip install thoughtleaders-cli
93
93
  ```
94
94
 
95
+ #### Windows with Smart App Control / WDAC
96
+
97
+ The pipx/uv install above creates an **unsigned** launcher stub that Windows
98
+ Smart App Control (and enforced WDAC policies) block — `tl` fails to start with
99
+ a Code Integrity error. Fix it with:
100
+
101
+ ```powershell
102
+ tl setup windows
103
+ ```
104
+
105
+ That drops a small `tl.cmd` on your `PATH` (ahead of the blocked stub) which
106
+ launches the CLI through the already-signed `python.exe`, so it runs cleanly
107
+ under SAC. If `tl` is *already* blocked and won't start, bootstrap it through
108
+ the signed interpreter directly, then reopen your terminal:
109
+
110
+ ```powershell
111
+ & "$env:USERPROFILE\pipx\venvs\thoughtleaders-cli\Scripts\python.exe" -m tl_cli setup windows
112
+ ```
113
+
95
114
  Then set up:
96
115
  ```bash
97
116
  tl auth login # authenticate with ThoughtLeaders (OAuth2 browser flow, device code, or API key)
@@ -64,6 +64,25 @@ uv tool install thoughtleaders-cli
64
64
  pip install thoughtleaders-cli
65
65
  ```
66
66
 
67
+ #### Windows with Smart App Control / WDAC
68
+
69
+ The pipx/uv install above creates an **unsigned** launcher stub that Windows
70
+ Smart App Control (and enforced WDAC policies) block — `tl` fails to start with
71
+ a Code Integrity error. Fix it with:
72
+
73
+ ```powershell
74
+ tl setup windows
75
+ ```
76
+
77
+ That drops a small `tl.cmd` on your `PATH` (ahead of the blocked stub) which
78
+ launches the CLI through the already-signed `python.exe`, so it runs cleanly
79
+ under SAC. If `tl` is *already* blocked and won't start, bootstrap it through
80
+ the signed interpreter directly, then reopen your terminal:
81
+
82
+ ```powershell
83
+ & "$env:USERPROFILE\pipx\venvs\thoughtleaders-cli\Scripts\python.exe" -m tl_cli setup windows
84
+ ```
85
+
67
86
  Then set up:
68
87
  ```bash
69
88
  tl auth login # authenticate with ThoughtLeaders (OAuth2 browser flow, device code, or API key)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "thoughtleaders-cli"
7
- version = "0.9.8"
7
+ version = "0.9.9"
8
8
  description = "ThoughtLeaders CLI — query sponsorship data, channels, brands, and intelligence"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,3 +1,3 @@
1
1
  """ThoughtLeaders CLI — query sponsorship data, channels, brands, and intelligence."""
2
2
 
3
- __version__ = "0.9.8"
3
+ __version__ = "0.9.9"
@@ -0,0 +1,13 @@
1
+ """Module entry point for the CLI.
2
+
3
+ Enables `python -m tl_cli` and serves as the single entry script for the
4
+ PyInstaller-frozen standalone build (see packaging/tl.spec). Invoking the CLI
5
+ through the signed `python.exe` / signed frozen exe is what keeps it runnable
6
+ under Windows Smart App Control, which blocks the unsigned launcher stub that
7
+ pipx/uv generate per install.
8
+ """
9
+
10
+ from tl_cli.main import cli
11
+
12
+ if __name__ == "__main__":
13
+ cli()
@@ -756,3 +756,74 @@ def setup_codex(
756
756
  json_output=json_output,
757
757
  toon_output=toon_output,
758
758
  )
759
+
760
+
761
+ def _prepend_user_path(new_dir: str) -> bool:
762
+ """Prepend ``new_dir`` to the persistent per-user PATH.
763
+
764
+ Writes HKCU\\Environment and broadcasts the change so new processes pick it
765
+ up without a sign-out. Returns True if PATH was changed, False if new_dir
766
+ was already present. Windows-only.
767
+ """
768
+ import ctypes
769
+ import winreg
770
+
771
+ with winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Environment", 0, winreg.KEY_READ | winreg.KEY_WRITE) as key:
772
+ try:
773
+ current, _ = winreg.QueryValueEx(key, "Path")
774
+ except FileNotFoundError:
775
+ current = ""
776
+ parts = [p for p in current.split(os.pathsep) if p]
777
+ target = os.path.normcase(os.path.normpath(new_dir))
778
+ if any(os.path.normcase(os.path.normpath(p)) == target for p in parts):
779
+ return False
780
+ updated = os.pathsep.join([new_dir, *parts]) if parts else new_dir
781
+ winreg.SetValueEx(key, "Path", 0, winreg.REG_EXPAND_SZ, updated)
782
+
783
+ # Tell running shells the environment changed (best-effort).
784
+ ctypes.windll.user32.SendMessageTimeoutW(0xFFFF, 0x1A, 0, "Environment", 0x2, 5000, None)
785
+ return True
786
+
787
+
788
+ @app.command("windows")
789
+ def setup_windows(
790
+ force: bool = typer.Option(False, "--force", help="Overwrite an existing tl.cmd wrapper"),
791
+ ) -> None:
792
+ """Make `tl` runnable under Windows Smart App Control (Windows only).
793
+
794
+ pipx/uv expose `tl` through an *unsigned* launcher stub that Smart App
795
+ Control (and enforced WDAC policies) block. This writes a small `tl.cmd`
796
+ that runs the CLI through the already-signed `python.exe` instead, and
797
+ puts it ahead of the blocked stub on your PATH.
798
+
799
+ Run once. On a machine where `tl` is already blocked, bootstrap it with
800
+ the venv's signed python directly:
801
+
802
+ <pipx-venv>\\Scripts\\python.exe -m tl_cli setup windows
803
+
804
+ Examples:
805
+ tl setup windows
806
+ """
807
+ if sys.platform != "win32":
808
+ console.print("[yellow]`tl setup windows` only applies on Windows — nothing to do here.[/yellow]")
809
+ return
810
+
811
+ python_exe = Path(sys.executable)
812
+ wrapper_dir = Path(os.environ.get("LOCALAPPDATA", Path.home())) / "Programs" / "tl-cli"
813
+ wrapper = wrapper_dir / "tl.cmd"
814
+
815
+ if wrapper.exists() and not force:
816
+ console.print(f"[yellow]Wrapper already exists:[/yellow] {wrapper}\nRe-run with --force to regenerate it.")
817
+ return
818
+
819
+ wrapper_dir.mkdir(parents=True, exist_ok=True)
820
+ # Absolute path to the signed interpreter bypasses PATH so the launch can't
821
+ # resolve back to the blocked stub. %* forwards all arguments unchanged.
822
+ wrapper.write_text(f'@echo off\r\n"{python_exe}" -m tl_cli %*\r\n', encoding="ascii", newline="")
823
+
824
+ console.print(f"[green]✓[/green] Wrote signed-launcher wrapper: {wrapper}")
825
+ if _prepend_user_path(str(wrapper_dir)):
826
+ console.print(f"[green]✓[/green] Added to your user PATH (ahead of the blocked stub): {wrapper_dir}")
827
+ else:
828
+ console.print(f"[dim]Already on your user PATH: {wrapper_dir}[/dim]")
829
+ console.print("[dim]Open a new terminal, then run:[/dim] tl whoami")
@@ -1,38 +0,0 @@
1
- name: CI
2
-
3
- # Fast, hermetic checks on every push to main and every PR. These run the
4
- # mocked unit suite under tests/ — no live API, no credits, fully
5
- # deterministic. The live CLI tests live in cli-integration.yml.
6
-
7
- on:
8
- push:
9
- branches: [main]
10
- pull_request:
11
-
12
- permissions:
13
- contents: read
14
-
15
- concurrency:
16
- group: ci-${{ github.workflow }}-${{ github.ref }}
17
- cancel-in-progress: true
18
-
19
- jobs:
20
- unit-tests:
21
- name: Unit tests (mocked) · py${{ matrix.python-version }}
22
- runs-on: ubuntu-latest
23
- strategy:
24
- fail-fast: false
25
- matrix:
26
- # Matches `requires-python = ">=3.12"`.
27
- python-version: ["3.12", "3.13", "3.14"]
28
- steps:
29
- - uses: actions/checkout@v7
30
- - uses: astral-sh/setup-uv@v7
31
- with:
32
- enable-cache: true
33
- - name: Sync locked dependencies
34
- run: uv sync --frozen --python ${{ matrix.python-version }}
35
- - name: Run unit tests
36
- # tests/ mock the HTTP client (CliRunner + fake get_client), so there
37
- # is no network, no API key, and no credit spend.
38
- run: uv run --python ${{ matrix.python-version }} --with pytest pytest tests/ -v