thoughtleaders-cli 0.6.42__tar.gz → 0.6.43__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 (95) hide show
  1. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/.claude-plugin/plugin.json +1 -1
  2. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/PKG-INFO +1 -1
  3. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/pyproject.toml +1 -1
  4. thoughtleaders_cli-0.6.43/skills/tl-feedback/SKILL.md +87 -0
  5. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/SKILL.md +1 -1
  6. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/report_glossary.md +19 -21
  7. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/__init__.py +1 -1
  8. thoughtleaders_cli-0.6.43/src/tl_cli/commands/feedback.py +61 -0
  9. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/main.py +2 -0
  10. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/.claude-plugin/marketplace.json +0 -0
  11. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/.github/workflows/python-publish.yml +0 -0
  12. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/.gitignore +0 -0
  13. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/AGENTS.md +0 -0
  14. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/CLAUDE.md +0 -0
  15. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/LICENSE +0 -0
  16. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/README.md +0 -0
  17. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/agents/tl-analyst.md +0 -0
  18. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/docs/architecture.md +0 -0
  19. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/hooks/hooks.json +0 -0
  20. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/hooks/scripts/load-tl-skill.mjs +0 -0
  21. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/hooks/scripts/post-usage.sh +0 -0
  22. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/hooks/scripts/pre-check.sh +0 -0
  23. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl/SKILL.md +0 -0
  24. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl/references/business-glossary.md +0 -0
  25. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl/references/elasticsearch-schema.md +0 -0
  26. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl/references/firebolt-schema.md +0 -0
  27. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl/references/postgres-schema.md +0 -0
  28. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-import/SKILL.md +0 -0
  29. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/examples/e2e_findings.md +0 -0
  30. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/examples/golden_queries.md +0 -0
  31. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/columns_brands.md +0 -0
  32. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/columns_channels.md +0 -0
  33. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/columns_content.md +0 -0
  34. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/columns_sponsorships.md +0 -0
  35. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/intelligence_filterset_schema.json +0 -0
  36. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/intelligence_widget_schema.json +0 -0
  37. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/sortable_columns.json +0 -0
  38. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/sponsorship_filterset_schema.json +0 -0
  39. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/sponsorship_widget_schema.json +0 -0
  40. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/references/widgets.md +0 -0
  41. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/tools/column_builder.md +0 -0
  42. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/tools/database_query.md +0 -0
  43. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/tools/keyword_research.md +0 -0
  44. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/tools/name_resolver.md +0 -0
  45. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/tools/sample_judge.md +0 -0
  46. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/tools/similar_channels.md +0 -0
  47. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/tools/topic_matcher.md +0 -0
  48. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/skills/tl-report-builder/tools/widget_builder.md +0 -0
  49. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/_completions.py +0 -0
  50. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/auth/__init__.py +0 -0
  51. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/auth/commands.py +0 -0
  52. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/auth/finalize.py +0 -0
  53. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/auth/login.py +0 -0
  54. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/auth/pkce.py +0 -0
  55. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/auth/token_store.py +0 -0
  56. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/client/__init__.py +0 -0
  57. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/client/errors.py +0 -0
  58. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/client/http.py +0 -0
  59. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/__init__.py +0 -0
  60. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/_comments_common.py +0 -0
  61. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/ask.py +0 -0
  62. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/balance.py +0 -0
  63. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/brands.py +0 -0
  64. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/bulk_import.py +0 -0
  65. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/changelog.py +0 -0
  66. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/channels.py +0 -0
  67. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/credits.py +0 -0
  68. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/db.py +0 -0
  69. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/deals.py +0 -0
  70. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/describe.py +0 -0
  71. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/doctor.py +0 -0
  72. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/matches.py +0 -0
  73. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/proposals.py +0 -0
  74. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/recommender.py +0 -0
  75. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/reports.py +0 -0
  76. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/schema.py +0 -0
  77. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/setup.py +0 -0
  78. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/snapshots.py +0 -0
  79. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/sponsorships.py +0 -0
  80. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/uploads.py +0 -0
  81. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/commands/whoami.py +0 -0
  82. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/config.py +0 -0
  83. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/filters.py +0 -0
  84. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/hints.py +0 -0
  85. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/output/__init__.py +0 -0
  86. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/output/formatter.py +0 -0
  87. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/src/tl_cli/self_update.py +0 -0
  88. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/tests/__init__.py +0 -0
  89. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/tests/test_auth.py +0 -0
  90. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/tests/test_filters.py +0 -0
  91. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/tests/test_http_auth.py +0 -0
  92. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/tests/test_output.py +0 -0
  93. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/tests/test_reports.py +0 -0
  94. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/tests/test_sponsorships.py +0 -0
  95. {thoughtleaders_cli-0.6.42 → thoughtleaders_cli-0.6.43}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tl-cli",
