thoughtleaders-cli 0.9.19__tar.gz → 0.9.20__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.19 → thoughtleaders_cli-0.9.20}/.claude-plugin/plugin.json +1 -1
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/PKG-INFO +1 -1
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/pyproject.toml +1 -1
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/_shared/tl_data.py +20 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/SKILL.md +2 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/build_html.py +6 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/analyze_channel.py +8 -1
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/SKILL.md +3 -1
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-views-guarantee/scripts/vg.py +18 -1
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/__init__.py +1 -1
- thoughtleaders_cli-0.9.20/src/tl_cli/commands/agent.py +57 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/main.py +12 -9
- thoughtleaders_cli-0.9.20/tests/test_agent_complete.py +81 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_shared_tl_data.py +18 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/uv.lock +1 -1
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/.claude-plugin/marketplace.json +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/.github/dependabot.yml +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/.github/workflows/ci.yml +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/.github/workflows/cli-integration.yml +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/.github/workflows/python-publish.yml +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/.gitignore +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/AGENTS.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/API.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/CLAUDE.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/LICENSE +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/README.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/cast-sheet.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/gem-classifier.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/keyword-context-classifier.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/keyword-entity-resolver.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/keyword-relevance-validator.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/merge-shard.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/tl-analyst.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/youtube-comment-classifier.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/hooks/hooks.json +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/hooks/scripts/load-tl-skill.mjs +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/hooks/scripts/post-usage.sh +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/hooks/scripts/pre-check.sh +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/connector-impact/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/connector-impact/references/help.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/connector-impact/references/impact-schema.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/connector-impact/references/impact-to-tl-mapping.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl/references/business-glossary.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl/references/elasticsearch-schema.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl/references/firebolt-schema.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl/references/postgres-schema.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/references/cast-sheet.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/references/creator-brief-template.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/references/cue-phrases.txt +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/references/evidence-rules.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/references/extractor-rubric.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/references/identity-lane.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/references/profile-spec.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/references/transcript-mining.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/assemble_extracts.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/authenticate.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/bio_lane.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/brand_reads.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/cast_sheet.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/channel_context.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/cluster_gems.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/extractor_prompt.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/fetch_cues.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/identity_prompt.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/ledger_meta.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/merge_pass.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/page.css +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/start_run.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/store_io.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/tier_hint.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/scripts/verify_quotes.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/.gitignore +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/references/comment-patterns.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/references/peer-cohort.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/references/red-flags.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/references/scoring.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/_io_utf8.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/anomaly_detector.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/channel_lookup.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/comment_analyzer.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/comment_scraper.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/engagement_ratios.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/peer_cohort.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/report.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/resolve_channel.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/score.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/video_integrity.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/scripts/view_curves.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-create-workflow/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-create-workflow/references/creating-in-app.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-create-workflow/references/methodology.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-create-workflow/references/pitfalls.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-create-workflow/references/workflow-model.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/references/elasticsearch-content-search.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/references/help.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/scripts/build_report.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/scripts/expand_entities.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/scripts/fetch_context.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/scripts/probe.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/scripts/search_channels.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/scripts/search_videos.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-keyword-research/scripts/select_keywords.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/columns_brands.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/columns_channels.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/columns_content.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/columns_sponsorships.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/intelligence_filterset_schema.json +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/intelligence_widget_schema.json +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/report_glossary.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/sortable_columns.json +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/sponsorship_filterset_schema.json +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/sponsorship_widget_schema.json +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-save-report/references/widgets.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-top-partnerships/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-top-partnerships/scripts/top_partnerships.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-views-guarantee/SKILL.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/__main__.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/_completions.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/_typer_utils.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/auth/__init__.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/auth/commands.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/auth/login.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/auth/pkce.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/auth/token_store.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/client/__init__.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/client/errors.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/client/http.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/__init__.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/_comments_common.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/balance.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/brands.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/bulk_import.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/changelog.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/channels.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/credits.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/db.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/deals.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/describe.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/doctor.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/matches.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/memory.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/profiles.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/proposals.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/recommender.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/reports.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/schema.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/setup.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/skills.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/snapshots.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/sponsorships.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/uploads.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/whoami.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/commands/workflows.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/config.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/filters.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/hints.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/output/__init__.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/output/formatter.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/query_history.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/self_update.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/src/tl_cli/skill_registry.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/__init__.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_assemble_extracts.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_auth.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_bio_lane.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_brands_winner_channels.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_build_report.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_cast_sheet.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_channels_lookalike.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_cluster_gems.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_creator_brief_accuracy.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_creator_brief_scripts.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_db_repeat_warning.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_describe.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_error_hints.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_expand_entities.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_extractor_prompt.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_fetch_cues.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_filters.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_http_auth.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_ledger_meta.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_memory.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_merge_pass.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_output.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_probe.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_profiles.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_quota_refusal_message.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_refusal_rendering.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_reports.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_scripts_executable.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_search_channels.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_search_videos.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_select_keywords.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_setup.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_setup_marker_respect.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_skill_registry.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_skills_command.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_sponsorships.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_start_run.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_whoami_newsletter.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests/test_workflows.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests_cli/AGENTS.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests_cli/conftest.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests_cli/test_balance.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests_cli/test_db_es.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests_cli/test_db_fb.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests_cli/test_db_pg.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests_cli/test_schema.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tests_cli/test_whoami.py +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tools/tl-brand-creator-connection/references/cue-phrases.trained-2026-09-15.txt +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tools/tl-brand-creator-connection/references/cue-training.md +0 -0
- {thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/tools/tl-brand-creator-connection/scripts/train_cues.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: thoughtleaders-cli
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.20
|
|
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
|
|
@@ -235,6 +235,26 @@ def preflight() -> None:
|
|
|
235
235
|
_tl(["whoami"], timeout=60)
|
|
236
236
|
|
|
237
237
|
|
|
238
|
+
def report_run(skill: str, outcome: str = "completed") -> None:
|
|
239
|
+
"""Tell ThoughtLeaders a skill opened from one of its surfaces has finished.
|
|
240
|
+
|
|
241
|
+
Best effort, never raises: the skill's own result is already on the way
|
|
242
|
+
to the user, and a report that cannot be delivered must not change that.
|
|
243
|
+
A skill started by hand has no run to close; the CLI says so and exits 0.
|
|
244
|
+
"""
|
|
245
|
+
exe = shutil.which(TL_BIN) or TL_BIN
|
|
246
|
+
try:
|
|
247
|
+
subprocess.run(
|
|
248
|
+
[exe, "agent", "complete", skill, "--outcome", outcome],
|
|
249
|
+
capture_output=True,
|
|
250
|
+
env=_child_env(),
|
|
251
|
+
timeout=30,
|
|
252
|
+
check=False,
|
|
253
|
+
)
|
|
254
|
+
except (OSError, subprocess.SubprocessError):
|
|
255
|
+
pass
|
|
256
|
+
|
|
257
|
+
|
|
238
258
|
if __name__ == "__main__":
|
|
239
259
|
if len(sys.argv) == 2 and sys.argv[1] == "preflight":
|
|
240
260
|
preflight()
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-brand-creator-connection/SKILL.md
RENAMED
|
@@ -224,6 +224,8 @@ PROFILE completion, three lines:
|
|
|
224
224
|
2. Fact count and what the socials lane did: `socials off, N linked platforms listed unread` or `socials on, N websites opened, N sources read, N facts`. Report "on" with 0 facts as such.
|
|
225
225
|
3. What was cached on the channel record this run (host name, format label, host aliases, sibling channels), from `host_name_cache` and `cache`.
|
|
226
226
|
|
|
227
|
+
A PROFILE-only run (no brand) is finished here: run `tl agent complete tl-brand-creator-connection` so a run opened from a ThoughtLeaders surface is counted (the CONNECT page reports itself). If the ledger could not be built, run it with `--outcome failed`.
|
|
228
|
+
|
|
227
229
|
**Fast run** (a run shape, not a flag): PROFILE only, primary channel only, socials OFF without asking, default selection, no corroboration round.
|
|
228
230
|
|
|
229
231
|
## 4. CONNECT pipeline
|
|
@@ -86,6 +86,10 @@ from collections import Counter, defaultdict
|
|
|
86
86
|
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent))
|
|
87
87
|
import tier_hint # sibling module # noqa: E402
|
|
88
88
|
from store_io import read_ledger # sibling module # noqa: E402
|
|
89
|
+
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2] / "_shared"))
|
|
90
|
+
import tl_data # noqa: E402
|
|
91
|
+
|
|
92
|
+
SKILL = "tl-brand-creator-connection"
|
|
89
93
|
|
|
90
94
|
BADGES = {
|
|
91
95
|
"direct": "direct",
|
|
@@ -2092,6 +2096,8 @@ def main() -> None:
|
|
|
2092
2096
|
elapsed_s=round(time.monotonic() - t0, 1))
|
|
2093
2097
|
if problems:
|
|
2094
2098
|
print("PAGE CONTRACT: " + "; ".join(problems), file=sys.stderr)
|
|
2099
|
+
# The connections page is the deliverable; a no-fit page is still a result.
|
|
2100
|
+
tl_data.report_run(SKILL)
|
|
2095
2101
|
|
|
2096
2102
|
|
|
2097
2103
|
if __name__ == "__main__":
|
|
@@ -42,6 +42,7 @@ import tl_data
|
|
|
42
42
|
|
|
43
43
|
import channel_lookup
|
|
44
44
|
|
|
45
|
+
SKILL = "tl-channel-authenticity"
|
|
45
46
|
OUT_DIR = Path("/tmp")
|
|
46
47
|
|
|
47
48
|
|
|
@@ -147,12 +148,18 @@ def main() -> None:
|
|
|
147
148
|
if args.finalize:
|
|
148
149
|
if len(args.finalize) < 2:
|
|
149
150
|
ap.error("--finalize needs STATE and at least one LLM file")
|
|
150
|
-
|
|
151
|
+
try:
|
|
152
|
+
res = finalize(args.finalize[0], args.finalize[1:])
|
|
153
|
+
except Exception:
|
|
154
|
+
tl_data.report_run(SKILL, "failed")
|
|
155
|
+
raise
|
|
151
156
|
print(res["markdown"])
|
|
152
157
|
print(
|
|
153
158
|
f"\n<!-- final JSON: {res['final_json']} · "
|
|
154
159
|
f"report: {res['report_md']} -->"
|
|
155
160
|
)
|
|
161
|
+
# The verdict is the deliverable; the run is counted once it is printed.
|
|
162
|
+
tl_data.report_run(SKILL)
|
|
156
163
|
elif args.ref:
|
|
157
164
|
res = collect(args.ref)
|
|
158
165
|
print(json.dumps(res, indent=2))
|
|
@@ -505,9 +505,11 @@ The follow-up offer matters because **FilterSet changes (keywords, demographics,
|
|
|
505
505
|
|
|
506
506
|
If the user requests a chart, create it as a SVG graphic.
|
|
507
507
|
|
|
508
|
+
Then, as the last step, run `tl agent complete tl-save-report`. A run opened from a ThoughtLeaders surface (the Chrome extension's skill buttons) is counted as finished by it; one started by hand gets a short note and nothing else, which is fine.
|
|
509
|
+
|
|
508
510
|
### On failure
|
|
509
511
|
|
|
510
|
-
If the command exits non-zero, the CLI prints the error on stderr (shape: `Error (NNN): <detail>` for most codes; specific lines for 401/402/403). **Surface the error verbatim** — do NOT silently report success.
|
|
512
|
+
If the command exits non-zero, the CLI prints the error on stderr (shape: `Error (NNN): <detail>` for most codes; specific lines for 401/402/403). **Surface the error verbatim** — do NOT silently report success. Then run `tl agent complete tl-save-report --outcome failed`.
|
|
511
513
|
|
|
512
514
|
Map the visible code + detail to the likely cause:
|
|
513
515
|
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-views-guarantee/scripts/vg.py
RENAMED
|
@@ -15,12 +15,18 @@ Usage:
|
|
|
15
15
|
import argparse
|
|
16
16
|
import datetime
|
|
17
17
|
import json
|
|
18
|
+
import pathlib as _pathlib
|
|
18
19
|
import random
|
|
19
20
|
import subprocess
|
|
20
21
|
import sys
|
|
21
22
|
from dataclasses import dataclass
|
|
22
23
|
from typing import TypedDict
|
|
23
24
|
|
|
25
|
+
sys.path.insert(0, str(_pathlib.Path(__file__).resolve().parents[2] / "_shared"))
|
|
26
|
+
import tl_data # noqa: E402
|
|
27
|
+
|
|
28
|
+
SKILL = "tl-views-guarantee"
|
|
29
|
+
|
|
24
30
|
SEED = 42 # passed to a fresh random.Random in bootstrap_sweep so each call starts from the same RNG state
|
|
25
31
|
DEFAULT_MAX_BUNDLE_SIZE = 4
|
|
26
32
|
HARD_MAX_BUNDLE_SIZE = 10
|
|
@@ -368,4 +374,15 @@ def main() -> None:
|
|
|
368
374
|
|
|
369
375
|
|
|
370
376
|
if __name__ == "__main__":
|
|
371
|
-
|
|
377
|
+
# The run is counted once the four lines are out; a data shortfall (a
|
|
378
|
+
# message exit) is a run with nothing to show, a crash is a failed one.
|
|
379
|
+
try:
|
|
380
|
+
main()
|
|
381
|
+
except SystemExit as exc:
|
|
382
|
+
if exc.code not in (None, 0):
|
|
383
|
+
tl_data.report_run(SKILL, "no_results" if isinstance(exc.code, str) else "failed")
|
|
384
|
+
raise
|
|
385
|
+
except Exception:
|
|
386
|
+
tl_data.report_run(SKILL, "failed")
|
|
387
|
+
raise
|
|
388
|
+
tl_data.report_run(SKILL)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""tl agent — the AI agent you open ThoughtLeaders skills in.
|
|
2
|
+
|
|
3
|
+
A skill handed over from a ThoughtLeaders surface (the Chrome extension's skill
|
|
4
|
+
buttons, the web app's export door) is counted as finished when it reports back
|
|
5
|
+
here with its slug and how it ended.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
|
|
11
|
+
from tl_cli._typer_utils import AlphaSortedTyperGroup
|
|
12
|
+
from tl_cli.client.errors import ApiError, handle_api_error
|
|
13
|
+
from tl_cli.client.http import get_client
|
|
14
|
+
from tl_cli.output.formatter import detect_format, output_single
|
|
15
|
+
|
|
16
|
+
app = typer.Typer(cls=AlphaSortedTyperGroup, help="Your AI agent: report a skill it ran as finished (free)")
|
|
17
|
+
|
|
18
|
+
OUTCOMES = ("completed", "no_results", "failed")
|
|
19
|
+
NO_RUN_CODE = "run_not_found"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@app.command("complete")
|
|
23
|
+
def complete_cmd(
|
|
24
|
+
skill: str = typer.Argument(..., help="The skill's slug, e.g. tl-views-guarantee"),
|
|
25
|
+
outcome: str = typer.Option("completed", "--outcome", help="How the run ended: completed, no_results or failed"),
|
|
26
|
+
json_output: bool = typer.Option(False, "--json", help="JSON output"),
|
|
27
|
+
toon_output: bool = typer.Option(False, "--toon", help="TOON output (token-efficient for LLMs)"),
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Report that a skill opened from a ThoughtLeaders surface has finished.
|
|
30
|
+
|
|
31
|
+
Skills call this as their last step. Only a skill opened from a ThoughtLeaders
|
|
32
|
+
surface has a run to close; one started by hand is simply not counted, and
|
|
33
|
+
this command says so and exits cleanly, so a skill's own result is never
|
|
34
|
+
lost over it.
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
tl agent complete tl-views-guarantee
|
|
38
|
+
tl agent complete tl-channel-authenticity --outcome no_results
|
|
39
|
+
tl agent complete tl-brand-creator-connection --outcome failed
|
|
40
|
+
"""
|
|
41
|
+
fmt = detect_format(json_output, False, False, toon_output)
|
|
42
|
+
err = Console(stderr=True)
|
|
43
|
+
if outcome not in OUTCOMES:
|
|
44
|
+
err.print(f"[red]Error:[/red] --outcome must be one of: {', '.join(OUTCOMES)}.")
|
|
45
|
+
raise typer.Exit(1)
|
|
46
|
+
|
|
47
|
+
client = get_client()
|
|
48
|
+
try:
|
|
49
|
+
data = client.post("/agent/complete", json_body={"skill": skill, "outcome": outcome})
|
|
50
|
+
output_single(data, fmt)
|
|
51
|
+
except ApiError as e:
|
|
52
|
+
if e.status_code == 404 and isinstance(e.raw, dict) and e.raw.get("code") == NO_RUN_CODE:
|
|
53
|
+
err.print(f"[dim]No open run of {skill} from a ThoughtLeaders surface; nothing to report.[/dim]")
|
|
54
|
+
return
|
|
55
|
+
handle_api_error(e)
|
|
56
|
+
finally:
|
|
57
|
+
client.close()
|
|
@@ -10,33 +10,35 @@ import typer
|
|
|
10
10
|
from rich.console import Console
|
|
11
11
|
|
|
12
12
|
from tl_cli import __version__
|
|
13
|
-
from tl_cli._typer_utils import AlphaSortedTyperGroup
|
|
14
13
|
from tl_cli import config as tl_config
|
|
14
|
+
from tl_cli._typer_utils import AlphaSortedTyperGroup
|
|
15
15
|
from tl_cli.auth.commands import app as auth_app
|
|
16
|
+
from tl_cli.commands.agent import app as agent_app
|
|
16
17
|
from tl_cli.commands.balance import app as balance_app
|
|
17
|
-
from tl_cli.commands.changelog import changelog_command
|
|
18
18
|
from tl_cli.commands.brands import app as brands_app
|
|
19
19
|
from tl_cli.commands.bulk_import import bulk_import_command
|
|
20
|
-
from tl_cli.commands.
|
|
20
|
+
from tl_cli.commands.changelog import changelog_command
|
|
21
21
|
from tl_cli.commands.channels import app as channels_app
|
|
22
|
+
from tl_cli.commands.credits import app as credits_app
|
|
22
23
|
from tl_cli.commands.db import app as db_app
|
|
23
24
|
from tl_cli.commands.deals import app as deals_app
|
|
25
|
+
from tl_cli.commands.describe import app as describe_app
|
|
26
|
+
from tl_cli.commands.doctor import app as doctor_app
|
|
24
27
|
from tl_cli.commands.matches import app as matches_app
|
|
25
28
|
from tl_cli.commands.memory import app as memory_app
|
|
26
29
|
from tl_cli.commands.profiles import app as profiles_app
|
|
27
30
|
from tl_cli.commands.proposals import app as proposals_app
|
|
28
31
|
from tl_cli.commands.recommender import app as recommender_app
|
|
29
|
-
from tl_cli.commands.sponsorships import app as sponsorships_app
|
|
30
|
-
from tl_cli.commands.describe import app as describe_app
|
|
31
|
-
from tl_cli.commands.schema import app as schema_app
|
|
32
|
-
from tl_cli.commands.doctor import app as doctor_app
|
|
33
32
|
from tl_cli.commands.reports import app as reports_app
|
|
34
|
-
from tl_cli.commands.
|
|
33
|
+
from tl_cli.commands.schema import app as schema_app
|
|
35
34
|
from tl_cli.commands.setup import app as setup_app
|
|
36
|
-
from tl_cli.commands.skills import app as skills_app
|
|
35
|
+
from tl_cli.commands.skills import app as skills_app
|
|
36
|
+
from tl_cli.commands.skills import check_skill_staleness
|
|
37
37
|
from tl_cli.commands.snapshots import app as snapshots_app
|
|
38
|
+
from tl_cli.commands.sponsorships import app as sponsorships_app
|
|
38
39
|
from tl_cli.commands.uploads import app as uploads_app
|
|
39
40
|
from tl_cli.commands.whoami import app as whoami_app
|
|
41
|
+
from tl_cli.commands.workflows import app as workflows_app
|
|
40
42
|
|
|
41
43
|
app = typer.Typer(
|
|
42
44
|
name="tl",
|
|
@@ -124,6 +126,7 @@ app.add_typer(balance_app, name="balance")
|
|
|
124
126
|
app.add_typer(credits_app, name="credits")
|
|
125
127
|
app.add_typer(doctor_app, name="doctor")
|
|
126
128
|
app.add_typer(whoami_app, name="whoami")
|
|
129
|
+
app.add_typer(agent_app, name="agent")
|
|
127
130
|
|
|
128
131
|
# `changelog` is a single command (not a sub-typer) so positional version args
|
|
129
132
|
# don't get interpreted as subcommand names.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Tests for `tl agent complete`: the skill reports its slug and outcome, and a
|
|
2
|
+
skill with no run behind it exits cleanly so the skill's own result survives."""
|
|
3
|
+
|
|
4
|
+
from unittest.mock import patch
|
|
5
|
+
|
|
6
|
+
from typer.testing import CliRunner
|
|
7
|
+
|
|
8
|
+
from tl_cli.client.errors import ApiError
|
|
9
|
+
from tl_cli.commands import agent as agent_mod
|
|
10
|
+
from tl_cli.main import app as root_app
|
|
11
|
+
|
|
12
|
+
runner = CliRunner()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class _FakeClient:
|
|
16
|
+
def __init__(self, payload: dict | None = None, error: ApiError | None = None) -> None:
|
|
17
|
+
self.payload = payload or {}
|
|
18
|
+
self.error = error
|
|
19
|
+
self.posts: list[tuple[str, dict]] = []
|
|
20
|
+
|
|
21
|
+
def post(self, path: str, json_body: dict | None = None, timeout: float | None = None) -> dict:
|
|
22
|
+
self.posts.append((path, json_body or {}))
|
|
23
|
+
if self.error is not None:
|
|
24
|
+
raise self.error
|
|
25
|
+
return self.payload
|
|
26
|
+
|
|
27
|
+
def close(self) -> None:
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _done() -> dict:
|
|
32
|
+
return {
|
|
33
|
+
"run_id": "0123456789abcdef",
|
|
34
|
+
"skill": "tl-views-guarantee",
|
|
35
|
+
"outcome": "completed",
|
|
36
|
+
"usage": {"credits_charged": 0},
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_reports_the_skill_with_the_default_outcome() -> None:
|
|
41
|
+
fake = _FakeClient(_done())
|
|
42
|
+
with patch.object(agent_mod, "get_client", return_value=fake):
|
|
43
|
+
result = runner.invoke(root_app, ["agent", "complete", "tl-views-guarantee", "--json"])
|
|
44
|
+
assert result.exit_code == 0, result.output
|
|
45
|
+
assert fake.posts == [("/agent/complete", {"skill": "tl-views-guarantee", "outcome": "completed"})]
|
|
46
|
+
assert '"run_id": "0123456789abcdef"' in result.output
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_outcome_is_passed_through() -> None:
|
|
50
|
+
fake = _FakeClient(_done())
|
|
51
|
+
with patch.object(agent_mod, "get_client", return_value=fake):
|
|
52
|
+
result = runner.invoke(root_app, ["agent", "complete", "tl-channel-authenticity", "--outcome", "no_results"])
|
|
53
|
+
assert result.exit_code == 0, result.output
|
|
54
|
+
assert fake.posts[0][1] == {"skill": "tl-channel-authenticity", "outcome": "no_results"}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_unknown_outcome_is_refused_before_any_request() -> None:
|
|
58
|
+
fake = _FakeClient(_done())
|
|
59
|
+
with patch.object(agent_mod, "get_client", return_value=fake):
|
|
60
|
+
result = runner.invoke(root_app, ["agent", "complete", "tl-views-guarantee", "--outcome", "done"])
|
|
61
|
+
assert result.exit_code == 1
|
|
62
|
+
assert fake.posts == []
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_a_skill_started_by_hand_exits_cleanly() -> None:
|
|
66
|
+
# The command sits at the end of a skill's script; a non-zero exit here would
|
|
67
|
+
# read as the skill failing, when it only has nothing to report.
|
|
68
|
+
error = ApiError(404, "No open run", raw={"code": "run_not_found"})
|
|
69
|
+
fake = _FakeClient(error=error)
|
|
70
|
+
with patch.object(agent_mod, "get_client", return_value=fake):
|
|
71
|
+
result = runner.invoke(root_app, ["agent", "complete", "tl-views-guarantee"])
|
|
72
|
+
assert result.exit_code == 0, result.output
|
|
73
|
+
assert "No open run of tl-views-guarantee" in result.stderr
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_other_errors_still_fail() -> None:
|
|
77
|
+
error = ApiError(401, "Not signed in", raw={"code": "not_authenticated"})
|
|
78
|
+
fake = _FakeClient(error=error)
|
|
79
|
+
with patch.object(agent_mod, "get_client", return_value=fake), patch.object(agent_mod, "handle_api_error") as handled:
|
|
80
|
+
runner.invoke(root_app, ["agent", "complete", "tl-views-guarantee"])
|
|
81
|
+
handled.assert_called_once_with(error)
|
|
@@ -166,3 +166,21 @@ class TestTransientRetry:
|
|
|
166
166
|
_use(monkeypatch, self._flaky(tmp_path, 1, "no such table"))
|
|
167
167
|
with pytest.raises(tl_data.DataError, match="no such table"):
|
|
168
168
|
tl_data.db_pg("SELECT 1")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class TestReportRun:
|
|
172
|
+
def test_reports_the_skill_and_outcome(self, tmp_path: Path, monkeypatch) -> None:
|
|
173
|
+
runner = _stub(tmp_path, exit_code=0, stdout="{}")
|
|
174
|
+
monkeypatch.setattr(tl_data, "TL_BIN", str(runner))
|
|
175
|
+
tl_data.report_run("tl-views-guarantee", "no_results")
|
|
176
|
+
call = json.loads((tmp_path / "call.json").read_text())
|
|
177
|
+
assert call["argv"] == ["agent", "complete", "tl-views-guarantee", "--outcome", "no_results"]
|
|
178
|
+
|
|
179
|
+
def test_never_raises(self, tmp_path: Path, monkeypatch) -> None:
|
|
180
|
+
# The report sits after the skill's own result; a missing or failing
|
|
181
|
+
# CLI must not turn a finished run into a crash.
|
|
182
|
+
monkeypatch.setattr(tl_data, "TL_BIN", str(tmp_path / "no-such-tl"))
|
|
183
|
+
tl_data.report_run("tl-views-guarantee")
|
|
184
|
+
runner = _stub(tmp_path, exit_code=3, stderr="server error")
|
|
185
|
+
monkeypatch.setattr(tl_data, "TL_BIN", str(runner))
|
|
186
|
+
tl_data.report_run("tl-views-guarantee", "failed")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/.github/workflows/cli-integration.yml
RENAMED
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/.github/workflows/python-publish.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/keyword-context-classifier.md
RENAMED
|
File without changes
|
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/keyword-relevance-validator.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/agents/youtube-comment-classifier.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/connector-impact/references/help.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl/references/business-glossary.md
RENAMED
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl/references/elasticsearch-schema.md
RENAMED
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl/references/firebolt-schema.md
RENAMED
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl/references/postgres-schema.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/.gitignore
RENAMED
|
File without changes
|
{thoughtleaders_cli-0.9.19 → thoughtleaders_cli-0.9.20}/skills/tl-channel-authenticity/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|