kryncord 0.1.0b1__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 (241) hide show
  1. kryncord-0.1.0b1/.gitignore +58 -0
  2. kryncord-0.1.0b1/CHANGELOG.md +36 -0
  3. kryncord-0.1.0b1/LICENSE +21 -0
  4. kryncord-0.1.0b1/PKG-INFO +209 -0
  5. kryncord-0.1.0b1/README.md +177 -0
  6. kryncord-0.1.0b1/docs/README.md +38 -0
  7. kryncord-0.1.0b1/docs/api/components-v1.md +507 -0
  8. kryncord-0.1.0b1/docs/api/components-v2-and-modals.md +679 -0
  9. kryncord-0.1.0b1/docs/decisions/0001-http-transport.md +41 -0
  10. kryncord-0.1.0b1/docs/decisions/0002-websocket-transport.md +38 -0
  11. kryncord-0.1.0b1/docs/decisions/0003-data-models.md +49 -0
  12. kryncord-0.1.0b1/docs/decisions/0004-build-order.md +54 -0
  13. kryncord-0.1.0b1/docs/decisions/0005-gateway-reconnect.md +72 -0
  14. kryncord-0.1.0b1/docs/decisions/0006-event-dispatch.md +121 -0
  15. kryncord-0.1.0b1/docs/decisions/0007-api-layer.md +175 -0
  16. kryncord-0.1.0b1/docs/decisions/0008-cache-and-state.md +362 -0
  17. kryncord-0.1.0b1/docs/decisions/0009-command-responder-surface.md +226 -0
  18. kryncord-0.1.0b1/docs/decisions/0010-client-options.md +137 -0
  19. kryncord-0.1.0b1/docs/decisions/0011-command-registry.md +117 -0
  20. kryncord-0.1.0b1/docs/decisions/0012-contextos.md +130 -0
  21. kryncord-0.1.0b1/docs/decisions/0013-router-syntax.md +144 -0
  22. kryncord-0.1.0b1/docs/decisions/0014-converters.md +126 -0
  23. kryncord-0.1.0b1/docs/decisions/0015-components.md +180 -0
  24. kryncord-0.1.0b1/docs/decisions/0016-interaction-state.md +179 -0
  25. kryncord-0.1.0b1/docs/decisions/0017-middleware-errors.md +162 -0
  26. kryncord-0.1.0b1/docs/decisions/0018-command-sync.md +150 -0
  27. kryncord-0.1.0b1/docs/decisions/0019-discovery-bootstrap.md +138 -0
  28. kryncord-0.1.0b1/docs/decisions/0020-events.md +162 -0
  29. kryncord-0.1.0b1/docs/decisions/0021-autocomplete.md +125 -0
  30. kryncord-0.1.0b1/docs/decisions/0022-context-menus-transport.md +119 -0
  31. kryncord-0.1.0b1/docs/decisions/0023-responder-parity.md +247 -0
  32. kryncord-0.1.0b1/docs/decisions/0024-components-block.md +204 -0
  33. kryncord-0.1.0b1/docs/decisions/0025-events-payloads-snapshot.md +268 -0
  34. kryncord-0.1.0b1/docs/decisions/0026-interaction-routing-commands.md +287 -0
  35. kryncord-0.1.0b1/docs/decisions/0027-discovery-bootstrap-impl.md +234 -0
  36. kryncord-0.1.0b1/docs/decisions/0028-command-scope-deferred.md +134 -0
  37. kryncord-0.1.0b1/docs/decisions/0029-on-not-found-arity.md +126 -0
  38. kryncord-0.1.0b1/docs/decisions/0030-per-command-error-handlers.md +139 -0
  39. kryncord-0.1.0b1/docs/decisions/README.md +61 -0
  40. kryncord-0.1.0b1/docs/guides/publication.md +137 -0
  41. kryncord-0.1.0b1/docs/internals/architecture.md +848 -0
  42. kryncord-0.1.0b1/docs/internals/initial-decisions.md +11 -0
  43. kryncord-0.1.0b1/docs/reference/ideiabase.md +2673 -0
  44. kryncord-0.1.0b1/examples/minimal_bot.py +43 -0
  45. kryncord-0.1.0b1/pyproject.toml +108 -0
  46. kryncord-0.1.0b1/src/kryncord/__init__.py +336 -0
  47. kryncord-0.1.0b1/src/kryncord/api/__init__.py +111 -0
  48. kryncord-0.1.0b1/src/kryncord/api/_parse.py +92 -0
  49. kryncord-0.1.0b1/src/kryncord/api/_resolve.py +65 -0
  50. kryncord-0.1.0b1/src/kryncord/api/applications.py +184 -0
  51. kryncord-0.1.0b1/src/kryncord/api/channels.py +336 -0
  52. kryncord-0.1.0b1/src/kryncord/api/guilds.py +52 -0
  53. kryncord-0.1.0b1/src/kryncord/api/interactions.py +316 -0
  54. kryncord-0.1.0b1/src/kryncord/api/members.py +235 -0
  55. kryncord-0.1.0b1/src/kryncord/api/messages.py +327 -0
  56. kryncord-0.1.0b1/src/kryncord/api/roles.py +116 -0
  57. kryncord-0.1.0b1/src/kryncord/api/users.py +47 -0
  58. kryncord-0.1.0b1/src/kryncord/api/webhooks.py +184 -0
  59. kryncord-0.1.0b1/src/kryncord/builders/__init__.py +33 -0
  60. kryncord-0.1.0b1/src/kryncord/builders/embed.py +437 -0
  61. kryncord-0.1.0b1/src/kryncord/builders/messages.py +137 -0
  62. kryncord-0.1.0b1/src/kryncord/cache/__init__.py +55 -0
  63. kryncord-0.1.0b1/src/kryncord/cache/keys.py +97 -0
  64. kryncord-0.1.0b1/src/kryncord/cache/memory.py +241 -0
  65. kryncord-0.1.0b1/src/kryncord/cache/policy.py +188 -0
  66. kryncord-0.1.0b1/src/kryncord/cache/protocol.py +114 -0
  67. kryncord-0.1.0b1/src/kryncord/cache/stats.py +122 -0
  68. kryncord-0.1.0b1/src/kryncord/client.py +662 -0
  69. kryncord-0.1.0b1/src/kryncord/commands/__init__.py +60 -0
  70. kryncord-0.1.0b1/src/kryncord/commands/autocomplete.py +229 -0
  71. kryncord-0.1.0b1/src/kryncord/commands/context.py +441 -0
  72. kryncord-0.1.0b1/src/kryncord/commands/decorators.py +296 -0
  73. kryncord-0.1.0b1/src/kryncord/commands/definition.py +104 -0
  74. kryncord-0.1.0b1/src/kryncord/commands/dispatch.py +434 -0
  75. kryncord-0.1.0b1/src/kryncord/commands/instance.py +437 -0
  76. kryncord-0.1.0b1/src/kryncord/commands/option.py +178 -0
  77. kryncord-0.1.0b1/src/kryncord/commands/registry.py +241 -0
  78. kryncord-0.1.0b1/src/kryncord/commands/sync.py +316 -0
  79. kryncord-0.1.0b1/src/kryncord/commands/validation.py +199 -0
  80. kryncord-0.1.0b1/src/kryncord/components/__init__.py +144 -0
  81. kryncord-0.1.0b1/src/kryncord/components/base.py +75 -0
  82. kryncord-0.1.0b1/src/kryncord/components/buttons.py +155 -0
  83. kryncord-0.1.0b1/src/kryncord/components/choices.py +116 -0
  84. kryncord-0.1.0b1/src/kryncord/components/colors.py +101 -0
  85. kryncord-0.1.0b1/src/kryncord/components/displays.py +400 -0
  86. kryncord-0.1.0b1/src/kryncord/components/inputs.py +206 -0
  87. kryncord-0.1.0b1/src/kryncord/components/modals.py +128 -0
  88. kryncord-0.1.0b1/src/kryncord/components/rows.py +213 -0
  89. kryncord-0.1.0b1/src/kryncord/components/selects.py +272 -0
  90. kryncord-0.1.0b1/src/kryncord/components/uploads.py +76 -0
  91. kryncord-0.1.0b1/src/kryncord/components/validation.py +199 -0
  92. kryncord-0.1.0b1/src/kryncord/config.py +277 -0
  93. kryncord-0.1.0b1/src/kryncord/discovery/__init__.py +24 -0
  94. kryncord-0.1.0b1/src/kryncord/discovery/bootstrap.py +188 -0
  95. kryncord-0.1.0b1/src/kryncord/discovery/loader.py +315 -0
  96. kryncord-0.1.0b1/src/kryncord/enums.py +374 -0
  97. kryncord-0.1.0b1/src/kryncord/errors.py +229 -0
  98. kryncord-0.1.0b1/src/kryncord/events/__init__.py +59 -0
  99. kryncord-0.1.0b1/src/kryncord/events/context.py +136 -0
  100. kryncord-0.1.0b1/src/kryncord/events/decorators.py +256 -0
  101. kryncord-0.1.0b1/src/kryncord/events/dispatcher.py +474 -0
  102. kryncord-0.1.0b1/src/kryncord/events/names.py +62 -0
  103. kryncord-0.1.0b1/src/kryncord/events/payloads.py +236 -0
  104. kryncord-0.1.0b1/src/kryncord/events/snapshot.py +114 -0
  105. kryncord-0.1.0b1/src/kryncord/gateway/__init__.py +70 -0
  106. kryncord-0.1.0b1/src/kryncord/gateway/client.py +750 -0
  107. kryncord-0.1.0b1/src/kryncord/gateway/compression.py +209 -0
  108. kryncord-0.1.0b1/src/kryncord/gateway/connection.py +243 -0
  109. kryncord-0.1.0b1/src/kryncord/gateway/heartbeat.py +243 -0
  110. kryncord-0.1.0b1/src/kryncord/gateway/identify.py +236 -0
  111. kryncord-0.1.0b1/src/kryncord/gateway/payloads.py +172 -0
  112. kryncord-0.1.0b1/src/kryncord/gateway/reconnect.py +250 -0
  113. kryncord-0.1.0b1/src/kryncord/gateway/session.py +120 -0
  114. kryncord-0.1.0b1/src/kryncord/http/__init__.py +76 -0
  115. kryncord-0.1.0b1/src/kryncord/http/authentication.py +76 -0
  116. kryncord-0.1.0b1/src/kryncord/http/buckets.py +181 -0
  117. kryncord-0.1.0b1/src/kryncord/http/client.py +213 -0
  118. kryncord-0.1.0b1/src/kryncord/http/multipart.py +191 -0
  119. kryncord-0.1.0b1/src/kryncord/http/rate_limits.py +272 -0
  120. kryncord-0.1.0b1/src/kryncord/http/request.py +97 -0
  121. kryncord-0.1.0b1/src/kryncord/http/response.py +104 -0
  122. kryncord-0.1.0b1/src/kryncord/http/retries.py +151 -0
  123. kryncord-0.1.0b1/src/kryncord/http/routes.py +138 -0
  124. kryncord-0.1.0b1/src/kryncord/intents.py +104 -0
  125. kryncord-0.1.0b1/src/kryncord/interactions/__init__.py +30 -0
  126. kryncord-0.1.0b1/src/kryncord/interactions/component.py +102 -0
  127. kryncord-0.1.0b1/src/kryncord/interactions/dispatch.py +148 -0
  128. kryncord-0.1.0b1/src/kryncord/interactions/response.py +354 -0
  129. kryncord-0.1.0b1/src/kryncord/internal/__init__.py +9 -0
  130. kryncord-0.1.0b1/src/kryncord/internal/compose.py +97 -0
  131. kryncord-0.1.0b1/src/kryncord/internal/tasks.py +67 -0
  132. kryncord-0.1.0b1/src/kryncord/internal/timing.py +47 -0
  133. kryncord-0.1.0b1/src/kryncord/lifecycle.py +138 -0
  134. kryncord-0.1.0b1/src/kryncord/logging.py +84 -0
  135. kryncord-0.1.0b1/src/kryncord/models/__init__.py +86 -0
  136. kryncord-0.1.0b1/src/kryncord/models/attachment.py +51 -0
  137. kryncord-0.1.0b1/src/kryncord/models/ban.py +42 -0
  138. kryncord-0.1.0b1/src/kryncord/models/base.py +191 -0
  139. kryncord-0.1.0b1/src/kryncord/models/channel.py +163 -0
  140. kryncord-0.1.0b1/src/kryncord/models/command.py +107 -0
  141. kryncord-0.1.0b1/src/kryncord/models/guild.py +126 -0
  142. kryncord-0.1.0b1/src/kryncord/models/interaction.py +232 -0
  143. kryncord-0.1.0b1/src/kryncord/models/member.py +81 -0
  144. kryncord-0.1.0b1/src/kryncord/models/message.py +177 -0
  145. kryncord-0.1.0b1/src/kryncord/models/partial.py +91 -0
  146. kryncord-0.1.0b1/src/kryncord/models/ready.py +93 -0
  147. kryncord-0.1.0b1/src/kryncord/models/role.py +109 -0
  148. kryncord-0.1.0b1/src/kryncord/models/typing.py +98 -0
  149. kryncord-0.1.0b1/src/kryncord/models/user.py +88 -0
  150. kryncord-0.1.0b1/src/kryncord/models/voice.py +111 -0
  151. kryncord-0.1.0b1/src/kryncord/models/webhook.py +84 -0
  152. kryncord-0.1.0b1/src/kryncord/permissions.py +190 -0
  153. kryncord-0.1.0b1/src/kryncord/py.typed +0 -0
  154. kryncord-0.1.0b1/src/kryncord/registry.py +40 -0
  155. kryncord-0.1.0b1/src/kryncord/responders/__init__.py +63 -0
  156. kryncord-0.1.0b1/src/kryncord/responders/context.py +324 -0
  157. kryncord-0.1.0b1/src/kryncord/responders/converters.py +479 -0
  158. kryncord-0.1.0b1/src/kryncord/responders/decorators.py +77 -0
  159. kryncord-0.1.0b1/src/kryncord/responders/dispatch.py +341 -0
  160. kryncord-0.1.0b1/src/kryncord/responders/ids.py +253 -0
  161. kryncord-0.1.0b1/src/kryncord/responders/params.py +61 -0
  162. kryncord-0.1.0b1/src/kryncord/responders/patterns.py +183 -0
  163. kryncord-0.1.0b1/src/kryncord/responders/registry.py +155 -0
  164. kryncord-0.1.0b1/src/kryncord/rest/__init__.py +10 -0
  165. kryncord-0.1.0b1/src/kryncord/rest/client.py +374 -0
  166. kryncord-0.1.0b1/src/kryncord/state/__init__.py +35 -0
  167. kryncord-0.1.0b1/src/kryncord/state/connection_state.py +441 -0
  168. kryncord-0.1.0b1/src/kryncord/state/event_updates.py +662 -0
  169. kryncord-0.1.0b1/src/kryncord/state/guild_state.py +134 -0
  170. kryncord-0.1.0b1/src/kryncord/version.py +8 -0
  171. kryncord-0.1.0b1/src/kryncord/voice/__init__.py +8 -0
  172. kryncord-0.1.0b1/tests/conftest.py +255 -0
  173. kryncord-0.1.0b1/tests/unit/builders/__init__.py +3 -0
  174. kryncord-0.1.0b1/tests/unit/builders/test_embed.py +225 -0
  175. kryncord-0.1.0b1/tests/unit/components/__init__.py +6 -0
  176. kryncord-0.1.0b1/tests/unit/components/test_button_rules.py +150 -0
  177. kryncord-0.1.0b1/tests/unit/components/test_displays.py +252 -0
  178. kryncord-0.1.0b1/tests/unit/components/test_flag.py +219 -0
  179. kryncord-0.1.0b1/tests/unit/components/test_modal.py +284 -0
  180. kryncord-0.1.0b1/tests/unit/components/test_rows.py +184 -0
  181. kryncord-0.1.0b1/tests/unit/components/test_selects.py +149 -0
  182. kryncord-0.1.0b1/tests/unit/pacote_circular/__init__.py +1 -0
  183. kryncord-0.1.0b1/tests/unit/pacote_circular/a.py +11 -0
  184. kryncord-0.1.0b1/tests/unit/pacote_circular/b.py +11 -0
  185. kryncord-0.1.0b1/tests/unit/pacote_quebrado/__init__.py +1 -0
  186. kryncord-0.1.0b1/tests/unit/pacote_quebrado/estoura.py +3 -0
  187. kryncord-0.1.0b1/tests/unit/pacote_teste/__init__.py +15 -0
  188. kryncord-0.1.0b1/tests/unit/pacote_teste/alpha_mod.py +5 -0
  189. kryncord-0.1.0b1/tests/unit/pacote_teste/beta_mod.py +5 -0
  190. kryncord-0.1.0b1/tests/unit/pacote_teste/handlers.py +18 -0
  191. kryncord-0.1.0b1/tests/unit/pacote_teste/sub/__init__.py +5 -0
  192. kryncord-0.1.0b1/tests/unit/pacote_teste/sub/profundo.py +5 -0
  193. kryncord-0.1.0b1/tests/unit/pacote_teste/util.py +5 -0
  194. kryncord-0.1.0b1/tests/unit/registro_ordem.py +15 -0
  195. kryncord-0.1.0b1/tests/unit/responders/__init__.py +12 -0
  196. kryncord-0.1.0b1/tests/unit/responders/test_context.py +472 -0
  197. kryncord-0.1.0b1/tests/unit/responders/test_converters.py +338 -0
  198. kryncord-0.1.0b1/tests/unit/responders/test_dispatch.py +429 -0
  199. kryncord-0.1.0b1/tests/unit/responders/test_ids.py +153 -0
  200. kryncord-0.1.0b1/tests/unit/responders/test_patterns.py +148 -0
  201. kryncord-0.1.0b1/tests/unit/responders/test_registry.py +170 -0
  202. kryncord-0.1.0b1/tests/unit/test_api.py +578 -0
  203. kryncord-0.1.0b1/tests/unit/test_api_resources.py +1108 -0
  204. kryncord-0.1.0b1/tests/unit/test_authentication.py +101 -0
  205. kryncord-0.1.0b1/tests/unit/test_autocomplete.py +210 -0
  206. kryncord-0.1.0b1/tests/unit/test_bootstrap.py +308 -0
  207. kryncord-0.1.0b1/tests/unit/test_buckets.py +224 -0
  208. kryncord-0.1.0b1/tests/unit/test_cache.py +554 -0
  209. kryncord-0.1.0b1/tests/unit/test_client.py +425 -0
  210. kryncord-0.1.0b1/tests/unit/test_command_context.py +455 -0
  211. kryncord-0.1.0b1/tests/unit/test_commands.py +505 -0
  212. kryncord-0.1.0b1/tests/unit/test_commands_routing.py +1071 -0
  213. kryncord-0.1.0b1/tests/unit/test_config.py +168 -0
  214. kryncord-0.1.0b1/tests/unit/test_dispatcher.py +418 -0
  215. kryncord-0.1.0b1/tests/unit/test_enums.py +140 -0
  216. kryncord-0.1.0b1/tests/unit/test_event_updates.py +655 -0
  217. kryncord-0.1.0b1/tests/unit/test_events.py +647 -0
  218. kryncord-0.1.0b1/tests/unit/test_gateway_client.py +733 -0
  219. kryncord-0.1.0b1/tests/unit/test_gateway_compression.py +255 -0
  220. kryncord-0.1.0b1/tests/unit/test_gateway_connection.py +143 -0
  221. kryncord-0.1.0b1/tests/unit/test_gateway_heartbeat.py +315 -0
  222. kryncord-0.1.0b1/tests/unit/test_gateway_identify.py +299 -0
  223. kryncord-0.1.0b1/tests/unit/test_gateway_payloads.py +204 -0
  224. kryncord-0.1.0b1/tests/unit/test_gateway_reconnect.py +167 -0
  225. kryncord-0.1.0b1/tests/unit/test_gateway_session.py +149 -0
  226. kryncord-0.1.0b1/tests/unit/test_http_client.py +324 -0
  227. kryncord-0.1.0b1/tests/unit/test_intents.py +101 -0
  228. kryncord-0.1.0b1/tests/unit/test_interactions_state.py +398 -0
  229. kryncord-0.1.0b1/tests/unit/test_lifecycle.py +164 -0
  230. kryncord-0.1.0b1/tests/unit/test_loader.py +186 -0
  231. kryncord-0.1.0b1/tests/unit/test_logging.py +110 -0
  232. kryncord-0.1.0b1/tests/unit/test_models.py +1041 -0
  233. kryncord-0.1.0b1/tests/unit/test_multipart.py +221 -0
  234. kryncord-0.1.0b1/tests/unit/test_permissions.py +154 -0
  235. kryncord-0.1.0b1/tests/unit/test_public_api.py +97 -0
  236. kryncord-0.1.0b1/tests/unit/test_rate_limits.py +298 -0
  237. kryncord-0.1.0b1/tests/unit/test_rest_client.py +676 -0
  238. kryncord-0.1.0b1/tests/unit/test_retries.py +210 -0
  239. kryncord-0.1.0b1/tests/unit/test_routes.py +201 -0
  240. kryncord-0.1.0b1/tests/unit/test_state.py +491 -0
  241. kryncord-0.1.0b1/tests/unit/test_sync.py +433 -0
