thoughtleaders-cli 0.9.3__tar.gz → 0.9.4__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.
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/.claude-plugin/plugin.json +1 -1
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/.github/workflows/ci.yml +2 -2
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/.github/workflows/cli-integration.yml +2 -2
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/.github/workflows/python-publish.yml +1 -1
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/API.md +4 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/PKG-INFO +16 -1
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/README.md +15 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/pyproject.toml +1 -1
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl/SKILL.md +17 -3
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/__init__.py +1 -1
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/client/http.py +12 -8
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/balance.py +6 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/db.py +5 -3
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/setup.py +30 -1
- thoughtleaders_cli-0.9.4/src/tl_cli/commands/skills.py +437 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/main.py +9 -0
- thoughtleaders_cli-0.9.4/src/tl_cli/skill_registry.py +312 -0
- thoughtleaders_cli-0.9.4/tests/test_setup_marker_respect.py +214 -0
- thoughtleaders_cli-0.9.4/tests/test_skill_registry.py +376 -0
- thoughtleaders_cli-0.9.4/tests/test_skills_command.py +420 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/uv.lock +7 -19
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/.claude-plugin/marketplace.json +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/.github/dependabot.yml +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/.gitignore +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/AGENTS.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/CLAUDE.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/LICENSE +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/agents/keyword-context-classifier.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/agents/keyword-entity-resolver.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/agents/keyword-relevance-validator.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/agents/tl-analyst.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/agents/youtube-comment-classifier.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/hooks/hooks.json +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/hooks/scripts/load-tl-skill.mjs +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/hooks/scripts/post-usage.sh +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/hooks/scripts/pre-check.sh +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl/references/business-glossary.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl/references/elasticsearch-schema.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl/references/firebolt-schema.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl/references/postgres-schema.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/.gitignore +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/references/comment-patterns.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/references/peer-cohort.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/references/red-flags.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/references/scoring.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/_io_utf8.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/analyze_channel.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/anomaly_detector.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/comment_analyzer.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/comment_scraper.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/engagement_ratios.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/peer_cohort.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/report.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/resolve_channel.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/score.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/tl_cli.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/video_integrity.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-channel-authenticity/scripts/view_curves.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-create-workflow/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-create-workflow/references/creating-in-app.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-create-workflow/references/methodology.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-create-workflow/references/pitfalls.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-create-workflow/references/workflow-model.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/references/elasticsearch-content-search.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/references/help.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/scripts/build_report.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/scripts/expand_entities.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/scripts/fetch_context.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/scripts/probe.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/scripts/search_channels.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/scripts/search_videos.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-keyword-research/scripts/select_keywords.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/columns_brands.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/columns_channels.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/columns_content.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/columns_sponsorships.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/intelligence_filterset_schema.json +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/intelligence_widget_schema.json +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/report_glossary.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/sortable_columns.json +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/sponsorship_filterset_schema.json +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/sponsorship_widget_schema.json +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-save-report/references/widgets.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-top-partnerships/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-top-partnerships/scripts/top_partnerships.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-views-guarantee/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/skills/tl-views-guarantee/scripts/vg.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/_completions.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/_typer_utils.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/auth/__init__.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/auth/commands.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/auth/login.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/auth/pkce.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/auth/token_store.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/client/__init__.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/client/errors.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/__init__.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/_comments_common.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/brands.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/bulk_import.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/changelog.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/channels.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/credits.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/deals.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/describe.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/doctor.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/matches.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/profiles.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/proposals.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/recommender.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/reports.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/schema.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/snapshots.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/sponsorships.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/uploads.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/whoami.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/commands/workflows.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/config.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/filters.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/hints.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/output/__init__.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/output/formatter.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/query_history.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/src/tl_cli/self_update.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/__init__.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_auth.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_brands_winner_channels.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_build_report.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_channels_lookalike.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_db_repeat_warning.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_describe.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_error_hints.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_expand_entities.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_filters.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_http_auth.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_output.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_probe.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_profiles.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_reports.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_scripts_executable.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_search_channels.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_search_videos.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_select_keywords.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_setup.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_sponsorships.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests/test_workflows.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests_cli/AGENTS.md +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests_cli/conftest.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests_cli/test_balance.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests_cli/test_db_es.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests_cli/test_db_fb.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests_cli/test_db_pg.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests_cli/test_schema.py +0 -0
- {thoughtleaders_cli-0.9.3 → thoughtleaders_cli-0.9.4}/tests_cli/test_whoami.py +0 -0
|
@@ -26,8 +26,8 @@ jobs:
|
|
|
26
26
|
# Matches `requires-python = ">=3.12"`.
|
|
27
27
|
python-version: ["3.12", "3.13", "3.14"]
|
|
28
28
|
steps:
|
|
29
|
-
- uses: actions/checkout@
|
|
30
|
-
- uses: astral-sh/setup-uv@
|
|
29
|
+
- uses: actions/checkout@v7
|
|
30
|
+
- uses: astral-sh/setup-uv@v7
|
|
31
31
|
with:
|
|
32
32
|
enable-cache: true
|
|
33
33
|
- name: Sync locked dependencies
|
|
@@ -29,8 +29,8 @@ jobs:
|
|
|
29
29
|
name: Live read-only CLI tests
|
|
30
30
|
runs-on: ubuntu-latest
|
|
31
31
|
steps:
|
|
32
|
-
- uses: actions/checkout@
|
|
33
|
-
- uses: astral-sh/setup-uv@
|
|
32
|
+
- uses: actions/checkout@v7
|
|
33
|
+
- uses: astral-sh/setup-uv@v7
|
|
34
34
|
with:
|
|
35
35
|
enable-cache: true
|
|
36
36
|
- name: Sync locked dependencies (installs the `tl` CLI)
|
|
@@ -142,6 +142,8 @@ Useful for verifying the API key resolves to the user you expect before kicking
|
|
|
142
142
|
|
|
143
143
|
`GET /balance` — credit balance plus the last 10 metered calls for the org. Free.
|
|
144
144
|
|
|
145
|
+
`balance` is the combined total of two pools: `topup_balance` (plan-granted credits, reset to the plan allowance each top-up period, spent first) and `purchased_balance` (bought credits — they survive top-up resets, are spent last, and keep working after the per-user session quota is exhausted).
|
|
146
|
+
|
|
145
147
|
```bash
|
|
146
148
|
curl -sS "$TL_API_BASE/balance" \
|
|
147
149
|
-H "Authorization: Bearer $TL_API_KEY" \
|
|
@@ -155,6 +157,8 @@ print(get('/balance'))
|
|
|
155
157
|
```json
|
|
156
158
|
{
|
|
157
159
|
"balance": 9995.88,
|
|
160
|
+
"topup_balance": 8995.88,
|
|
161
|
+
"purchased_balance": 1000.00,
|
|
158
162
|
"allow_overage": false,
|
|
159
163
|
"recent_usage": [
|
|
160
164
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thoughtleaders-cli
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.4
|
|
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
|
|
@@ -284,6 +284,21 @@ The plugin ships several focused skills (installed by all the `tl setup *` comma
|
|
|
284
284
|
- **`tl-views-guarantee`** — sizes a multi-video sponsorship buy for a channel, returning the video bundle size, views guarantee, and likelihood to hit.
|
|
285
285
|
- **`tl-top-partnerships`** — brand-user performance report. Ranks a brand's sold sponsorships by live eCPM vs the sold-date projection, aggregates per channel, and delivers a two-tab Google Sheet ("By Deal" / "By Channel") via `gws`. Uses only public CLI commands (`tl whoami`, `tl sponsorships list`).
|
|
286
286
|
|
|
287
|
+
## Distributed skills
|
|
288
|
+
|
|
289
|
+
Beyond the bundled set above, an organization can be granted additional skills that aren't part of a CLI release — `tl skill` fetches and installs them on demand into the same directories `tl setup` uses (Claude Code's standalone skills directory, OpenCode's skills directory, and the directory shared by Gemini and Codex), so every supported agent picks them up automatically.
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
tl skill list # skills available to your organization, with installed/latest versions
|
|
293
|
+
tl skill list --all # full catalog (full-access accounts only)
|
|
294
|
+
tl skill download my-skill # fetch and install into every AI-agent skill directory
|
|
295
|
+
tl skill download my-skill --force # overwrite a directory tl doesn't already manage
|
|
296
|
+
tl skill update # refresh every downloaded skill to its latest version
|
|
297
|
+
tl skill remove my-skill # uninstall a downloaded skill
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
A directory `tl skill download` doesn't already manage (no prior `tl`-managed install there) is left alone unless `--force` is passed — it never overwrites a skill you installed some other way. `tl` warns once a day, on any command, when a downloaded skill has a newer version available. `tl setup` and self-update re-syncs also respect these directories: a downloaded skill is never rmtree'd or overwritten, even if its name collides with a bundled skill.
|
|
301
|
+
|
|
287
302
|
## Output Formats
|
|
288
303
|
|
|
289
304
|
By default, output is a styled table in the terminal and JSON when piped.
|
|
@@ -256,6 +256,21 @@ The plugin ships several focused skills (installed by all the `tl setup *` comma
|
|
|
256
256
|
- **`tl-views-guarantee`** — sizes a multi-video sponsorship buy for a channel, returning the video bundle size, views guarantee, and likelihood to hit.
|
|
257
257
|
- **`tl-top-partnerships`** — brand-user performance report. Ranks a brand's sold sponsorships by live eCPM vs the sold-date projection, aggregates per channel, and delivers a two-tab Google Sheet ("By Deal" / "By Channel") via `gws`. Uses only public CLI commands (`tl whoami`, `tl sponsorships list`).
|
|
258
258
|
|
|
259
|
+
## Distributed skills
|
|
260
|
+
|
|
261
|
+
Beyond the bundled set above, an organization can be granted additional skills that aren't part of a CLI release — `tl skill` fetches and installs them on demand into the same directories `tl setup` uses (Claude Code's standalone skills directory, OpenCode's skills directory, and the directory shared by Gemini and Codex), so every supported agent picks them up automatically.
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
tl skill list # skills available to your organization, with installed/latest versions
|
|
265
|
+
tl skill list --all # full catalog (full-access accounts only)
|
|
266
|
+
tl skill download my-skill # fetch and install into every AI-agent skill directory
|
|
267
|
+
tl skill download my-skill --force # overwrite a directory tl doesn't already manage
|
|
268
|
+
tl skill update # refresh every downloaded skill to its latest version
|
|
269
|
+
tl skill remove my-skill # uninstall a downloaded skill
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
A directory `tl skill download` doesn't already manage (no prior `tl`-managed install there) is left alone unless `--force` is passed — it never overwrites a skill you installed some other way. `tl` warns once a day, on any command, when a downloaded skill has a newer version available. `tl setup` and self-update re-syncs also respect these directories: a downloaded skill is never rmtree'd or overwritten, even if its name collides with a bundled skill.
|
|
273
|
+
|
|
259
274
|
## Output Formats
|
|
260
275
|
|
|
261
276
|
By default, output is a styled table in the terminal and JSON when piped.
|
|
@@ -251,9 +251,8 @@ contact field:
|
|
|
251
251
|
|
|
252
252
|
The channel's full email archive (`all_emails` — a JSON object keyed by email address,
|
|
253
253
|
each value recording when and where the address was found) is **not editable here**;
|
|
254
|
-
sending it returns a 400. It is append-only
|
|
255
|
-
|
|
256
|
-
modifies or removes existing entries.
|
|
254
|
+
sending it returns a 400. It is append-only and managed through an internal-only
|
|
255
|
+
process that never modifies or removes existing entries — not available via this CLI.
|
|
257
256
|
|
|
258
257
|
**Profile notes.** `tl profiles update` (superuser only) edits a brand/publisher profile's
|
|
259
258
|
**`superuser_notes`** — the internal free-text notes field on the customer record
|
|
@@ -503,6 +502,21 @@ tl changelog since v0.4.10 # Notes from v0.4.10 to latest
|
|
|
503
502
|
tl changelog --md > CHANGELOG.md # Capture for a doc
|
|
504
503
|
```
|
|
505
504
|
|
|
505
|
+
#### Distributed skills — beyond the bundled set
|
|
506
|
+
|
|
507
|
+
An organization can be granted additional skills that aren't part of a CLI release. `tl skill` fetches and installs them on demand into the same directories `tl setup` uses (Claude Code's standalone skills directory, OpenCode's skills directory, and the directory shared by Gemini and Codex), so every supported agent picks them up automatically — no restart or reconfiguration needed beyond re-reading the skill listing.
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
tl skill list # Skills available to your org, with installed/latest versions (free)
|
|
511
|
+
tl skill list --all # Full catalog (full-access accounts only)
|
|
512
|
+
tl skill download <name> # Fetch and install into every AI-agent skill directory on this machine
|
|
513
|
+
tl skill download <name> --force # Overwrite a directory tl doesn't already manage
|
|
514
|
+
tl skill update # Refresh every downloaded skill to its latest version
|
|
515
|
+
tl skill remove <name> # Uninstall a downloaded skill
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
If a user asks to find, add, or refresh a skill by capability ("is there a skill for X", "get me the latest Y skill"), check `tl skill list` before saying no — the bundled set isn't the whole catalog. `tl skill download` never overwrites a directory it doesn't already manage unless `--force` is passed, so it's safe to run without clobbering a manually-installed skill of the same name. `tl` warns once a day, on any command, when a downloaded skill has a newer version available — surface that nag to the user rather than silently ignoring it, and offer to run `tl skill update`.
|
|
519
|
+
|
|
506
520
|
#### Channel & video discovery — pick the path for the question shape
|
|
507
521
|
|
|
508
522
|
Four first-class paths, each with a different signal. **Pick by the SHAPE of the user's question, not by habit.** "Recommender first" is the right default only for path 2 — for paths 1, 3, and 4 the recommender is the wrong tool.
|
|
@@ -23,8 +23,8 @@ class TLClient:
|
|
|
23
23
|
},
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
-
def get(self, path: str, params: dict | None = None) -> dict:
|
|
27
|
-
return self._request("GET", path, params=params)
|
|
26
|
+
def get(self, path: str, params: dict | None = None, timeout: float | None = None) -> dict:
|
|
27
|
+
return self._request("GET", path, params=params, timeout=timeout)
|
|
28
28
|
|
|
29
29
|
def post(self, path: str, json_body: dict | None = None) -> dict:
|
|
30
30
|
return self._request("POST", path, json_body=json_body)
|
|
@@ -38,20 +38,24 @@ class TLClient:
|
|
|
38
38
|
path: str,
|
|
39
39
|
params: dict | None = None,
|
|
40
40
|
json_body: dict | None = None,
|
|
41
|
+
timeout: float | None = None,
|
|
41
42
|
) -> dict:
|
|
42
43
|
headers = self._auth_headers()
|
|
44
|
+
# Only overrides the client's default timeout when the caller asks
|
|
45
|
+
# for one — passing `timeout=None` through to httpx means "no
|
|
46
|
+
# timeout", not "use the default", so it's omitted entirely here.
|
|
47
|
+
request_kwargs = {"params": params, "json": json_body, "headers": headers}
|
|
48
|
+
if timeout is not None:
|
|
49
|
+
request_kwargs["timeout"] = timeout
|
|
43
50
|
|
|
44
|
-
response = self._client.request(
|
|
45
|
-
method, path, params=params, json=json_body, headers=headers
|
|
46
|
-
)
|
|
51
|
+
response = self._client.request(method, path, **request_kwargs)
|
|
47
52
|
|
|
48
53
|
# On 401, try refreshing the token once
|
|
49
54
|
if response.status_code == 401:
|
|
50
55
|
headers = self._refresh_and_get_headers()
|
|
51
56
|
if headers:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
)
|
|
57
|
+
request_kwargs["headers"] = headers
|
|
58
|
+
response = self._client.request(method, path, **request_kwargs)
|
|
55
59
|
|
|
56
60
|
if response.status_code >= 400:
|
|
57
61
|
detail = self._extract_detail(response)
|
|
@@ -44,6 +44,12 @@ def balance(
|
|
|
44
44
|
allow_overage = data.get("allow_overage", False)
|
|
45
45
|
|
|
46
46
|
console.print(f"\n[bold]Credit Balance:[/bold] [cyan]{balance_val}[/cyan] credits")
|
|
47
|
+
# Older servers return only the combined balance; newer ones split it
|
|
48
|
+
# into the plan-granted (top-up) pool and the purchased pool.
|
|
49
|
+
topup_val = data.get("topup_balance")
|
|
50
|
+
purchased_val = data.get("purchased_balance")
|
|
51
|
+
if topup_val is not None and purchased_val is not None:
|
|
52
|
+
console.print(f"[dim]Plan (top-up) credits: {topup_val} · Purchased: {purchased_val}[/dim]")
|
|
47
53
|
if allow_overage:
|
|
48
54
|
console.print("[dim]Overage: enabled[/dim]")
|
|
49
55
|
|
|
@@ -99,9 +99,11 @@ def pg_cmd(
|
|
|
99
99
|
Common traps — check before writing SQL:
|
|
100
100
|
|
|
101
101
|
- Column names follow the current schema: subscribers, projected_views,
|
|
102
|
-
scheduled_date, is_tpp, advertiser_profile_id, views_guarantee
|
|
103
|
-
older reach / impression / send_date /
|
|
104
|
-
/ impressions_guarantee.
|
|
102
|
+
scheduled_date, is_tpp, advertiser_profile_id, views_guarantee, url (the
|
|
103
|
+
channel's own URL) — NOT the older reach / impression / send_date /
|
|
104
|
+
is_tl_channel / creator_profile_id / impressions_guarantee / channel_url.
|
|
105
|
+
- thoughtleaders_adlink has no bare `url` column — the live sponsored-video
|
|
106
|
+
URL is `media_url`.
|
|
105
107
|
- The sponsorship table (thoughtleaders_adlink) hides its relations behind
|
|
106
108
|
joins: no channel_id/channel_name (join thoughtleaders_adspot via
|
|
107
109
|
ad_spot_id, then thoughtleaders_channel) and no brand_id (join
|
|
@@ -21,6 +21,7 @@ from pytoon import encode as toon_encode
|
|
|
21
21
|
from rich.console import Console
|
|
22
22
|
|
|
23
23
|
from tl_cli import __version__
|
|
24
|
+
from tl_cli.skill_registry import is_marked_for
|
|
24
25
|
|
|
25
26
|
app = typer.Typer(cls=AlphaSortedTyperGroup, help="Set up integrations (Claude Code, OpenCode, Gemini, Codex)")
|
|
26
27
|
console = Console(stderr=True)
|
|
@@ -201,6 +202,20 @@ def check_plugin_version() -> list[str]:
|
|
|
201
202
|
return warnings
|
|
202
203
|
|
|
203
204
|
|
|
205
|
+
def _warn_marker_skip(path: Path, name: str) -> None:
|
|
206
|
+
"""Print the standard warning when setup leaves a tl-managed skill dir alone.
|
|
207
|
+
|
|
208
|
+
Shared by every place in this module that would otherwise rmtree/copytree
|
|
209
|
+
over a skill directory — a directory carrying a valid `.tl-skill.json`
|
|
210
|
+
marker was installed by `tl skill download` and must never be clobbered
|
|
211
|
+
by a bundled-skill sync, regardless of name collision or content match.
|
|
212
|
+
"""
|
|
213
|
+
console.print(
|
|
214
|
+
f" [yellow]![/yellow] skipping {path}: managed by 'tl skill' downloads — "
|
|
215
|
+
f"remove with [cyan]tl skill remove {name}[/cyan] if you want the bundled version"
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
|
|
204
219
|
def _install_standalone_skills(plugin_root: Path) -> int:
|
|
205
220
|
"""Copy skills and commands to ~/.claude/ for non-namespaced invocation.
|
|
206
221
|
|
|
@@ -214,6 +229,9 @@ def _install_standalone_skills(plugin_root: Path) -> int:
|
|
|
214
229
|
for skill_dir in skills_src.iterdir():
|
|
215
230
|
if skill_dir.is_dir() and (skill_dir / "SKILL.md").is_file():
|
|
216
231
|
dst = CLAUDE_SKILLS_DIR / skill_dir.name
|
|
232
|
+
if dst.exists() and is_marked_for(dst, skill_dir.name):
|
|
233
|
+
_warn_marker_skip(dst, skill_dir.name)
|
|
234
|
+
continue
|
|
217
235
|
if dst.exists():
|
|
218
236
|
shutil.rmtree(dst)
|
|
219
237
|
shutil.copytree(skill_dir, dst)
|
|
@@ -279,6 +297,11 @@ def _remove_matching_standalone_skills(plugin_root: Path) -> tuple[int, int]:
|
|
|
279
297
|
standalone = CLAUDE_SKILLS_DIR / skill_dir.name
|
|
280
298
|
if not standalone.is_dir():
|
|
281
299
|
continue
|
|
300
|
+
if is_marked_for(standalone, skill_dir.name):
|
|
301
|
+
# tl-managed download — excluded from deletion candidates entirely,
|
|
302
|
+
# regardless of whether its content happens to match the bundled skill.
|
|
303
|
+
_warn_marker_skip(standalone, skill_dir.name)
|
|
304
|
+
continue
|
|
282
305
|
if _trees_identical(skill_dir, standalone):
|
|
283
306
|
shutil.rmtree(standalone)
|
|
284
307
|
removed += 1
|
|
@@ -537,7 +560,10 @@ def _install_skill_trees(plugin_root: Path, target_dir: Path) -> int:
|
|
|
537
560
|
(OpenCode, Gemini, Codex) — each agent reads skills from a different
|
|
538
561
|
base directory, so we just parameterise on that. A `.tl-version`
|
|
539
562
|
stamp is written into the target so `check_plugin_version()` can
|
|
540
|
-
detect drift later.
|
|
563
|
+
detect drift later. A destination carrying a `.tl-skill.json` marker
|
|
564
|
+
for this skill name is a `tl skill download` install — it's skipped
|
|
565
|
+
(with a warning) rather than clobbered, and isn't counted in the
|
|
566
|
+
returned total. Returns the number of skills installed.
|
|
541
567
|
"""
|
|
542
568
|
count = 0
|
|
543
569
|
skills_src = plugin_root / "skills"
|
|
@@ -545,6 +571,9 @@ def _install_skill_trees(plugin_root: Path, target_dir: Path) -> int:
|
|
|
545
571
|
for skill_dir in skills_src.iterdir():
|
|
546
572
|
if skill_dir.is_dir() and (skill_dir / "SKILL.md").is_file():
|
|
547
573
|
dst = target_dir / skill_dir.name
|
|
574
|
+
if dst.exists() and is_marked_for(dst, skill_dir.name):
|
|
575
|
+
_warn_marker_skip(dst, skill_dir.name)
|
|
576
|
+
continue
|
|
548
577
|
if dst.exists():
|
|
549
578
|
shutil.rmtree(dst)
|
|
550
579
|
shutil.copytree(skill_dir, dst)
|