gitcast 1.0.0__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 (81) hide show
  1. gitcast-1.0.0/.env.example +26 -0
  2. gitcast-1.0.0/LICENSE +21 -0
  3. gitcast-1.0.0/MANIFEST.in +7 -0
  4. gitcast-1.0.0/PKG-INFO +77 -0
  5. gitcast-1.0.0/README.md +35 -0
  6. gitcast-1.0.0/ai/__init__.py +0 -0
  7. gitcast-1.0.0/ai/formatter.py +59 -0
  8. gitcast-1.0.0/ai/generator.py +604 -0
  9. gitcast-1.0.0/ai/prompts.py +197 -0
  10. gitcast-1.0.0/ai/viral_patterns.py +75 -0
  11. gitcast-1.0.0/api/__init__.py +0 -0
  12. gitcast-1.0.0/api/analytics.py +48 -0
  13. gitcast-1.0.0/api/auth.py +49 -0
  14. gitcast-1.0.0/api/auth_middleware.py +129 -0
  15. gitcast-1.0.0/api/auth_routes.py +117 -0
  16. gitcast-1.0.0/api/monitoring.py +56 -0
  17. gitcast-1.0.0/api/payload.py +253 -0
  18. gitcast-1.0.0/api/ratelimit.py +9 -0
  19. gitcast-1.0.0/api/routes.py +1565 -0
  20. gitcast-1.0.0/api/server.py +162 -0
  21. gitcast-1.0.0/api/validators.py +101 -0
  22. gitcast-1.0.0/assets/favicon-16x16.png +0 -0
  23. gitcast-1.0.0/assets/favicon-32x32.png +0 -0
  24. gitcast-1.0.0/assets/favicon-64x64.png +0 -0
  25. gitcast-1.0.0/assets/favicon.ico +0 -0
  26. gitcast-1.0.0/assets/icon.png +0 -0
  27. gitcast-1.0.0/cli/__init__.py +1 -0
  28. gitcast-1.0.0/cli/gitcast.py +56 -0
  29. gitcast-1.0.0/config/__init__.py +0 -0
  30. gitcast-1.0.0/config/settings.py +213 -0
  31. gitcast-1.0.0/core/__init__.py +0 -0
  32. gitcast-1.0.0/core/capture.py +258 -0
  33. gitcast-1.0.0/core/codebase_reader.py +90 -0
  34. gitcast-1.0.0/core/framing.py +86 -0
  35. gitcast-1.0.0/core/hotkey.py +21 -0
  36. gitcast-1.0.0/core/log_stream.py +50 -0
  37. gitcast-1.0.0/core/ocr.py +173 -0
  38. gitcast-1.0.0/core/screenshot_session.py +274 -0
  39. gitcast-1.0.0/core/security.py +126 -0
  40. gitcast-1.0.0/core/tray.py +54 -0
  41. gitcast-1.0.0/docs/api-keys.md +77 -0
  42. gitcast-1.0.0/docs/article-generator.md +45 -0
  43. gitcast-1.0.0/docs/capture-flow.md +50 -0
  44. gitcast-1.0.0/docs/changelog.md +33 -0
  45. gitcast-1.0.0/docs/contributing.md +54 -0
  46. gitcast-1.0.0/docs/dashboard.md +55 -0
  47. gitcast-1.0.0/docs/insights.md +46 -0
  48. gitcast-1.0.0/docs/introduction.md +35 -0
  49. gitcast-1.0.0/docs/post-formats.md +46 -0
  50. gitcast-1.0.0/docs/providers.md +46 -0
  51. gitcast-1.0.0/docs/quickstart.md +80 -0
  52. gitcast-1.0.0/docs/sprint-mode.md +37 -0
  53. gitcast-1.0.0/gitcast.egg-info/PKG-INFO +77 -0
  54. gitcast-1.0.0/gitcast.egg-info/SOURCES.txt +79 -0
  55. gitcast-1.0.0/gitcast.egg-info/dependency_links.txt +1 -0
  56. gitcast-1.0.0/gitcast.egg-info/entry_points.txt +2 -0
  57. gitcast-1.0.0/gitcast.egg-info/requires.txt +20 -0
  58. gitcast-1.0.0/gitcast.egg-info/top_level.txt +8 -0
  59. gitcast-1.0.0/publisher/__init__.py +0 -0
  60. gitcast-1.0.0/publisher/clipboard.py +44 -0
  61. gitcast-1.0.0/publisher/twitter.py +100 -0
  62. gitcast-1.0.0/pyproject.toml +3 -0
  63. gitcast-1.0.0/requirements.txt +20 -0
  64. gitcast-1.0.0/setup.cfg +4 -0
  65. gitcast-1.0.0/setup.py +39 -0
  66. gitcast-1.0.0/storage/__init__.py +0 -0
  67. gitcast-1.0.0/storage/cleanup.py +60 -0
  68. gitcast-1.0.0/storage/engagement.py +114 -0
  69. gitcast-1.0.0/storage/insights.py +203 -0
  70. gitcast-1.0.0/storage/key_manager.py +45 -0
  71. gitcast-1.0.0/storage/logger.py +208 -0
  72. gitcast-1.0.0/storage/metrics.py +119 -0
  73. gitcast-1.0.0/storage/sprint.py +40 -0
  74. gitcast-1.0.0/storage/streak.py +0 -0
  75. gitcast-1.0.0/storage/supabase_client.py +25 -0
  76. gitcast-1.0.0/storage/tone_memory.py +139 -0
  77. gitcast-1.0.0/tests/test_keys.py +86 -0
  78. gitcast-1.0.0/tests/test_ocr_fix.py +77 -0
  79. gitcast-1.0.0/ui/__init__.py +0 -0
  80. gitcast-1.0.0/web/index.html +4994 -0
  81. gitcast-1.0.0/web/landing.html +925 -0
