codex-bot 0.1.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 (64) hide show
  1. codex_bot/__init__.py +24 -0
  2. codex_bot/animation/__init__.py +10 -0
  3. codex_bot/animation/animation_service.py +298 -0
  4. codex_bot/base/__init__.py +22 -0
  5. codex_bot/base/base_orchestrator.py +123 -0
  6. codex_bot/base/context_dto.py +42 -0
  7. codex_bot/base/view_dto.py +93 -0
  8. codex_bot/cli/__init__.py +11 -0
  9. codex_bot/cli/commands.py +215 -0
  10. codex_bot/director/__init__.py +13 -0
  11. codex_bot/director/director.py +107 -0
  12. codex_bot/director/protocols.py +80 -0
  13. codex_bot/engine/__init__.py +13 -0
  14. codex_bot/engine/discovery/__init__.py +7 -0
  15. codex_bot/engine/discovery/service.py +258 -0
  16. codex_bot/engine/factory/__init__.py +7 -0
  17. codex_bot/engine/factory/bot_builder.py +111 -0
  18. codex_bot/engine/http/__init__.py +10 -0
  19. codex_bot/engine/http/api_client.py +123 -0
  20. codex_bot/engine/i18n/__init__.py +7 -0
  21. codex_bot/engine/i18n/locales_compiler.py +83 -0
  22. codex_bot/engine/middlewares/__init__.py +24 -0
  23. codex_bot/engine/middlewares/container.py +46 -0
  24. codex_bot/engine/middlewares/i18n.py +90 -0
  25. codex_bot/engine/middlewares/throttling.py +69 -0
  26. codex_bot/engine/middlewares/user_validation.py +49 -0
  27. codex_bot/engine/router_builder/__init__.py +10 -0
  28. codex_bot/engine/router_builder/router_builder.py +133 -0
  29. codex_bot/fsm/__init__.py +16 -0
  30. codex_bot/fsm/common_fsm_handlers.py +46 -0
  31. codex_bot/fsm/garbage_collector.py +141 -0
  32. codex_bot/fsm/state_helper.py +72 -0
  33. codex_bot/fsm/state_manager.py +104 -0
  34. codex_bot/helper/__init__.py +7 -0
  35. codex_bot/helper/context_helper.py +61 -0
  36. codex_bot/redis/__init__.py +15 -0
  37. codex_bot/redis/dispatcher.py +169 -0
  38. codex_bot/redis/router.py +71 -0
  39. codex_bot/redis/stream_processor.py +210 -0
  40. codex_bot/sender/__init__.py +15 -0
  41. codex_bot/sender/protocols.py +67 -0
  42. codex_bot/sender/sender_keys.py +50 -0
  43. codex_bot/sender/sender_manager.py +85 -0
  44. codex_bot/sender/view_sender.py +200 -0
  45. codex_bot/templates/feature/callbacks.py.tpl +14 -0
  46. codex_bot/templates/feature/contract.py.tpl +12 -0
  47. codex_bot/templates/feature/dto.py.tpl +7 -0
  48. codex_bot/templates/feature/feature.py.tpl +26 -0
  49. codex_bot/templates/feature/feature_redis.py.tpl +6 -0
  50. codex_bot/templates/feature/formatters.py.tpl +15 -0
  51. codex_bot/templates/feature/handlers.py.tpl +32 -0
  52. codex_bot/templates/feature/handlers_redis.py.tpl +24 -0
  53. codex_bot/templates/feature/keyboards.py.tpl +14 -0
  54. codex_bot/templates/feature/orchestrator.py.tpl +26 -0
  55. codex_bot/templates/feature/orchestrator_redis.py.tpl +17 -0
  56. codex_bot/templates/feature/texts.py.tpl +6 -0
  57. codex_bot/templates/feature/ui.py.tpl +19 -0
  58. codex_bot/url_signer/__init__.py +7 -0
  59. codex_bot/url_signer/service.py +116 -0
  60. codex_bot-0.1.0.dist-info/METADATA +116 -0
  61. codex_bot-0.1.0.dist-info/RECORD +64 -0
  62. codex_bot-0.1.0.dist-info/WHEEL +4 -0
  63. codex_bot-0.1.0.dist-info/entry_points.txt +2 -0
  64. codex_bot-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,116 @@