3
- "version": "0.6.42",
3
+ "version": "0.6.43",
4
4
  "description": "ThoughtLeaders CLI — query sponsorship deals, channels, brands, uploads, and intelligence from the terminal",
5
5
  "author": {
6
6
  "name": "ThoughtLeaders",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: thoughtleaders-cli
3
- Version: 0.6.42
3
+ Version: 0.6.43
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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "thoughtleaders-cli"
7
- version = "0.6.42"
7
+ version = "0.6.43"
8
8
  description = "ThoughtLeaders CLI — query sponsorship data, channels, brands, and intelligence"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: tl-feedback
3
+ description: Compose and submit feedback about the current AI Agent session that used the `tl` CLI. Triggers on phrases like "send feedback", "report a problem with the session", "tell the team how this went", "submit session feedback", "feedback about tl", "this session was frustrating, send feedback", "tl feedback", "share this session with the team", "log issues from this run". Use it ONLY when the user wants to send a written report about the session to the ThoughtLeaders team — never on requests that just *use* `tl` to query data.
4
+ ---
5
+
6
+ # Send a session-feedback report via `tl feedback`
7
+
8
+ The `tl feedback` command POSTs a markdown-formatted message to the ThoughtLeaders team's `#ai-feedback` Slack channel. The server-side endpoint prepends the user/org context (user, email, organisation, links into Django admin), so the body you send should contain **only the session-specific report** — do not try to restate the user's name or org yourself.
9
+
10
+ This skill produces that body. Do not invoke `tl feedback` until every section below is written.
11
+
12
+ ## When to invoke
13
+
14
+ Trigger this skill **only** when the user is explicitly asking for feedback to be sent — phrases like "send feedback", "log a problem with this session", "share these issues with the team", "submit session feedback", "tl feedback". Do **not** trigger it when the user is asking `tl` to fetch data, build a report, or perform any other analytical task; in those cases the `tl-cli:tl` or `tl-cli:tl-report-builder` skills are the right ones.
15
+
16
+ If you are not sure whether the user wants the feedback sent now or is just venting, ask one clarifying question before composing the body. Otherwise proceed.
17
+
18
+ ## What the body must contain
19
+
20
+ Write the body to a scratch buffer (do not stream it directly to the shell) and only send it once all four sections are present. Use the **Slack mrkdwn subset** of markdown — Slack does not render standard markdown:
21
+
22
+ | Want | Slack mrkdwn |
23
+ | --- | --- |
24
+ | Bold | `*bold*` (single asterisk) |
25
+ | Italic | `_italic_` |
26
+ | Strike | `~strike~` |
27
+ | Inline code | `` `code` `` |
28
+ | Code block | triple backticks |
29
+ | Block quote | `> text` |
30
+ | Bullets | leading `• ` (or `- `) |
31
+ | Link | `<https://example.com|label>` |
32
+
33
+ `**double-asterisk bold**`, `[text](url)` links, and `#` headers render as **plain characters** in Slack — do not use them.
34
+
35
+ ### Required sections, in this exact order
36
+
37
+ 1. **One-sentence summary of the session.**
38
+ Lead with one sentence (no header, no bullets) describing what the user was trying to accomplish in this session and how it went overall (e.g. *"Pulled Q1 sponsored-channel rosters for three brands; ran into a sanitizer rejection on the third query and resolved it via `tl db pg`."*).
39
+
40
+ 2. **User prompts and the work done.**
41
+ Section header `*User prompts and actions taken*`. Then a bulleted list — one bullet per distinct prompt the user issued in the session, in order. Each prompt is the parent bullet (a short paraphrase of what they asked, in quotes). Under each prompt, indent sub-bullets listing every concrete tool call or shell command you ran to handle it. Examples:
42
+
43
+ ```
44
+ • _"Find me Holafly's sponsored channels in the last 6 months"_
45
+ • `tl db pg "SELECT DISTINCT c.id, c.channel_name FROM …"`
46
+ • `tl brands find Holafly`
47
+ • _"Now show their evergreenness scores"_
48
+ • `tl db es '{"aggs":{"channels":{"terms":{"field":"channel.id"}}}}'`
49
+ • `tl db pg "SELECT id, channel_name, evergreenness FROM thoughtleaders_channel WHERE id IN (…)"`
50
+ ```
51
+
52
+ Include every prompt — even ones that were short clarifications. If you used a non-`tl` tool (`jq`, `duckdb`, Read, Edit, Bash), list it too. Do not dump full command output; one line per command is enough.
53
+
54
+ 3. **Analysis section.**
55
+ Section header `*Analysis: problems, frustrations, weaknesses*`. Write a few short paragraphs (no bullets needed) covering, in this order:
56
+ - **Problems / data errors** encountered (e.g. sanitizer rejections, schema mismatches, missing fields, wrong field names, 5xx responses, slow endpoints). Quote the exact error text or command when relevant.
57
+ - **User frustrations** signalled in their messages (impatience, asking the same question twice, "this isn't what I asked for", profanity, abandoning a thread). Be honest — the team needs the actual signal, not a sanitised version. Do not editorialise about whether the frustration was justified.
58
+ - **Weaknesses / gaps in the `tl` CLI or skills** that surfaced. Concrete examples: missing filters, output formats that needed jq post-processing, schema docs that were wrong or out of date, commands that ought to exist but don't, places where you (the agent) had to guess.
59
+ - **What went well** — keep this short (one or two sentences). Skip the section if nothing notably went well.
60
+
61
+ If a category has nothing to report, write *"None observed."* under the heading rather than omitting the heading entirely. Do not invent problems to fill space.
62
+
63
+ 4. **Anything else the user explicitly asked you to include.**
64
+ If the user's "send feedback" request contained a specific message ("tell them the new find command is great"), append it verbatim under a final `*From the user*` section as a block quote.
65
+
66
+ ## After the body is ready
67
+
68
+ Send it with `tl feedback` — pass the body as a single argument (heredoc / `$(cat <<EOF …)` works well for multi-line content):
69
+
70
+ ```bash
71
+ tl feedback "$(cat <<'EOF'
72
+ <the body you composed>
73
+ EOF
74
+ )"
75
+ ```
76
+
77
+ On success the CLI prints `Thanks! Your feedback was sent to the team.` Confirm to the user with a brief, neutral one-liner ("Sent."). Do not echo the full body back to the user — they wrote it with you, they don't need to re-read it.
78
+
79
+ If `tl feedback` exits non-zero (network failure, server error), show the user the raw error and offer to retry. Do not silently swallow failures — feedback that didn't reach Slack is the worst possible outcome here.
80
+
81
+ ## What NOT to do
82
+
83
+ - Do not prepend user name, email, organisation, or admin links to the body. The server adds those.
84
+ - Do not use `**bold**` or `[text](url)` markdown — Slack will print the literal characters.
85
+ - Do not split the report into multiple `tl feedback` calls. One message, one call.
86
+ - Do not invent prompts or commands you did not actually use. If you can't recall, write *"(earlier commands not captured)"*.
87
+ - Do not mark the task complete until `tl feedback` exits 0.
@@ -646,7 +646,7 @@ The view exposes one row per (adlink × brand × channel) and surfaces these col
646
646
  - `organization_id`, `organization_name`, `organization_is_managed_services`
647
647
  - `adlink_owner_advertiser_email`, `adlink_owner_sales_email`
648
648
 
649
- **Important: count and sample MUST be deduped by `adlink_id`.** The view holds one row per `(adlink × brand × channel)` — a single sponsorship that involves multiple brands or multiple channel relations produces multiple rows. Type-8 reports count sponsorship records (AdLinks), not view rows. **Always use `COUNT(DISTINCT adlink_id)` for `db_count` and dedupe samples by `adlink_id`.** A globally-confirmed 184 view rows correspond to fewer underlying adlinks — direct `COUNT(*)` overcounts those cases.
649
+ **Important: count and sample MUST be deduped by `adlink_id`.** The view holds one row per `(adlink × brand × channel)` — a sponsorship spanning multiple brands or channels produces multiple rows. Type-8 counts sponsorship records (AdLinks), not view rows. **Always `COUNT(DISTINCT adlink_id)` for `db_count`; dedupe samples by `adlink_id`.** Direct `COUNT(*)` overcounts multi-brand/multi-channel adlinks.
650
650
 
651
651
  ##### Filter predicate mapping (must mirror the saved FilterSet)
652
652
 
@@ -22,33 +22,31 @@ Phase 1 + 2 disambiguation: report-type synonyms, TL terminology, field-pair cho
22
22
  | **"pipeline"** *(no other context)* | Type 8 with active-stage filter | Default to type 8; confirm. |
23
23
  | **"book of business"** | Type 8 with `tl_sponsorships_only: true` | Default to type 8 + filter; confirm scope. |
24
24
 
25
- ### TL role / pool synonyms
25
+ ### TL role / pool synonyms + TL terminology
26
26
 
27
- | Term | Meaning | Where it shows up |
28
- |---|---|---|
29
- | **MSN** | Media Selling Network — broad ~11K opted-in channel pool | `msn_channels_only` |
30
- | **TPP** | ThoughtLeaders Premier Partners — smaller ~169 high-touch managed pool. **Resolve-and-pin pattern**: `SELECT id FROM thoughtleaders_channel WHERE is_tl_channel = TRUE AND is_active = TRUE ORDER BY id` → put IDs in `filterset.channels`. TPP IS a recognized filter; the implementation detail is resolve-and-pin. | `is_tl_channel = TRUE` resolved → `filterset.channels` |
31
- | **MBN** | Media Buying Network — managed-services advertisers | `cross_references` type `include_sponsored_by_mbn` |
32
- | **AM** / **Account Manager** | Advertiser-side deal owner | `owner_advertiser_name` (in `filters_json` for type 8) |
33
- | **TM** / **Talent Manager** / **Publisher Manager** | Publisher-side deal owner | `owner_publisher_name` (in `filters_json` for type 8) |
27
+ > **Canonical source**: [`tl/references/business-glossary.md`](../../tl/references/business-glossary.md) the canonical home for TL business terminology (MSN, TPP, MBN, AM/TM ownership, View Guarantees, Net revenue, TL profit, performance grade, industry-vs-TL vocabulary translations). Do NOT redefine these terms here; this skill defers to the glossary.
34
28
 
35
- ## TL terminologyuse these
29
+ Quick **FilterSet-mapping reference** (where these business terms appear in the report-builder context for full definitions see the canonical glossary):
36
30
 
37
- | Term | Meaning | Where it shows up |
38
- |---|---|---|
39
- | **Reach** | TL's rolling audience-size metric (not raw YouTube subs) | `reach_from` / `reach_to` |
40
- | **Projected Views (PV)** | Pricing estimate for next video; drives sponsorship pricing | `projected_views_from` / `projected_views_to`; column `Projected Views` |
41
- | **View Guarantee (VG)** | Contractual floor on views for a deal. Type-8 only. | Type 8 columns: `Views Guaranteed`, `Views Guarantee Days` |
42
- | **Net revenue** | TL's earned revenue. NOT "margin." | Type 8 column: `Revenue` |
43
- | **TL profit** | `Price - Cost`. NOT "margin." | Custom formula `{Price} - {Cost}` |
44
- | **Sold sponsorship** | Contractually agreed deal | Type 8 `filters_json.publish_status` |
45
- | **Match / Proposal / Deal** | Funnel: Match (possible) Proposal (offered) → Deal (sold) | `filters_json.publish_status` for type 8 |
31
+ | Term | FilterSet / `filters_json` mapping in this skill |
32
+ |---|---|
33
+ | **MSN** | `msn_channels_only: true` |
34
+ | **TPP** | resolve-and-pin pattern `SELECT id FROM thoughtleaders_channel WHERE is_tl_channel = TRUE AND is_active = TRUE ORDER BY id` → put IDs in `filterset.channels` |
35
+ | **MBN** | `cross_references` type `include_sponsored_by_mbn` |
36
+ | **AM** / Account Manager | `owner_advertiser_name` (in `filters_json` for type 8) |
37
+ | **TM** / Talent Manager | `owner_publisher_name` (in `filters_json` for type 8) |
38
+ | **Reach** | `reach_from` / `reach_to` (narrate as "subscribers" per business-glossary) |
39
+ | **Projected Views (PV)** | `projected_views_from` / `projected_views_to`; column `Projected Views` |
40
+ | **View Guarantee (VG)** | Type 8 columns: `Views Guaranteed`, `Views Guarantee Days` |
41
+ | **Net revenue** | Type 8 column: `Revenue` |
42
+ | **TL profit** | Custom formula `{Price} - {Cost}` (NOT "margin" — see glossary) |
43
+ | **Sold sponsorship / Match / Proposal / Deal** | `filters_json.publish_status` (see "Deal-stage jargon" below for ID mapping) |
46
44
 
47
- ## TL terminology — DON'T use
45
+ ### Industry terms — DON'T emit in config
48
46
 
49
47
  Industry-default terms that don't translate; never put in field names, formulas, columns, or user-facing copy:
50
48
 
51
- - ❌ **"flight"** (MarTech) → say "campaign" or "date range"
49
+ - ❌ **"flight"** (MarTech) → say "campaign" or "date range" (full flight-variant translation lives in [`business-glossary.md`](../../tl/references/business-glossary.md) "Industry Terms vs TL Vocabulary")
52
50
  - ❌ **"hero / hero-tier / hero channel"** → say "high-priority" or "TPP" if appropriate
53
51
  - ❌ **"margin"** (accounting) → say `Net revenue` or `TL profit`
54
52
  - ❌ **"impressions"** in YouTube context → say `Views` or `Projected Views`
@@ -71,7 +69,7 @@ Map informal descriptions → `filters_json.publish_status` IDs (integer; platfo
71
69
  | **"in progress"** / **"active"** | `0, 2, 3, 6` | — | Active incl. sold |
72
70
  | **"live"** / **"currently running"** | `3` | `ad_publish_status: "0"` | Sold AND published |
73
71
 
74
- Status reference: `0` Creator Approved, `1` Unavailable, `2` Pending, `3` Sold, `4` Rejected by Brand, `5` Rejected by Creator, `6` Proposal Approved, `7` Matched, `8` Reached Out, `9` Rejected by Agency.
72
+ Full `publish_status` enum (all 12 codes incl. CLIENT_SIDE_* and pipeline weights) lives at the canonical schema home: [`tl/references/postgres-schema.md` `publish_status` Constants](../../tl/references/postgres-schema.md#publish_status-constants). The NL ID mapping above is what this skill consumes; refer to the schema doc for the full enum and Django-side constants.
75
73
 
76
74
  ## Field-pair disambiguation
77
75
 
@@ -1,3 +1,3 @@
1
1
  """ThoughtLeaders CLI — query sponsorship data, channels, brands, and intelligence."""
2
2
 
3
- __version__ = "0.6.42"
3
+ __version__ = "0.6.43"
@@ -0,0 +1,61 @@
1
+ """tl feedback — Send a markdown-formatted note to the #ai-feedback channel."""
2
+
3
+ import sys
4
+
5
+ import typer
6
+ from rich.console import Console
7
+
8
+ from tl_cli.client.errors import ApiError, handle_api_error
9
+ from tl_cli.client.http import get_client
10
+
11
+
12
+ app = typer.Typer(help="Send feedback about the CLI to the team (free)")
13
+ console = Console(stderr=True)
14
+
15
+
16
+ @app.callback(invoke_without_command=True)
17
+ def feedback(
18
+ ctx: typer.Context,
19
+ text: str = typer.Argument(
20
+ None,
21
+ help='Markdown-formatted feedback. Omit to read from stdin (handy for piping or heredocs).',
22
+ ),
23
+ ) -> None:
24
+ """Send a markdown-formatted note to the ThoughtLeaders team.
25
+
26
+ The server prepends your user/org context and posts everything to the
27
+ #ai-feedback Slack channel. Slack supports a subset of markdown —
28
+ `*bold*`, `_italic_`, `~strike~`, ``code``, ```fences```, `> quotes`,
29
+ and `<url|label>` links. Standard `**bold**`, `[text](url)` links,
30
+ and `#` headers render as plain text in Slack.
31
+
32
+ Examples:
33
+ tl feedback "The new *find* command is great, but it should also accept channel IDs from URLs."
34
+ echo "long note here" | tl feedback
35
+ tl feedback <<< "$(cat note.md)"
36
+ """
37
+ if ctx.invoked_subcommand is not None:
38
+ return
39
+
40
+ body = text
41
+ if body is None:
42
+ if sys.stdin.isatty():
43
+ console.print('[red]Error:[/red] no feedback text provided.')
44
+ console.print('Pass the text as an argument, or pipe it via stdin.')
45
+ raise typer.Exit(1)
46
+ body = sys.stdin.read()
47
+
48
+ body = (body or '').strip()
49
+ if not body:
50
+ console.print('[red]Error:[/red] feedback text is empty.')
51
+ raise typer.Exit(1)
52
+
53
+ client = get_client()
54
+ try:
55
+ client.post('/feedback', json_body={'text': body})
56
+ except ApiError as e:
57
+ handle_api_error(e)
58
+ finally:
59
+ client.close()
60
+
61
+ console.print('[green]Thanks![/green] Your feedback was sent to the team.')
@@ -28,6 +28,7 @@ from tl_cli.commands.sponsorships import app as sponsorships_app
28
28
  from tl_cli.commands.describe import app as describe_app
29
29
  from tl_cli.commands.schema import app as schema_app
30
30
  from tl_cli.commands.doctor import app as doctor_app
31
+ from tl_cli.commands.feedback import app as feedback_app
31
32
  from tl_cli.commands.reports import app as reports_app
32
33
  from tl_cli.commands.setup import app as setup_app
33
34
  from tl_cli.commands.snapshots import app as snapshots_app
@@ -108,6 +109,7 @@ app.add_typer(balance_app, name="balance")
108
109
  app.add_typer(credits_app, name="credits")
109
110
  app.add_typer(doctor_app, name="doctor")
110
111
  app.add_typer(whoami_app, name="whoami")
112
+ app.add_typer(feedback_app, name="feedback")
111
113
 
112
114
  # `changelog` is a single command (not a sub-typer) so positional version args
113
115
  # don't get interpreted as subcommand names.