@@ -0,0 +1,26 @@
1
+ # Groq — primary AI inference
2
+ GROQ_API_KEY=your_groq_api_key_here
3
+
4
+ # DeepSeek & Moonshot — specialized/free-tier fallbacks
5
+ DEEPSEEK_API_KEY=your_deepseek_api_key_here
6
+ MOONSHOT_API_KEY=your_moonshot_api_key_here
7
+ CEREBRAS_API_KEY=your_cerebras_api_key_here
8
+ OPENROUTER_API_KEY=your_openrouter_api_key_here
9
+
10
+ # Gemini — vision fallback (when OCR confidence is too low)
11
+ GEMINI_API_KEY=your_gemini_api_key_here
12
+
13
+ # Optional model overrides
14
+ GROQ_MODEL=llama-3.3-70b-versatile
15
+ DEEPSEEK_MODEL=deepseek-chat
16
+ MOONSHOT_MODEL=moonshot-v1-8k
17
+ GEMINI_MODEL=gemini-2.0-flash
18
+ CEREBRAS_MODEL=llama-3.3-70b
19
+ OPENROUTER_MODEL=meta-llama/llama-3.3-70b-instruct:free
20
+
21
+ # X (Twitter) API v2 — all five are required for posting
22
+ TWITTER_API_KEY=your_twitter_api_key_here
23
+ TWITTER_API_SECRET=your_twitter_api_secret_here
24
+ TWITTER_ACCESS_TOKEN=your_twitter_access_token_here
25
+ TWITTER_ACCESS_SECRET=your_twitter_access_secret_here
26
+ TWITTER_BEARER_TOKEN=your_twitter_bearer_token_here
gitcast-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Timilehin Agoro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include README.md
2
+ include LICENSE
3
+ include .env.example
4
+ include requirements.txt
5
+ recursive-include web *
6
+ recursive-include assets *
7
+ recursive-include docs *
gitcast-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,77 @@
1
+ Metadata-Version: 2.4
2
+ Name: gitcast
3
+ Version: 1.0.0
4
+ Summary: git diff → published post. under 60 seconds.
5
+ Home-page: https://github.com/drizzy765/gitcast
6
+ Author: Timilehin Agoro
7
+ Author-email: agorotimilehi05@gmail.com
8
+ License: MIT
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: pynput
13
+ Requires-Dist: pystray
14
+ Requires-Dist: Pillow
15
+ Requires-Dist: fastapi
16
+ Requires-Dist: uvicorn
17
+ Requires-Dist: python-dotenv
18
+ Requires-Dist: groq
19
+ Requires-Dist: tweepy
20
+ Requires-Dist: mss
21
+ Requires-Dist: pytesseract
22
+ Requires-Dist: httpx
23
+ Requires-Dist: supabase
24
+ Requires-Dist: cryptography
25
+ Requires-Dist: python-jose[cryptography]
26
+ Requires-Dist: rich
27
+ Requires-Dist: keyboard
28
+ Requires-Dist: slowapi
29
+ Requires-Dist: limits
30
+ Requires-Dist: sentry-sdk[fastapi]
31
+ Requires-Dist: posthog
32
+ Dynamic: author
33
+ Dynamic: author-email
34
+ Dynamic: description
35
+ Dynamic: description-content-type
36
+ Dynamic: home-page
37
+ Dynamic: license
38
+ Dynamic: license-file
39
+ Dynamic: requires-dist
40
+ Dynamic: requires-python
41
+ Dynamic: summary
42
+
43
+ # Gitcast
44
+
45
+ On-demand, privacy-first desktop utility that captures active window context,
46
+ extracts code changes, and generates platform-ready X (Twitter) posts with one keystroke.
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pip install gitcast
52
+ ```
53
+
54
+ ## Setup
55
+
56
+ 1. Install Tesseract OCR:
57
+ - Windows: https://github.com/UB-Mannheim/tesseract/wiki
58
+ - Mac: `brew install tesseract`
59
+ - Linux: `sudo apt install tesseract-ocr`
60
+
61
+ 2. Add your API keys:
62
+ ```bash
63
+ gitcast --setup
64
+ ```
65
+ (opens `.env` file for editing)
66
+
67
+ 3. Run:
68
+ ```bash
69
+ gitcast
70
+ ```
71
+
72
+ Dashboard opens at http://127.0.0.1:8000
73
+ Press Ctrl+Shift+P from anywhere to capture.
74
+
75
+ ## Stack
76
+ - Python 3.11+
77
+ - FastAPI, pynput, mss, Tesseract, Groq API, Tweepy
@@ -0,0 +1,35 @@
1
+ # Gitcast
2
+
3
+ On-demand, privacy-first desktop utility that captures active window context,
4
+ extracts code changes, and generates platform-ready X (Twitter) posts with one keystroke.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ pip install gitcast
10
+ ```
11
+
12
+ ## Setup
13
+
14
+ 1. Install Tesseract OCR:
15
+ - Windows: https://github.com/UB-Mannheim/tesseract/wiki
16
+ - Mac: `brew install tesseract`
17
+ - Linux: `sudo apt install tesseract-ocr`
18
+
19
+ 2. Add your API keys:
20
+ ```bash
21
+ gitcast --setup
22
+ ```
23
+ (opens `.env` file for editing)
24
+
25
+ 3. Run:
26
+ ```bash
27
+ gitcast
28
+ ```
29
+
30
+ Dashboard opens at http://127.0.0.1:8000
31
+ Press Ctrl+Shift+P from anywhere to capture.
32
+
33
+ ## Stack
34
+ - Python 3.11+
35
+ - FastAPI, pynput, mss, Tesseract, Groq API, Tweepy
File without changes
@@ -0,0 +1,59 @@
1
+ import re
2
+
3
+ # [Formatter] module for post cleaning and thread splitting
4
+
5
+ def split_into_thread(post_text: str, max_chars: int = 270) -> list[str]:
6
+ """
7
+ Splits text into multiple tweets at sentence boundaries.
8
+ Numbers each tweet: 1/ 2/ 3/
9
+ """
10
+ if len(post_text) <= 280:
11
+ return [post_text]
12
+
13
+ # Split into sentences (basic regex split)
14
+ sentences = re.split(r'(?<=[.!?])\s+', post_text.strip())
15
+
16
+ tweets = []
17
+ current_tweet = ""
18
+ tweet_number = 1
19
+
20
+ for sentence in sentences:
21
+ # Check if adding this sentence exceeds limit (considering "N/ " prefix)
22
+ prefix = f"{tweet_number}/ "
23
+ potential_content = current_tweet + (" " if current_tweet else "") + sentence
24
+
25
+ if len(prefix + potential_content) <= max_chars:
26
+ current_tweet = potential_content
27
+ else:
28
+ if current_tweet:
29
+ tweets.append(f"{tweet_number}/ {current_tweet}")
30
+ tweet_number += 1
31
+
32
+ # If a single sentence is too long, we must split it by words
33
+ if len(f"{tweet_number}/ {sentence}") > max_chars:
34
+ words = sentence.split()
35
+ sub_tweet = ""
36
+ for word in words:
37
+ if len(f"{tweet_number}/ {sub_tweet} {word}") <= max_chars:
38
+ sub_tweet = f"{sub_tweet} {word}".strip()
39
+ else:
40
+ tweets.append(f"{tweet_number}/ {sub_tweet}...")
41
+ tweet_number += 1
42
+ sub_tweet = word
43
+ current_tweet = sub_tweet
44
+ else:
45
+ current_tweet = sentence
46
+
47
+ if current_tweet:
48
+ tweets.append(f"{tweet_number}/ {current_tweet}")
49
+
50
+ return tweets
51
+
52
+ if __name__ == "__main__":
53
+ print("=== THREAD SPLITTER TEST ===")
54
+ long_post = "This is a very long post that should be split into multiple tweets. It contains many sentences. Each sentence is relatively short but together they exceed the limit of a single tweet. We want to see how the formatter handles this situation by splitting at sentence boundaries and numbering the resulting tweets correctly."
55
+
56
+ # Force small limit for testing
57
+ result = split_into_thread(long_post, max_chars=100)
58
+ for t in result:
59
+ print(f"[{len(t)} chars] {t}")