thoughtleaders-cli 0.5.0__py3-none-any.whl

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 (59) hide show
  1. thoughtleaders_cli-0.5.0.dist-info/METADATA +215 -0
  2. thoughtleaders_cli-0.5.0.dist-info/RECORD +59 -0
  3. thoughtleaders_cli-0.5.0.dist-info/WHEEL +4 -0
  4. thoughtleaders_cli-0.5.0.dist-info/entry_points.txt +2 -0
  5. thoughtleaders_cli-0.5.0.dist-info/licenses/LICENSE +21 -0
  6. tl_cli/__init__.py +3 -0
  7. tl_cli/_completions.py +4 -0
  8. tl_cli/_plugin/.claude-plugin/marketplace.json +17 -0
  9. tl_cli/_plugin/.claude-plugin/plugin.json +12 -0
  10. tl_cli/_plugin/agents/tl-analyst.md +66 -0
  11. tl_cli/_plugin/commands/tl-balance.md +10 -0
  12. tl_cli/_plugin/commands/tl-brands.md +16 -0
  13. tl_cli/_plugin/commands/tl-channels.md +31 -0
  14. tl_cli/_plugin/commands/tl-reports.md +16 -0
  15. tl_cli/_plugin/commands/tl-sponsorships.md +23 -0
  16. tl_cli/_plugin/commands/tl.md +28 -0
  17. tl_cli/_plugin/hooks/hooks.json +26 -0
  18. tl_cli/_plugin/hooks/scripts/post-usage.sh +26 -0
  19. tl_cli/_plugin/hooks/scripts/pre-check.sh +30 -0
  20. tl_cli/_plugin/skills/tl/SKILL.md +413 -0
  21. tl_cli/_plugin/skills/tl/references/business-glossary.md +159 -0
  22. tl_cli/_plugin/skills/tl/references/elasticsearch-schema.md +259 -0
  23. tl_cli/_plugin/skills/tl/references/firebolt-schema.md +208 -0
  24. tl_cli/_plugin/skills/tl/references/postgres-schema.md +269 -0
  25. tl_cli/auth/__init__.py +0 -0
  26. tl_cli/auth/commands.py +49 -0
  27. tl_cli/auth/login.py +328 -0
  28. tl_cli/auth/pkce.py +21 -0
  29. tl_cli/auth/token_store.py +98 -0
  30. tl_cli/client/__init__.py +0 -0
  31. tl_cli/client/errors.py +72 -0
  32. tl_cli/client/http.py +109 -0
  33. tl_cli/commands/__init__.py +0 -0
  34. tl_cli/commands/ask.py +54 -0
  35. tl_cli/commands/balance.py +68 -0
  36. tl_cli/commands/brands.py +174 -0
  37. tl_cli/commands/changelog.py +119 -0
  38. tl_cli/commands/channels.py +291 -0
  39. tl_cli/commands/comments.py +63 -0
  40. tl_cli/commands/db.py +104 -0
  41. tl_cli/commands/deals.py +52 -0
  42. tl_cli/commands/describe.py +166 -0
  43. tl_cli/commands/doctor.py +70 -0
  44. tl_cli/commands/matches.py +69 -0
  45. tl_cli/commands/proposals.py +69 -0
  46. tl_cli/commands/reports.py +346 -0
  47. tl_cli/commands/schema.py +55 -0
  48. tl_cli/commands/setup.py +401 -0
  49. tl_cli/commands/snapshots.py +93 -0
  50. tl_cli/commands/sponsorships.py +193 -0
  51. tl_cli/commands/uploads.py +84 -0
  52. tl_cli/commands/whoami.py +206 -0
  53. tl_cli/config.py +55 -0
  54. tl_cli/filters.py +88 -0
  55. tl_cli/hints.py +53 -0
  56. tl_cli/main.py +209 -0
  57. tl_cli/output/__init__.py +0 -0
  58. tl_cli/output/formatter.py +436 -0
  59. tl_cli/self_update.py +173 -0