@@ -0,0 +1,58 @@
1
+ # Ambientes virtuais
2
+ .venv/
3
+ venv/
4
+ env/
5
+ ENV/
6
+
7
+ # Bytecode e caches
8
+ __pycache__/
9
+ *.py[cod]
10
+ *$py.class
11
+ *.so
12
+ .mypy_cache/
13
+ .ruff_cache/
14
+ .pytest_cache/
15
+ .pytest_history/
16
+
17
+ # Build
18
+ build/
19
+ dist/
20
+ *.egg-info/
21
+ *.egg
22
+ .eggs/
23
+ pip-wheel-metadata/
24
+
25
+ # Editores
26
+ .idea/
27
+ .vscode/*
28
+ !.vscode/extensions.json
29
+ !.vscode/settings.json
30
+ *.swp
31
+ *.swo
32
+ *~
33
+
34
+ # Sistema
35
+ .DS_Store
36
+ Thumbs.db
37
+
38
+ # Segredos — nunca commitar
39
+ .env
40
+ .env.*
41
+ !.env.example
42
+ *.token
43
+ secrets.*
44
+ config.local.*
45
+
46
+ # Cobertura
47
+ .coverage
48
+ .coverage.*
49
+ htmlcov/
50
+ coverage.xml
51
+
52
+ # Fora do repositório — material local, não é parte da biblioteca
53
+ # (o gitignore não aceita comentário no fim da linha: o `#` viraria
54
+ # parte do padrão e nada seria ignorado)
55
+ base/
56
+ .freebuff/
57
+ ideias/
58
+ bot testes/
@@ -0,0 +1,36 @@
1
+ # Changelog
2
+
3
+ Formato em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/),
4
+ numeração em [SemVer](https://semver.org/lang/pt-BR/).
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [0.1.0b1] — 2026-10-16
9
+
10
+ Primeira versão beta pública. O núcleo está de pé — REST e Gateway
11
+ próprios, sem dependência de `discord.py`.
12
+
13
+ ### Adicionado
14
+
15
+ - `Client` e `Config` — ciclo de vida assíncrono, `async with` fecha a
16
+ conexão sozinho.
17
+ - Camada REST própria (`client.api`) com rate limit, retries e multipart.
18
+ - Camada Gateway: Identify, heartbeat, ACK, reconexão e retomada de
19
+ sessão.
20
+ - Payloads entregues **interpretados**: `Message`, `Guild`, `Ready` e
21
+ companhia em vez de `dict`.
22
+ - Roteamento de comandos, interações e responders.
23
+ - Cache opcional por política (`CachePolicy`) com estatísticas de hit
24
+ rate.
25
+ - Tipagem completa (`py.typed`) e `mypy --strict` no código inteiro.
26
+
27
+ ### Conhecido
28
+
29
+ - O Discord não manda `guild_id` nos canais do `GUILD_CREATE` — a
30
+ biblioteca preenche a visão da guild por conta própria (verificado ao
31
+ vivo: 24/24 canais sem o campo).
32
+ - `MESSAGE_CONTENT` é privileged: precisa ser ligado no portal do
33
+ Discord antes de pedir o intent.
34
+
35
+ [Unreleased]: https://github.com/KrynCord/kryncord/compare/v0.1.0b1...HEAD
36
+ [0.1.0b1]: https://github.com/KrynCord/kryncord/releases/tag/v0.1.0b1
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gustavo Silva
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,209 @@
1
+ Metadata-Version: 2.5
2
+ Name: kryncord
3
+ Version: 0.1.0b1
4
+ Summary: Async-first Discord API library for Python
5
+ Project-URL: Homepage, https://github.com/KrynCord/kryncord
6
+ Project-URL: Repository, https://github.com/KrynCord/kryncord
7
+ Project-URL: Documentation, https://github.com/KrynCord/kryncord#readme
8
+ Project-URL: Issues, https://github.com/KrynCord/kryncord/issues
9
+ Project-URL: Changelog, https://github.com/KrynCord/kryncord/blob/main/CHANGELOG.md
10
+ Author: kruldevb
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: api,async,bot,discord,gateway,rest
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Framework :: AsyncIO
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Communications :: Chat
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.11
24
+ Requires-Dist: httpx<1,>=0.28.1
25
+ Requires-Dist: websockets<18,>=17.2
26
+ Provides-Extra: dev
27
+ Requires-Dist: mypy>=1.13; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
29
+ Requires-Dist: pytest>=8; extra == 'dev'
30
+ Requires-Dist: ruff>=0.9; extra == 'dev'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # KrynCord
34
+
35
+ Biblioteca assíncrona para criar bots Discord em Python, com implementação
36
+ própria das camadas REST e Gateway.
37
+
38
+ ## Objetivos
39
+
40
+ - API async-first
41
+ - REST e Gateway independentes
42
+ - Roteamento de comandos e interações
43
+ - Cache opcional
44
+ - Tipagem e validação
45
+ - Testes e benchmarks
46
+ - Sem dependência de discord.py ou forks
47
+
48
+ ## Instalação
49
+
50
+ ```bash
51
+ pip install kryncord
52
+ ```
53
+
54
+ Requer Python 3.11+.
55
+
56
+ ## Uso
57
+
58
+ ```python
59
+ import asyncio
60
+ import os
61
+
62
+ from kryncord import Client, Config, Intents, Message
63
+
64
+
65
+ async def main() -> None:
66
+ config = Config(token=os.environ["DISCORD_TOKEN"], intents=Intents.default())
67
+
68
+ async with Client(config) as client:
69
+
70
+ @client.on("message_create")
71
+ async def responde(message: Message) -> None:
72
+ if message.content == "!ping":
73
+ # `reply` aceita a própria mensagem — o canal sai de lá,
74
+ # e o `message_reference` é montado sozinho.
75
+ await client.api.messages.reply(message, "pong")
76
+
77
+ await client.start()
78
+ await asyncio.Event().wait() # fica no ar
79
+
80
+
81
+ asyncio.run(main())
82
+ ```
83
+
84
+ O handler recebe o payload **já interpretado** — um `Message`, não um
85
+ `dict`. `message.content` é `None` quando o Discord não mandou texto, e
86
+ não `""`; `message.author` é `None` quando não veio autor. Campo ausente
87
+ nunca é preenchido com default, porque ausente e default são coisas
88
+ diferentes.
89
+
90
+ O nome do evento aceita as duas formas — `"message_create"` e
91
+ `"MESSAGE_CREATE"` chegam ao mesmo handler. E os métodos da API aceitam
92
+ ID ou objeto: `send(123, ...)`, `send("123", ...)`,
93
+ `send(channel, ...)` e `send(message, ...)` são o mesmo destino.
94
+
95
+ O `api/` é alcançado por `client.api`, e não por `message.reply()` — os
96
+ modelos são dados puros, sem referência a runtime. Ver
97
+ [0007](docs/decisions/0007-api-layer.md) para o porquê.
98
+
99
+ ## Desenvolvimento
100
+
101
+ ```bash
102
+ python -m pip install -e ".[dev]"
103
+ pytest
104
+ ruff check src tests
105
+ ruff format --check src tests
106
+ mypy src/kryncord
107
+ ```
108
+
109
+ ## Status
110
+
111
+ **Fase 3 — Core.** O bot recebe payload tipado e consegue responder.
112
+ `models/` traz `User`, `Message`, `Channel`, `Guild`, `Member`,
113
+ `Attachment`, `Role`, `Ban`, `Webhook`, `ApplicationCommand`,
114
+ `Interaction`, `Ready` e os `Partial*` para o que o Discord entrega
115
+ incompletos de propósito. `events/` converte o payload e decide a
116
+ política de execução — sequencial, exceção isolada, cancelamento
117
+ propaga.
118
+
119
+ `api/` é o vocabulário por recurso sobre a mecânica REST da Fase 1 —
120
+ **70 métodos em 9 módulos** (`messages`, `channels`, `members`,
121
+ `roles`, `webhooks`, `applications`, `interactions`, `guilds`,
122
+ `users`) — e o `Client` liga as duas.
123
+
124
+ `cache/` + `state/` dão ao bot memória local: `client.cache`, **ligada
125
+ por padrão**, guarda guilds, channels, roles e users — `members` e
126
+ `messages` são opt-in por serem os que crescem com o servidor. Remoção
127
+ híbrida (eventos invalidam o que o gateway anuncia; LRU com teto guarda
128
+ o que não tem evento de remoção) e o evento é aplicado **antes** dos
129
+ handlers rodarem, senão todo handler leria o estado do evento
130
+ anterior.
131
+
132
+ 1516 testes passando. `ruff check`, `ruff format --check` e `mypy` limpos.
133
+
134
+ Fase 4 entrou em andamento pela metade dos registros de decisão —
135
+ `0010`–`0024` fecham a superfície inteira (construtor, registry,
136
+ contextos, rota, conversores, componentes, máquina de estados,
137
+ middleware, sync, bootstrap, eventos, autocomplete, context menus,
138
+ paridade com o discord.js e o bloco de componentes), e cada escolha
139
+ passou por um conselho de 22 perfis com veredito e divergência
140
+ registrados em `docs/decisions/`. Já em código: o `permissions.py` +
141
+ as três `Options` no `Config`, o `commands/` inteiro (option,
142
+ definition, validation, instance, registry, context, sync,
143
+ autocomplete), a máquina de estados de interação com a superfície do
144
+ discord.js (`update`, `defer_update`, `fetch_reply`, `launch_activity`,
145
+ `await_responder`), os 17 predicados `is_*()` no modelo, o `responders/`
146
+ inteiro (ids, patterns, router, converters, params, context, registry,
147
+ decorators, dispatch) e o `components/` inteiro (buttons, selects,
148
+ inputs, uploads, choices, rows, displays, modals, colors, validation)
149
+ com os embeds e a normalização que serializa no `api/`. Falta
150
+ `events/`, middleware como bloco próprio e o `bootstrap`.
151
+
152
+ | Fase | Conteúdo | Status |
153
+ |---|---|---|
154
+ | 0 | Pacote, erros, fundação, toolchain, CI | ✅ |
155
+ | 1 | REST: rotas, rate limits, buckets | ✅ |
156
+ | 2 | Gateway: connect, identify, heartbeat, resume | ✅ |
157
+ | 3 | Core: `Client`, `api/`, `models/`, dispatcher, `cache/`, `state/` | ✅ |
158
+ | 4 | Interações: commands, responders, components | 🔶 api/ |
159
+ | 5 | Benchmarks do cache | ⬜ |
160
+
161
+ ## Estrutura
162
+
163
+ ```text
164
+ src/kryncord/ pacote público
165
+ client.py fachada e ciclo de vida
166
+ config.py Config, HTTPConfig, GatewayConfig (frozen)
167
+ intents.py bits de intent + validação privileged
168
+ enums.py opcodes, close codes, permissões
169
+ errors.py hierarquia de exceções
170
+ logging.py namespace kryncord + redact()
171
+ lifecycle.py tasks supervisionadas, encerramento limpo
172
+ <pacote>/ api, gateway, http, rest, interactions,
173
+ responders, commands, components, events,
174
+ models, builders, cache, state, discovery,
175
+ voice, internal
176
+ tests/unit/ testes sem rede
177
+ tests/integration/ testes com transportes simulados
178
+ docs/decisions/ registros de decisão de arquitetura
179
+ ideias/ design da API de alto nível (referência)
180
+ base/discord.js/ referência do discord.js (não é código do projeto)
181
+ ```
182
+
183
+ Os pacotes de cada fase existem já com `__init__.py` documentando a
184
+ responsabilidade. Os arquivos de módulo entram quando tiverem testes e
185
+ uso claro — conforme o fim do `docs/internals/architecture.md`.
186
+
187
+ ## Verificação
188
+
189
+ ```bash
190
+ python -m pip install -e ".[dev]"
191
+ python -m pytest
192
+ python -m ruff check src tests
193
+ python -m ruff format --check src tests
194
+ python -m mypy
195
+ ```
196
+
197
+ ## Decisões
198
+
199
+ - [0001 — Transporte HTTP: httpx](docs/decisions/0001-http-transport.md)
200
+ - [0002 — Transporte WebSocket: websockets](docs/decisions/0002-websocket-transport.md)
201
+ - [0003 — Modelos de dados: dataclasses](docs/decisions/0003-data-models.md)
202
+ - [0004 — Ordem de construção: REST → Gateway](docs/decisions/0004-build-order.md)
203
+ - [0005 — Reconexão do Gateway: classificação de close code](docs/decisions/0005-gateway-reconnect.md)
204
+ - [0006 — Eventos: payload tipado e política de dispatch](docs/decisions/0006-event-dispatch.md)
205
+ - [0007 — Camada `api/`: vocabulário sobre a mecânica REST](docs/decisions/0007-api-layer.md)
206
+
207
+ ## Licença
208
+
209
+ MIT
@@ -0,0 +1,177 @@
1
+ # KrynCord
2
+
3
+ Biblioteca assíncrona para criar bots Discord em Python, com implementação
4
+ própria das camadas REST e Gateway.
5
+
6
+ ## Objetivos
7
+
8
+ - API async-first
9
+ - REST e Gateway independentes
10
+ - Roteamento de comandos e interações
11
+ - Cache opcional
12
+ - Tipagem e validação
13
+ - Testes e benchmarks
14
+ - Sem dependência de discord.py ou forks
15
+
16
+ ## Instalação
17
+
18
+ ```bash
19
+ pip install kryncord
20
+ ```
21
+
22
+ Requer Python 3.11+.
23
+
24
+ ## Uso
25
+
26
+ ```python
27
+ import asyncio
28
+ import os
29
+
30
+ from kryncord import Client, Config, Intents, Message
31
+
32
+
33
+ async def main() -> None:
34
+ config = Config(token=os.environ["DISCORD_TOKEN"], intents=Intents.default())
35
+
36
+ async with Client(config) as client:
37
+
38
+ @client.on("message_create")
39
+ async def responde(message: Message) -> None:
40
+ if message.content == "!ping":
41
+ # `reply` aceita a própria mensagem — o canal sai de lá,
42
+ # e o `message_reference` é montado sozinho.
43
+ await client.api.messages.reply(message, "pong")
44
+
45
+ await client.start()
46
+ await asyncio.Event().wait() # fica no ar
47
+
48
+
49
+ asyncio.run(main())
50
+ ```
51
+
52
+ O handler recebe o payload **já interpretado** — um `Message`, não um
53
+ `dict`. `message.content` é `None` quando o Discord não mandou texto, e
54
+ não `""`; `message.author` é `None` quando não veio autor. Campo ausente
55
+ nunca é preenchido com default, porque ausente e default são coisas
56
+ diferentes.
57
+
58
+ O nome do evento aceita as duas formas — `"message_create"` e
59
+ `"MESSAGE_CREATE"` chegam ao mesmo handler. E os métodos da API aceitam
60
+ ID ou objeto: `send(123, ...)`, `send("123", ...)`,
61
+ `send(channel, ...)` e `send(message, ...)` são o mesmo destino.
62
+
63
+ O `api/` é alcançado por `client.api`, e não por `message.reply()` — os
64
+ modelos são dados puros, sem referência a runtime. Ver
65
+ [0007](docs/decisions/0007-api-layer.md) para o porquê.
66
+
67
+ ## Desenvolvimento
68
+
69
+ ```bash
70
+ python -m pip install -e ".[dev]"
71
+ pytest
72
+ ruff check src tests
73
+ ruff format --check src tests
74
+ mypy src/kryncord
75
+ ```
76
+
77
+ ## Status
78
+
79
+ **Fase 3 — Core.** O bot recebe payload tipado e consegue responder.
80
+ `models/` traz `User`, `Message`, `Channel`, `Guild`, `Member`,
81
+ `Attachment`, `Role`, `Ban`, `Webhook`, `ApplicationCommand`,
82
+ `Interaction`, `Ready` e os `Partial*` para o que o Discord entrega
83
+ incompletos de propósito. `events/` converte o payload e decide a
84
+ política de execução — sequencial, exceção isolada, cancelamento
85
+ propaga.
86
+
87
+ `api/` é o vocabulário por recurso sobre a mecânica REST da Fase 1 —
88
+ **70 métodos em 9 módulos** (`messages`, `channels`, `members`,
89
+ `roles`, `webhooks`, `applications`, `interactions`, `guilds`,
90
+ `users`) — e o `Client` liga as duas.
91
+
92
+ `cache/` + `state/` dão ao bot memória local: `client.cache`, **ligada
93
+ por padrão**, guarda guilds, channels, roles e users — `members` e
94
+ `messages` são opt-in por serem os que crescem com o servidor. Remoção
95
+ híbrida (eventos invalidam o que o gateway anuncia; LRU com teto guarda
96
+ o que não tem evento de remoção) e o evento é aplicado **antes** dos
97
+ handlers rodarem, senão todo handler leria o estado do evento
98
+ anterior.
99
+
100
+ 1516 testes passando. `ruff check`, `ruff format --check` e `mypy` limpos.
101
+
102
+ Fase 4 entrou em andamento pela metade dos registros de decisão —
103
+ `0010`–`0024` fecham a superfície inteira (construtor, registry,
104
+ contextos, rota, conversores, componentes, máquina de estados,
105
+ middleware, sync, bootstrap, eventos, autocomplete, context menus,
106
+ paridade com o discord.js e o bloco de componentes), e cada escolha
107
+ passou por um conselho de 22 perfis com veredito e divergência
108
+ registrados em `docs/decisions/`. Já em código: o `permissions.py` +
109
+ as três `Options` no `Config`, o `commands/` inteiro (option,
110
+ definition, validation, instance, registry, context, sync,
111
+ autocomplete), a máquina de estados de interação com a superfície do
112
+ discord.js (`update`, `defer_update`, `fetch_reply`, `launch_activity`,
113
+ `await_responder`), os 17 predicados `is_*()` no modelo, o `responders/`
114
+ inteiro (ids, patterns, router, converters, params, context, registry,
115
+ decorators, dispatch) e o `components/` inteiro (buttons, selects,
116
+ inputs, uploads, choices, rows, displays, modals, colors, validation)
117
+ com os embeds e a normalização que serializa no `api/`. Falta
118
+ `events/`, middleware como bloco próprio e o `bootstrap`.
119
+
120
+ | Fase | Conteúdo | Status |
121
+ |---|---|---|
122
+ | 0 | Pacote, erros, fundação, toolchain, CI | ✅ |
123
+ | 1 | REST: rotas, rate limits, buckets | ✅ |
124
+ | 2 | Gateway: connect, identify, heartbeat, resume | ✅ |
125
+ | 3 | Core: `Client`, `api/`, `models/`, dispatcher, `cache/`, `state/` | ✅ |
126
+ | 4 | Interações: commands, responders, components | 🔶 api/ |
127
+ | 5 | Benchmarks do cache | ⬜ |
128
+
129
+ ## Estrutura
130
+
131
+ ```text
132
+ src/kryncord/ pacote público
133
+ client.py fachada e ciclo de vida
134
+ config.py Config, HTTPConfig, GatewayConfig (frozen)
135
+ intents.py bits de intent + validação privileged
136
+ enums.py opcodes, close codes, permissões
137
+ errors.py hierarquia de exceções
138
+ logging.py namespace kryncord + redact()
139
+ lifecycle.py tasks supervisionadas, encerramento limpo
140
+ <pacote>/ api, gateway, http, rest, interactions,
141
+ responders, commands, components, events,
142
+ models, builders, cache, state, discovery,
143
+ voice, internal
144
+ tests/unit/ testes sem rede
145
+ tests/integration/ testes com transportes simulados
146
+ docs/decisions/ registros de decisão de arquitetura
147
+ ideias/ design da API de alto nível (referência)
148
+ base/discord.js/ referência do discord.js (não é código do projeto)
149
+ ```
150
+
151
+ Os pacotes de cada fase existem já com `__init__.py` documentando a
152
+ responsabilidade. Os arquivos de módulo entram quando tiverem testes e
153
+ uso claro — conforme o fim do `docs/internals/architecture.md`.
154
+
155
+ ## Verificação
156
+
157
+ ```bash
158
+ python -m pip install -e ".[dev]"
159
+ python -m pytest
160
+ python -m ruff check src tests
161
+ python -m ruff format --check src tests
162
+ python -m mypy
163
+ ```
164
+
165
+ ## Decisões
166
+
167
+ - [0001 — Transporte HTTP: httpx](docs/decisions/0001-http-transport.md)
168
+ - [0002 — Transporte WebSocket: websockets](docs/decisions/0002-websocket-transport.md)
169
+ - [0003 — Modelos de dados: dataclasses](docs/decisions/0003-data-models.md)
170
+ - [0004 — Ordem de construção: REST → Gateway](docs/decisions/0004-build-order.md)
171
+ - [0005 — Reconexão do Gateway: classificação de close code](docs/decisions/0005-gateway-reconnect.md)
172
+ - [0006 — Eventos: payload tipado e política de dispatch](docs/decisions/0006-event-dispatch.md)
173
+ - [0007 — Camada `api/`: vocabulário sobre a mecânica REST](docs/decisions/0007-api-layer.md)
174
+
175
+ ## Licença
176
+
177
+ MIT
@@ -0,0 +1,38 @@
1
+ # Documentação
2
+
3
+ O que cada pasta é, e quando você abre cada uma.
4
+
5
+ | Pasta | Abra quando… |
6
+ |---|---|
7
+ | [`api/`](api/) | Quiser saber como a superfície pública se comporta — as regras de negócio, não o código. |
8
+ | [`decisions/`](decisions/) | Quiser saber **por que** o código é assim. ADRs numerados, um por escolha. |
9
+ | [`guides/`](guides/) | Quiser executar um procedimento passo a passo. |
10
+ | [`internals/`](internals/) | Quiser ver o desenho das camadas e o plano original. |
11
+ | [`reference/`](reference/) | Quiser o material externo que serviu de inspiração. |
12
+
13
+ ## Ordem de leitura para quem chega agora
14
+
15
+ 1. [`internals/initial-decisions.md`](internals/initial-decisions.md) — as
16
+ dez decisões que definem o projeto, em onze linhas.
17
+ 2. [`internals/architecture.md`](internals/architecture.md) — o desenho
18
+ completo: camadas, módulos e limites.
19
+ 3. [`decisions/`](decisions/) — na ordem dos números. Cada ADR explica o
20
+ que foi considerado, o que foi escolhido e o que foi descartado. Um
21
+ ADR **não é atualizado** quando a decisão muda: nasce um novo com
22
+ número maior, e o antigo fica como registro.
23
+
24
+ ## Duas distinções que a documentação inteira repete
25
+
26
+ **Ausente ≠ default.** Campo que o Discord não mandou chega `None`, e
27
+ nunca é preenchido com um valor de convenção. `""` e `None` não são a
28
+ mesma coisa, e um canal sem `rate_limit_per_user` não é um canal com
29
+ `rate_limit_per_user = 0`.
30
+
31
+ **REST ≠ Gateway.** São camadas independentes: dá para usar `client.api`
32
+ sem abrir o socket, e o Gateway fica vivo mesmo se o REST falhar.
33
+
34
+ ## Publicar
35
+
36
+ O passo a passo de publicação — incluindo TestPyPI, Trusted Publishing e
37
+ por que `pip install --pre` é obrigatório para beta — está em
38
+ [`guides/publication.md`](guides/publication.md).