1
+ """
2
+ UrlSignerService — Generation of HMAC-signed URLs for Telegram Mini Apps.
3
+
4
+ Provides protection against link forgery with a limited lifetime.
5
+ """
6
+
7
+ import hashlib
8
+ import hmac
9
+ import time
10
+ from urllib.parse import quote_plus, urlencode
11
+
12
+
13
+ class UrlSignerService:
14
+ """Generation of HMAC-signed URLs for Telegram Mini Apps.
15
+
16
+ Signs URLs using HMAC-SHA256 and a timestamp.
17
+ This protects against forgery and limits the link's lifetime.
18
+
19
+ Args:
20
+ secret_key: Secret key for signing (string).
21
+
22
+ Example:
23
+ ```python
24
+ signer = UrlSignerService(secret_key=settings.secret_key)
25
+ url = signer.generate_signed_url(
26
+ base_url="https://myapp.example.com",
27
+ request_id=42,
28
+ action="reply",
29
+ )
30
+ # https://myapp.example.com/tma/reply/?req_id=42&ts=...&sig=...
31
+ ```
32
+ """
33
+
34
+ def __init__(self, secret_key: str) -> None:
35
+ self._secret_key = secret_key.encode("utf-8")
36
+
37
+ def generate_signed_url(
38
+ self,
39
+ base_url: str,
40
+ request_id: str | int,
41
+ action: str = "reply",
42
+ ) -> str:
43
+ """Generates a signed URL for a WebApp.
44
+
45
+ Builds a URL of the form:
46
+ ``{base_url}/tma/{action}/?req_id=...&ts=...&sig=...``
47
+
48
+ The signature is calculated based on the string ``"{request_id}:{timestamp}"``.
49
+
50
+ Args:
51
+ base_url: Root URL of the site (e.g., ``"https://myapp.example.com"``).
52
+ request_id: Request ID included in the signature.
53
+ action: Action path (default is ``"reply"``).
54
+
55
+ Returns:
56
+ Full URL with signature parameters.
57
+
58
+ Example:
59
+ ```python
60
+ url = signer.generate_signed_url(
61
+ base_url="https://myapp.example.com",
62
+ request_id=123,
63
+ action="confirm",
64
+ )
65
+ ```
66
+ """
67
+ timestamp = str(int(time.time()))
68
+ req_id_str = str(request_id)
69
+
70
+ payload = f"{req_id_str}:{timestamp}".encode()
71
+ signature = hmac.new(self._secret_key, payload, hashlib.sha256).hexdigest()
72
+
73
+ params = {"req_id": req_id_str, "ts": timestamp, "sig": signature}
74
+ clean_base_url = base_url.rstrip("/")
75
+
76
+ return f"{clean_base_url}/tma/{action}/?{urlencode(params, quote_via=quote_plus)}"
77
+
78
+ def verify_signed_url(
79
+ self,
80
+ req_id: str,
81
+ timestamp: str,
82
+ signature: str,
83
+ max_age: int = 300,
84
+ ) -> bool:
85
+ """Verifies the URL signature.
86
+
87
+ Args:
88
+ req_id: Request ID from the ``req_id`` parameter.
89
+ timestamp: Timestamp from the ``ts`` parameter.
90
+ signature: Signature from the ``sig`` parameter.
91
+ max_age: Maximum signature age in seconds (default is 300).
92
+
93
+ Returns:
94
+ ``True`` if the signature is valid and has not expired.
95
+
96
+ Example:
97
+ ```python
98
+ is_valid = signer.verify_signed_url(
99
+ req_id=request.query_params["req_id"],
100
+ timestamp=request.query_params["ts"],
101
+ signature=request.query_params["sig"],
102
+ )
103
+ ```
104
+ """
105
+ try:
106
+ ts_int = int(timestamp)
107
+ except ValueError:
108
+ return False
109
+
110
+ if int(time.time()) - ts_int > max_age:
111
+ return False
112
+
113
+ payload = f"{req_id}:{timestamp}".encode()
114
+ expected = hmac.new(self._secret_key, payload, hashlib.sha256).hexdigest()
115
+
116
+ return hmac.compare_digest(expected, signature)
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.4
2
+ Name: codex-bot
3
+ Version: 0.1.0
4
+ Summary: Feature-based Aiogram framework library — reusable infrastructure for Telegram bots
5
+ Author: Codex Team
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Keywords: aiogram,bot,framework,telegram
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Framework :: AsyncIO
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Communications :: Chat
15
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
16
+ Requires-Python: >=3.12
17
+ Requires-Dist: aiogram<4.0,>=3.4
18
+ Requires-Dist: pydantic<3.0,>=2.0
19
+ Provides-Extra: all
20
+ Requires-Dist: aiogram-i18n>=1.4; extra == 'all'
21
+ Requires-Dist: arq>=0.25; extra == 'all'
22
+ Requires-Dist: httpx<1.0,>=0.27; extra == 'all'
23
+ Requires-Dist: redis[asyncio]<6.0,>=5.0; extra == 'all'
24
+ Provides-Extra: arq
25
+ Requires-Dist: arq>=0.25; extra == 'arq'
26
+ Provides-Extra: dev
27
+ Requires-Dist: bandit>=1.7; extra == 'dev'
28
+ Requires-Dist: mypy>=1.10; extra == 'dev'
29
+ Requires-Dist: pre-commit>=3.0; extra == 'dev'
30
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
31
+ Requires-Dist: pytest-cov; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.4; extra == 'dev'
34
+ Provides-Extra: docs
35
+ Requires-Dist: mkdocs-material>=9.0; extra == 'docs'
36
+ Requires-Dist: mkdocs>=1.5; extra == 'docs'
37
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
38
+ Provides-Extra: http
39
+ Requires-Dist: httpx<1.0,>=0.27; extra == 'http'
40
+ Provides-Extra: i18n
41
+ Requires-Dist: aiogram-i18n>=1.4; extra == 'i18n'
42
+ Provides-Extra: redis
43
+ Requires-Dist: redis[asyncio]<6.0,>=5.0; extra == 'redis'
44
+ Description-Content-Type: text/markdown
45
+
46
+ # Codex Bot Framework
47
+
48
+ [![PyPI version](https://img.shields.io/pypi/v/codex-bot.svg)](https://pypi.org/project/codex-bot/)
49
+ [![Python versions](https://img.shields.io/pypi/pyversions/codex-bot.svg)](https://pypi.org/project/codex-bot/)
50
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
51
+
52
+ **Codex Bot** is a professional, feature-based framework built on top of [Aiogram 3.x](https://github.com/aiogram/aiogram). It provides a reusable, production-ready infrastructure for building complex, scalable Telegram bots with a focus on stateless UI management and high-load Redis integration.
53
+
54
+ ---
55
+
56
+ ## 🚀 Key Features
57
+
58
+ - **Feature-based Architecture**: Organize your bot into independent, reusable features.
59
+ - **Stateless Orchestrators**: Manage UI logic without storing state in memory, making your bot horizontally scalable.
60
+ - **Redis Stream Integration**: Native support for high-load event processing with Consumer Groups.
61
+ - **Advanced FSM**: Automatic UI cleanup with `GarbageStateRegistry` and structured state management.
62
+ - **Unified View System**: Consistent message rendering across different platforms using DTOs.
63
+ - **Fluent-based I18n**: Powerful localization engine with project-level isolation and automatic compilation.
64
+ - **CLI Scaffolding**: Rapidly generate new features with pre-defined templates.
65
+
66
+ ---
67
+
68
+ ## 📦 Installation
69
+
70
+ Install the core library:
71
+ ```bash
72
+ pip install codex-bot
73
+ ```
74
+
75
+ Install with optional dependencies:
76
+ ```bash
77
+ pip install "codex-bot[redis,i18n,http]"
78
+ ```
79
+
80
+ ---
81
+
82
+ ## 🛠 Quick Start
83
+
84
+ ```python
85
+ from codex_bot import BotBuilder, BaseBotOrchestrator, Director
86
+ from codex_bot.base.view_dto import ViewResultDTO
87
+
88
+ # 1. Define your feature orchestrator
89
+ class MyFeatureOrchestrator(BaseBotOrchestrator[None]):
90
+ async def render_content(self, payload: None, director: Director) -> ViewResultDTO:
91
+ return ViewResultDTO(text="Hello from Codex Bot!")
92
+
93
+ # 2. Build and run your bot
94
+ builder = BotBuilder(token="YOUR_TELEGRAM_TOKEN")
95
+ builder.register_orchestrator("main", MyFeatureOrchestrator())
96
+ builder.run_polling()
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 📚 Documentation
102
+
103
+ - [English Documentation](https://codex-team.github.io/codex_bot/en_EN/)
104
+ - [Русская документация](https://codex-team.github.io/codex_bot/ru_RU/)
105
+ - [**Changelog**](CHANGELOG.md) — see what's new in the latest versions.
106
+
107
+ ---
108
+
109
+ ## 📄 License
110
+
111
+ This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details.
112
+
113
+ ---
114
+
115
+ ### 🇷🇺 Краткое описание (RU)
116
+ **Codex Bot** — это профессиональный фреймворк для создания Telegram-ботов на базе Aiogram 3.x. Он предоставляет готовую инфраструктуру для разработки сложных и масштабируемых систем, используя архитектуру на основе "фич", stateless-оркестраторы и глубокую интеграцию с Redis Streams.
@@ -0,0 +1,64 @@
1
+ codex_bot/__init__.py,sha256=i4FE75TbJxcG9ygMDQBBm_iChgZP6FwG4WTXLFPII5M,628
2
+ codex_bot/animation/__init__.py,sha256=2XBHp1mea4gcPlV07jHlIkxnfBvvMMo3nVUdACEXTBo,222
3
+ codex_bot/animation/animation_service.py,sha256=FCbtnMZfh7soxOqeHdDE17GXwU1e1l9_O7KrwiPxowQ,9971
4
+ codex_bot/base/__init__.py,sha256=pA3daayrcwK6zunSqqDGnmnYGLbNOrL0kUoxIl0tPbc,485
5
+ codex_bot/base/base_orchestrator.py,sha256=fiQd8T3d28jN-BBUT-m7RvjQsIBi536x0r2viq8RFd4,4155
6
+ codex_bot/base/context_dto.py,sha256=rUly2txZBpX_Y6o3AqQD-mvRT26B5aSeutpxAkO91hE,1242
7
+ codex_bot/base/view_dto.py,sha256=6byxHY9_wZfeMewPdeOdgDEpVz96GsxA9ARigXL6Jzw,2894
8
+ codex_bot/cli/__init__.py,sha256=8KCnN-1PIk848IAvixrhhl5gpcAxo3yR7gfTTvAAmRQ,217
9
+ codex_bot/cli/commands.py,sha256=G24tL9-XJ4E8RFixMlu9PmZLWwyhqU8zonKhtCFGO6c,7491
10
+ codex_bot/director/__init__.py,sha256=16Ttsvi7_HgiXgn5sDqIOemU6_eK4uAvdVL6XZyMIWY,316
11
+ codex_bot/director/director.py,sha256=-KLOAWiaFV-VWa6tW4DIctbSst3Af97HE8q4LONP4kc,3878
12
+ codex_bot/director/protocols.py,sha256=HV36pEnerBzE7s9ite9wMeNLPG5ZAVIVLhV3hJiseD8,2315
13
+ codex_bot/engine/__init__.py,sha256=7diEGgyoEzq7cJqEhLkDxt8VsYv-o2x3627IKRFObgQ,715
14
+ codex_bot/engine/discovery/__init__.py,sha256=Wj2Z8DCofYfeZSLZjDXWgKkkY9XRN5RW8e1ok_qxcU4,186
15
+ codex_bot/engine/discovery/service.py,sha256=NzQmZj92HvSkRCHpk04-g-d4ryFclwJop9wKpIa_9WY,9994
16
+ codex_bot/engine/factory/__init__.py,sha256=AdOmNzrbGamgPF5nhC425mzM1GTti7N8KhnjxeCVJ2E,166
17
+ codex_bot/engine/factory/bot_builder.py,sha256=NQHRLNXBeg7Ih7NdH0HXz2c0ZJnANFR3W4ztXPowiPg,3577
18
+ codex_bot/engine/http/__init__.py,sha256=XRpHndeYd3advmtKMeXNOZg_DvyVS30_YcW66Bc7Dh4,192
19
+ codex_bot/engine/http/api_client.py,sha256=ERlBSLtF5vNO0HeAK5qJK-rkenz2fhbuEmwszdJAuFo,3949
20
+ codex_bot/engine/i18n/__init__.py,sha256=q75bVn4OhlwQvbw08j--BxDApNZeAdSnUC5THmeNTUA,171
21
+ codex_bot/engine/i18n/locales_compiler.py,sha256=5h-lH_7C25BFudY096tLBrZPcgXtY3D5o6K8Z8FDHM0,3006
22
+ codex_bot/engine/middlewares/__init__.py,sha256=aSKBUER9Q9p6T7DzFqOPoO7OLC-9Q0cfTe2UtibnVqo,899
23
+ codex_bot/engine/middlewares/container.py,sha256=ZYcx1u789jySMFcysWtQD1ejktWabNxu_blptFpzJnw,1376
24
+ codex_bot/engine/middlewares/i18n.py,sha256=TJyDmh4iH_h5EXSy9bp_eJ_ohgKKBlMdee5rB29fkOs,2849
25
+ codex_bot/engine/middlewares/throttling.py,sha256=Q9UIlHElqYWLavbsZ5itXOyxTbzzJqB1F6q7dw74X1M,2338
26
+ codex_bot/engine/middlewares/user_validation.py,sha256=33bKB2Pd8JLzw0W434kGsleo0XcqDMegFS2bp7-PVsA,1519
27
+ codex_bot/engine/router_builder/__init__.py,sha256=bCF3AfTQqykHMHf9xakkldRc_3RwvHJt2XSn0B0adLU,258
28
+ codex_bot/engine/router_builder/router_builder.py,sha256=3Z6UDLw-K0YTYCOiZKixgfxDabpJVR62CC78Bh5dKtU,4852
29
+ codex_bot/fsm/__init__.py,sha256=pmxqkx9agSj-ly7bkVpl4EMm3cvt_2BbybJPfBao0og,426
30
+ codex_bot/fsm/common_fsm_handlers.py,sha256=0zZAFI3Rvjnprb545z3qp69S9DMiaz_QzovMBsTH66A,1524
31
+ codex_bot/fsm/garbage_collector.py,sha256=qZdPzsAi3o_YqeOxLBipRkZboCALJFetcXTwo0uaB6E,4223
32
+ codex_bot/fsm/state_helper.py,sha256=0_BTUncXfkZqWorTuJSwThtuaDm9_sXTIYBriHlEhhE,2178
33
+ codex_bot/fsm/state_manager.py,sha256=EeNSWKlwDauuvuN0lh1Nks6zE9zzxWGOZfmfBFT8FXk,3128
34
+ codex_bot/helper/__init__.py,sha256=Ds3_jmp1dBQukVLoz7DlqDCNYI78_iIGMDFrSk2WE-E,172
35
+ codex_bot/helper/context_helper.py,sha256=BTYdld7Akx0T8pIste8fjGqgeKD3mnv_NQzbzQrK3lg,1896
36
+ codex_bot/redis/__init__.py,sha256=mC7QUFTHgFeuwo3YrDFiTiFQYWtxq67I_eaEYvLLueM,442
37
+ codex_bot/redis/dispatcher.py,sha256=zPMH-V9FyygsRLx1E_LdgzJLEStqWCKnWhL6Ig7-ntI,5976
38
+ codex_bot/redis/router.py,sha256=6XysipG2Kc5srgZRn2MUuYTrycct6o7m2vnRt5ba-cE,2281
39
+ codex_bot/redis/stream_processor.py,sha256=oig3XGCsWP71mqrAP2Xun9SDUh9IOcHwSPuVxA3h4-E,7677
40
+ codex_bot/sender/__init__.py,sha256=hJKDzaSor4rVxqMCI4SYRdhQzuOaj_J_i4IaDvBM2U8,428
41
+ codex_bot/sender/protocols.py,sha256=OGQCqRXNg6x0prZf1NUuY_vh8HfziVMfl8fjwtHS4lY,2138
42
+ codex_bot/sender/sender_keys.py,sha256=xp5SXpW8w0T5mcF7dYShlVlg3RZBOFy06-ew0FRpQLU,1300
43
+ codex_bot/sender/sender_manager.py,sha256=7WJeDh_fJvz_CFYrTIqN6ixTMcHH6FLz5rupCrIdzpg,2805
44
+ codex_bot/sender/view_sender.py,sha256=qNSUyI7CLfqFMKivxN71jhwZlyBDsal3xs2gv0Y6oNQ,7170
45
+ codex_bot/templates/feature/callbacks.py.tpl,sha256=yZ9OYg2eW_5uOreSvi111SsRROezmbPhEd-J-E6oPXY,564
46
+ codex_bot/templates/feature/contract.py.tpl,sha256=0muFQG9BwyRAEpO6oD85a17h1fk-Lwwg87tGYnuxL7A,318
47
+ codex_bot/templates/feature/dto.py.tpl,sha256=GtTL3A641Web3IWJJVmx86OVkEEcZp8VoeIeT8-KLls,174
48
+ codex_bot/templates/feature/feature.py.tpl,sha256=FovoRZDZ1QdJprSJ929_GRD85eoVIZnqBktH1Ok2B5g,634
49
+ codex_bot/templates/feature/feature_redis.py.tpl,sha256=g7k0pppF5OTmtoT7sDv4x2UqZ-sPKV6pp5_oaDm0oVw,223
50
+ codex_bot/templates/feature/formatters.py.tpl,sha256=B-AeWaBs7hYYyfwaq5xuL9C_Fr3w9xokHBonZp25PQY,492
51
+ codex_bot/templates/feature/handlers.py.tpl,sha256=ncCRGUG1pApgId7dvjMRKrTA3PRB3uPn-FLELS2TkEY,934
52
+ codex_bot/templates/feature/handlers_redis.py.tpl,sha256=d8_iReh-K90kMjKsqxcEeITjo4dInbVJK1Rz_KDdPqo,797
53
+ codex_bot/templates/feature/keyboards.py.tpl,sha256=kDLRQWN_rVLrqI4gdZgQQmyprts2Uhpc9kR0dRgu-Qo,430
54
+ codex_bot/templates/feature/orchestrator.py.tpl,sha256=zmDDKXxGKzApv3d_IpqlH2-xHN0UPagwYHl1KORcqKo,911
55
+ codex_bot/templates/feature/orchestrator_redis.py.tpl,sha256=uAWf1m8WFSGro7zjwC5SXv98csg0jilathDCE3EjXMs,499
56
+ codex_bot/templates/feature/texts.py.tpl,sha256=QLskrg0esJD03DbAN3em7gCB5uHXxXyWnBaivcFUEp4,257
57
+ codex_bot/templates/feature/ui.py.tpl,sha256=3XFtPCjNvkXwFa3X8ymgO6vWphL2MHSuWB9viKbwYac,562
58
+ codex_bot/url_signer/__init__.py,sha256=8nQJHsnFNUIY9IRlYCNH4iOSWLRHJgcYcG7Vt5auvBs,156
59
+ codex_bot/url_signer/service.py,sha256=OqLa1Y_P2SgEa38Gh0dw553vPL7iD86d0iDtnXnzMs4,3513
60
+ codex_bot-0.1.0.dist-info/METADATA,sha256=2c8tDw2jE25SEP2YLR1_eWkyB1fZJPKDUQKYjIQhxik,4752
61
+ codex_bot-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
62
+ codex_bot-0.1.0.dist-info/entry_points.txt,sha256=qcXUNOjDOmIDwKegdbSQmrB1SFioo7zILnKmQo0nYjk,49
63
+ codex_bot-0.1.0.dist-info/licenses/LICENSE,sha256=hWy4ZuZrIx8qyauWVRZG22OeMnH21JHK053SG7DRQDs,1065
64
+ codex_bot-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ codex-bot = codex_bot.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CodexDLC
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.