tl_cli/self_update.py ADDED
@@ -0,0 +1,173 @@
1
+ """Post-command version check and auto-upgrade for pipx/uv installs.
2
+
3
+ Runs once per CLI invocation via atexit. Skipped for dev / pip installs
4
+ (we only know how to upgrade pipx and `uv tool` installations cleanly).
5
+
6
+ Network fetches are cached for 1 hour in ~/.cache/tl-cli/version-check.json,
7
+ so repeated invocations don't hammer the GitHub API.
8
+
9
+ All failure paths are silent — version-check issues must never break the
10
+ user's actual command output.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import json
16
+ import subprocess
17
+ import sys
18
+ import time
19
+ import urllib.error
20
+ import urllib.request
21
+ from pathlib import Path
22
+
23
+ from tl_cli import __version__
24
+
25
+ CACHE_PATH = Path.home() / ".cache" / "tl-cli" / "version-check.json"
26
+ CACHE_TTL_SECONDS = 3600 # 1 hour
27
+ LATEST_URL = "https://api.github.com/repos/ThoughtLeaders-io/thoughtleaders-cli/releases/latest"
28
+ REQUEST_TIMEOUT = 2 # tight — the user is already waiting to see their shell prompt back
29
+
30
+
31
+ def _detect_install_method() -> str | None:
32
+ """Return 'pipx', 'uv', or None (dev/pip install — don't auto-upgrade).
33
+
34
+ Both the new distribution name (`thoughtleaders-cli`) and the legacy one
35
+ (`tl-cli`) are matched so users who installed before the rename keep
36
+ auto-updating.
37
+ """
38
+ exe = sys.executable
39
+ for dist_name in ("thoughtleaders-cli", "tl-cli"):
40
+ if f"/pipx/venvs/{dist_name}/" in exe:
41
+ return "pipx"
42
+ if f"/uv/tools/{dist_name}/" in exe:
43
+ return "uv"
44
+ return None
45
+
46
+
47
+ def _read_cache() -> dict | None:
48
+ try:
49
+ cache = json.loads(CACHE_PATH.read_text())
50
+ except (OSError, json.JSONDecodeError):
51
+ return None
52
+ if time.time() - cache.get("checked_at", 0) >= CACHE_TTL_SECONDS:
53
+ return None
54
+ return cache
55
+
56
+
57
+ def _write_cache(latest: str | None) -> None:
58
+ try:
59
+ CACHE_PATH.parent.mkdir(parents=True, exist_ok=True)
60
+ CACHE_PATH.write_text(json.dumps({"checked_at": time.time(), "latest": latest}))
61
+ except OSError as e:
62
+ print(f"Error writing cache: {e}", file=sys.stderr)
63
+ pass
64
+
65
+
66
+ def _fetch_latest_version() -> str | None:
67
+ """Fetch latest release tag from GitHub. Returns the plain version
68
+ string (e.g. '0.4.2') or None on any failure."""
69
+ try:
70
+ req = urllib.request.Request(
71
+ LATEST_URL,
72
+ headers={
73
+ "Accept": "application/vnd.github+json",
74
+ "User-Agent": f"tl-cli/{__version__}",
75
+ },
76
+ )
77
+ with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT) as resp:
78
+ data = json.load(resp)
79
+ except (urllib.error.URLError, TimeoutError, json.JSONDecodeError, OSError):
80
+ return None
81
+ tag = (data.get("tag_name") or "").lstrip("v")
82
+ return tag or None
83
+
84
+
85
+ def _version_tuple(v: str) -> tuple[int, ...]:
86
+ return tuple(int(p) for p in v.split(".") if p.isdigit())
87
+
88
+
89
+ REPO_URL = "https://github.com/ThoughtLeaders-io/thoughtleaders-cli.git"
90
+
91
+
92
+ def _run_upgrade(method: str, latest: str) -> None:
93
+ """Block briefly to run the upgrade. Progress goes to stderr so piped
94
+ stdout stays clean.
95
+
96
+ Uses `install --force` with the new tag URL. pipx/uv pin the original
97
+ install spec including the git tag, so a plain `upgrade` re-installs
98
+ the same version — `--force` is the only way to advance the pinned tag.
99
+ """
100
+ tagged_url = f"git+{REPO_URL}@v{latest}"
101
+ cmd = {
102
+ "pipx": ["pipx", "install", "--force", tagged_url],
103
+ "uv": ["uv", "tool", "install", "--force", tagged_url],
104
+ }.get(method)
105
+ if not cmd:
106
+ return
107
+ print(
108
+ f"[tl-cli] upgrading {__version__} → {latest} via {method}…",
109
+ file=sys.stderr,
110
+ )
111
+ try:
112
+ subprocess.run(cmd, check=False, timeout=60)
113
+ except (OSError, subprocess.TimeoutExpired):
114
+ pass
115
+
116
+
117
+ def check_and_upgrade() -> None:
118
+ """Entry point. Runs via atexit; silent on every failure path."""
119
+ try:
120
+ method = _detect_install_method()
121
+ if not method:
122
+ return
123
+
124
+ cache = _read_cache()
125
+ if cache is None:
126
+ latest = _fetch_latest_version()
127
+ _write_cache(latest)
128
+ else:
129
+ latest = cache.get("latest")
130
+
131
+ if not latest:
132
+ return
133
+ try:
134
+ if _version_tuple(latest) <= _version_tuple(__version__):
135
+ return
136
+ except ValueError:
137
+ return
138
+
139
+ _run_upgrade(method, latest)
140
+ except Exception:
141
+ # Never let a version-check bug break the user's workflow.
142
+ pass
143
+
144
+
145
+ def force_upgrade() -> None:
146
+ """Explicitly requested upgrade — bypasses cache, prints verbose output."""
147
+ method = _detect_install_method()
148
+ if not method:
149
+ print(
150
+ "tl-cli was not installed via pipx or uv — cannot auto-upgrade.\n"
151
+ "Update it with the same tool you used to install it.",
152
+ file=sys.stderr,
153
+ )
154
+ sys.exit(1)
155
+
156
+ print(f"Checking for updates (current: {__version__})…", file=sys.stderr)
157
+ latest = _fetch_latest_version()
158
+ if latest is None:
159
+ print("Could not reach GitHub to check for updates.", file=sys.stderr)
160
+ sys.exit(1)
161
+
162
+ _write_cache(latest)
163
+
164
+ try:
165
+ newer = _version_tuple(latest) > _version_tuple(__version__)
166
+ except ValueError:
167
+ newer = False
168
+
169
+ if not newer:
170
+ print(f"tl-cli {__version__} is already the latest version.", file=sys.stderr)
171
+ return
172
+
173
+ _run_upgrade(method, latest)