better-notion 1.5.5__tar.gz → 1.6.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 (201) hide show
  1. {better_notion-1.5.5 → better_notion-1.6.0}/PKG-INFO +1 -1
  2. better_notion-1.6.0/better_notion/_cli/docs/__init__.py +20 -0
  3. better_notion-1.6.0/better_notion/_cli/docs/base.py +204 -0
  4. better_notion-1.6.0/better_notion/_cli/docs/formatters.py +128 -0
  5. better_notion-1.6.0/better_notion/_cli/docs/registry.py +82 -0
  6. better_notion-1.6.0/better_notion/_cli/main.py +316 -0
  7. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/response.py +64 -8
  8. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/official/agents.py +156 -0
  9. better_notion-1.6.0/better_notion/plugins/official/agents_schema.py +369 -0
  10. {better_notion-1.5.5 → better_notion-1.6.0}/pyproject.toml +1 -1
  11. better_notion-1.5.5/better_notion/_cli/main.py +0 -149
  12. {better_notion-1.5.5 → better_notion-1.6.0}/.gitignore +0 -0
  13. {better_notion-1.5.5 → better_notion-1.6.0}/LICENSE +0 -0
  14. {better_notion-1.5.5 → better_notion-1.6.0}/README.md +0 -0
  15. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/__init__.py +0 -0
  16. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/__init__.py +0 -0
  17. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/client.py +0 -0
  18. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/collections/__init__.py +0 -0
  19. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/collections/blocks.py +0 -0
  20. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/collections/comments.py +0 -0
  21. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/collections/databases.py +0 -0
  22. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/collections/pages.py +0 -0
  23. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/collections/users.py +0 -0
  24. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/entities/__init__.py +0 -0
  25. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/entities/block.py +0 -0
  26. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/entities/comment.py +0 -0
  27. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/entities/database.py +0 -0
  28. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/entities/page.py +0 -0
  29. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/entities/user.py +0 -0
  30. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/errors.py +0 -0
  31. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/oauth.py +0 -0
  32. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/__init__.py +0 -0
  33. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/base.py +0 -0
  34. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/checkbox.py +0 -0
  35. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/date.py +0 -0
  36. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/email.py +0 -0
  37. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/number.py +0 -0
  38. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/phone.py +0 -0
  39. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/rich_text.py +0 -0
  40. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/select.py +0 -0
  41. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/title.py +0 -0
  42. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/properties/url.py +0 -0
  43. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/utils/__init__.py +0 -0
  44. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_api/utils/pagination.py +0 -0
  45. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/__init__.py +0 -0
  46. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/async_typer.py +0 -0
  47. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/__init__.py +0 -0
  48. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/auth.py +0 -0
  49. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/blocks.py +0 -0
  50. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/comments.py +0 -0
  51. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/config.py +0 -0
  52. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/databases.py +0 -0
  53. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/pages.py +0 -0
  54. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/plugins.py +0 -0
  55. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/search.py +0 -0
  56. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/update.py +0 -0
  57. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/users.py +0 -0
  58. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/commands/workspace.py +0 -0
  59. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/config.py +0 -0
  60. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/display.py +0 -0
  61. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/errors.py +0 -0
  62. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/markdown.py +0 -0
  63. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_cli/utils/__init__.py +0 -0
  64. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/__init__.py +0 -0
  65. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/base/__init__.py +0 -0
  66. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/base/entity.py +0 -0
  67. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/cache/__init__.py +0 -0
  68. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/cache/cache.py +0 -0
  69. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/client.py +0 -0
  70. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/managers/__init__.py +0 -0
  71. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/managers/block_manager.py +0 -0
  72. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/managers/comment_manager.py +0 -0
  73. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/managers/database_manager.py +0 -0
  74. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/managers/page_manager.py +0 -0
  75. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/managers/user_manager.py +0 -0
  76. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/__init__.py +0 -0
  77. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/block.py +0 -0
  78. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/__init__.py +0 -0
  79. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/audio.py +0 -0
  80. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/bookmark.py +0 -0
  81. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/breadcrumb.py +0 -0
  82. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/bullet.py +0 -0
  83. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/callout.py +0 -0
  84. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/code.py +0 -0
  85. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/column.py +0 -0
  86. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/column_list.py +0 -0
  87. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/divider.py +0 -0
  88. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/embed.py +0 -0
  89. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/equation.py +0 -0
  90. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/file.py +0 -0
  91. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/heading.py +0 -0
  92. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/image.py +0 -0
  93. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/numbered.py +0 -0
  94. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/paragraph.py +0 -0
  95. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/pdf.py +0 -0
  96. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/quote.py +0 -0
  97. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/synced_block.py +0 -0
  98. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/table.py +0 -0
  99. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/table_row.py +0 -0
  100. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/template.py +0 -0
  101. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/todo.py +0 -0
  102. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/toggle.py +0 -0
  103. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/blocks/video.py +0 -0
  104. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/comment.py +0 -0
  105. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/database.py +0 -0
  106. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/page.py +0 -0
  107. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/models/user.py +0 -0
  108. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/parents/__init__.py +0 -0
  109. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/plugins.py +0 -0
  110. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/properties/__init__.py +0 -0
  111. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/properties/formula.py +0 -0
  112. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/properties/parsers.py +0 -0
  113. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/properties/relation.py +0 -0
  114. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/query/__init__.py +0 -0
  115. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/query/database_query.py +0 -0
  116. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/_sdk/query/filter_translator.py +0 -0
  117. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/__init__.py +0 -0
  118. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/base.py +0 -0
  119. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/loader.py +0 -0
  120. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/official/__init__.py +0 -0
  121. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/official/agents_cli.py +0 -0
  122. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/official/agents_sdk/__init__.py +0 -0
  123. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/official/agents_sdk/managers.py +0 -0
  124. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/official/agents_sdk/models.py +0 -0
  125. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/official/agents_sdk/plugin.py +0 -0
  126. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/official/productivity.py +0 -0
  127. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/plugins/state.py +0 -0
  128. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/__init__.py +0 -0
  129. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/agents/__init__.py +0 -0
  130. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/agents/auth.py +0 -0
  131. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/agents/dependency_resolver.py +0 -0
  132. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/agents/metadata.py +0 -0
  133. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/agents/project_context.py +0 -0
  134. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/agents/rbac.py +0 -0
  135. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/agents/schemas.py +0 -0
  136. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/agents/state_machine.py +0 -0
  137. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/agents/workspace.py +0 -0
  138. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/helpers.py +0 -0
  139. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/retry.py +0 -0
  140. {better_notion-1.5.5 → better_notion-1.6.0}/better_notion/utils/validators.py +0 -0
  141. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/base/test_entity.py +0 -0
  142. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/cache/test_cache.py +0 -0
  143. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/models/__init__.py +0 -0
  144. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/models/blocks/test_advanced_blocks.py +0 -0
  145. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/models/test_block.py +0 -0
  146. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/models/test_database.py +0 -0
  147. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/models/test_database_bug.py +0 -0
  148. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/models/test_page.py +0 -0
  149. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/models/test_user.py +0 -0
  150. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/properties/test_formula.py +0 -0
  151. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/properties/test_parsers.py +0 -0
  152. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/properties/test_relation.py +0 -0
  153. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/query/test_database_query.py +0 -0
  154. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/query/test_filter_translator.py +0 -0
  155. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/test_client.py +0 -0
  156. {better_notion-1.5.5 → better_notion-1.6.0}/tests/_sdk/test_comment.py +0 -0
  157. {better_notion-1.5.5 → better_notion-1.6.0}/tests/agents/__init__.py +0 -0
  158. {better_notion-1.5.5 → better_notion-1.6.0}/tests/agents/test_auth.py +0 -0
  159. {better_notion-1.5.5 → better_notion-1.6.0}/tests/agents/test_dependency_resolver.py +0 -0
  160. {better_notion-1.5.5 → better_notion-1.6.0}/tests/agents/test_plugin.py +0 -0
  161. {better_notion-1.5.5 → better_notion-1.6.0}/tests/agents/test_project_context.py +0 -0
  162. {better_notion-1.5.5 → better_notion-1.6.0}/tests/agents/test_rbac.py +0 -0
  163. {better_notion-1.5.5 → better_notion-1.6.0}/tests/agents/test_schemas.py +0 -0
  164. {better_notion-1.5.5 → better_notion-1.6.0}/tests/agents/test_state_machine.py +0 -0
  165. {better_notion-1.5.5 → better_notion-1.6.0}/tests/agents/test_workspace.py +0 -0
  166. {better_notion-1.5.5 → better_notion-1.6.0}/tests/cli/__init__.py +0 -0
  167. {better_notion-1.5.5 → better_notion-1.6.0}/tests/cli/test_async_typer.py +0 -0
  168. {better_notion-1.5.5 → better_notion-1.6.0}/tests/cli/test_config.py +0 -0
  169. {better_notion-1.5.5 → better_notion-1.6.0}/tests/cli/test_display.py +0 -0
  170. {better_notion-1.5.5 → better_notion-1.6.0}/tests/cli/test_errors.py +0 -0
  171. {better_notion-1.5.5 → better_notion-1.6.0}/tests/cli/test_main.py +0 -0
  172. {better_notion-1.5.5 → better_notion-1.6.0}/tests/cli/test_pages_commands.py +0 -0
  173. {better_notion-1.5.5 → better_notion-1.6.0}/tests/cli/test_response.py +0 -0
  174. {better_notion-1.5.5 → better_notion-1.6.0}/tests/cli/test_update.py +0 -0
  175. {better_notion-1.5.5 → better_notion-1.6.0}/tests/conftest.py +0 -0
  176. {better_notion-1.5.5 → better_notion-1.6.0}/tests/integration/conftest.py +0 -0
  177. {better_notion-1.5.5 → better_notion-1.6.0}/tests/integration/test_blocks.py +0 -0
  178. {better_notion-1.5.5 → better_notion-1.6.0}/tests/integration/test_databases.py +0 -0
  179. {better_notion-1.5.5 → better_notion-1.6.0}/tests/integration/test_pages.py +0 -0
  180. {better_notion-1.5.5 → better_notion-1.6.0}/tests/integration/test_search.py +0 -0
  181. {better_notion-1.5.5 → better_notion-1.6.0}/tests/integration/test_users.py +0 -0
  182. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/__init__.py +0 -0
  183. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_agents_cli.py +0 -0
  184. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_agents_sdk_integration.py +0 -0
  185. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_agents_sdk_managers.py +0 -0
  186. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_agents_sdk_models.py +0 -0
  187. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_base.py +0 -0
  188. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_loader.py +0 -0
  189. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_marketplace.py +0 -0
  190. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_plugin_commands_state.py +0 -0
  191. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_productivity_plugin.py +0 -0
  192. {better_notion-1.5.5 → better_notion-1.6.0}/tests/plugins/test_state.py +0 -0
  193. {better_notion-1.5.5 → better_notion-1.6.0}/tests/sdk/__init__.py +0 -0
  194. {better_notion-1.5.5 → better_notion-1.6.0}/tests/sdk/test_plugin_system.py +0 -0
  195. {better_notion-1.5.5 → better_notion-1.6.0}/tests/unit/test_client.py +0 -0
  196. {better_notion-1.5.5 → better_notion-1.6.0}/tests/unit/test_collections.py +0 -0
  197. {better_notion-1.5.5 → better_notion-1.6.0}/tests/unit/test_entities.py +0 -0
  198. {better_notion-1.5.5 → better_notion-1.6.0}/tests/unit/test_errors.py +0 -0
  199. {better_notion-1.5.5 → better_notion-1.6.0}/tests/unit/test_helpers.py +0 -0
  200. {better_notion-1.5.5 → better_notion-1.6.0}/tests/unit/test_properties.py +0 -0
  201. {better_notion-1.5.5 → better_notion-1.6.0}/tests/utils/test_retry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: better-notion
3
- Version: 1.5.5
3
+ Version: 1.6.0
4
4
  Summary: A high-level Python SDK for the Notion API with developer experience in mind.
5
5
  Project-URL: Homepage, https://github.com/nesalia-inc/better-notion
6
6
  Project-URL: Documentation, https://github.com/nesalia-inc/better-notion#readme
@@ -0,0 +1,20 @@
1
+ """Documentation system for AI agents.
2
+
3
+ This module provides infrastructure for documenting CLI commands
4
+ in a machine-readable format that AI agents can consume to understand
5
+ the system at a high level of abstraction.
6
+ """
7
+
8
+ from better_notion._cli.docs.base import (
9
+ Command,
10
+ Concept,
11
+ Schema,
12
+ Workflow,
13
+ )
14
+
15
+ __all__ = [
16
+ "Schema",
17
+ "Concept",
18
+ "Workflow",
19
+ "Command",
20
+ ]
@@ -0,0 +1,204 @@
1
+ """Base classes for documentation system.
2
+
3
+ This module provides the core data structures for documenting
4
+ CLI commands and workflows in a machine-readable format.
5
+ """
6
+
7
+ from dataclasses import dataclass, field
8
+ from typing import Any
9
+
10
+
11
+ @dataclass
12
+ class Concept:
13
+ """A concept represents a high-level idea in the system.
14
+
15
+ Concepts help AI agents understand what things are
16
+ (e.g., "workspace", "task", "version") beyond just
17
+ command syntax.
18
+
19
+ Attributes:
20
+ name: Name of the concept
21
+ description: Human-readable description
22
+ properties: Dict of concept properties and their meanings
23
+ relationships: Relationships to other concepts
24
+ """
25
+
26
+ name: str
27
+ description: str
28
+ properties: dict[str, Any] = field(default_factory=dict)
29
+ relationships: dict[str, str] = field(default_factory=dict)
30
+
31
+ def to_dict(self) -> dict[str, Any]:
32
+ """Convert to dictionary for JSON serialization."""
33
+ return {
34
+ "name": self.name,
35
+ "description": self.description,
36
+ "properties": self.properties,
37
+ "relationships": self.relationships,
38
+ }
39
+
40
+
41
+ @dataclass
42
+ class WorkflowStep:
43
+ """A single step in a workflow.
44
+
45
+ Attributes:
46
+ description: What this step does
47
+ command: Optional command to execute
48
+ purpose: Why this step is needed
49
+ """
50
+
51
+ description: str
52
+ command: str | None = None
53
+ purpose: str | None = None
54
+
55
+ def to_dict(self) -> dict[str, Any]:
56
+ """Convert to dictionary for JSON serialization."""
57
+ return {
58
+ "description": self.description,
59
+ "command": self.command,
60
+ "purpose": self.purpose,
61
+ }
62
+
63
+
64
+ @dataclass
65
+ class ErrorRecovery:
66
+ """Error recovery strategy for a command.
67
+
68
+ Attributes:
69
+ error_type: Type of error (e.g., "workspace_exists")
70
+ message: Human-readable error message
71
+ solutions: List of possible solutions with flags/actions
72
+ """
73
+
74
+ error_type: str
75
+ message: str
76
+ solutions: list[dict[str, Any]] = field(default_factory=list)
77
+
78
+ def to_dict(self) -> dict[str, Any]:
79
+ """Convert to dictionary for JSON serialization."""
80
+ return {
81
+ "error_type": self.error_type,
82
+ "message": self.message,
83
+ "solutions": self.solutions,
84
+ }
85
+
86
+
87
+ @dataclass
88
+ class Workflow:
89
+ """A workflow represents a sequence of operations.
90
+
91
+ Workflows help AI agents understand how to accomplish
92
+ high-level goals (e.g., "initialize_workspace",
93
+ "create_task").
94
+
95
+ Attributes:
96
+ name: Workflow name
97
+ description: What this workflow accomplishes
98
+ steps: List of steps in the workflow
99
+ commands: Example commands for this workflow
100
+ prerequisites: Required conditions before starting
101
+ error_recovery: Error handling strategies
102
+ """
103
+
104
+ name: str
105
+ description: str
106
+ steps: list[WorkflowStep | dict[str, Any]] = field(default_factory=list)
107
+ commands: list[str] = field(default_factory=list)
108
+ prerequisites: list[str] = field(default_factory=list)
109
+ error_recovery: dict[str, dict[str, Any]] = field(default_factory=dict)
110
+
111
+ def to_dict(self) -> dict[str, Any]:
112
+ """Convert to dictionary for JSON serialization."""
113
+ return {
114
+ "name": self.name,
115
+ "description": self.description,
116
+ "steps": [
117
+ step.to_dict() if isinstance(step, WorkflowStep) else step
118
+ for step in self.steps
119
+ ],
120
+ "commands": self.commands,
121
+ "prerequisites": self.prerequisites,
122
+ "error_recovery": self.error_recovery,
123
+ }
124
+
125
+
126
+ @dataclass
127
+ class Command:
128
+ """Documentation for a single command.
129
+
130
+ Command docs go beyond --help text to provide semantic
131
+ meaning and workflow context.
132
+
133
+ Attributes:
134
+ name: Command name
135
+ purpose: What this command does (semantic meaning)
136
+ description: Detailed description
137
+ flags: Dict of flag -> purpose
138
+ workflow: Which workflow this command belongs to
139
+ when_to_use: When this command should be used
140
+ error_recovery: Error handling strategies
141
+ """
142
+
143
+ name: str
144
+ purpose: str
145
+ description: str = ""
146
+ flags: dict[str, str] = field(default_factory=dict)
147
+ workflow: str | None = None
148
+ when_to_use: list[str] = field(default_factory=list)
149
+ error_recovery: dict[str, dict[str, Any]] = field(default_factory=dict)
150
+
151
+ def to_dict(self) -> dict[str, Any]:
152
+ """Convert to dictionary for JSON serialization."""
153
+ return {
154
+ "name": self.name,
155
+ "purpose": self.purpose,
156
+ "description": self.description,
157
+ "flags": self.flags,
158
+ "workflow": self.workflow,
159
+ "when_to_use": self.when_to_use,
160
+ "error_recovery": self.error_recovery,
161
+ }
162
+
163
+
164
+ @dataclass
165
+ class Schema:
166
+ """Complete schema documentation for a plugin.
167
+
168
+ A Schema provides everything an AI agent needs to understand
169
+ a plugin system at a high level.
170
+
171
+ Attributes:
172
+ name: Plugin name
173
+ version: Schema version
174
+ description: Plugin description
175
+ concepts: High-level concepts in the system
176
+ workflows: Available workflows
177
+ commands: Command documentation
178
+ best_practices: Recommended usage patterns
179
+ examples: Usage examples
180
+ """
181
+
182
+ name: str
183
+ version: str
184
+ description: str
185
+ concepts: list[Concept] = field(default_factory=list)
186
+ workflows: list[Workflow] = field(default_factory=list)
187
+ commands: dict[str, Command] = field(default_factory=dict)
188
+ best_practices: list[str] = field(default_factory=list)
189
+ examples: dict[str, str] = field(default_factory=dict)
190
+
191
+ def to_dict(self) -> dict[str, Any]:
192
+ """Convert to dictionary for JSON serialization."""
193
+ return {
194
+ "name": self.name,
195
+ "version": self.version,
196
+ "description": self.description,
197
+ "concepts": [concept.to_dict() for concept in self.concepts],
198
+ "workflows": [workflow.to_dict() for workflow in self.workflows],
199
+ "commands": {
200
+ name: command.to_dict() for name, command in self.commands.items()
201
+ },
202
+ "best_practices": self.best_practices,
203
+ "examples": self.examples,
204
+ }
@@ -0,0 +1,128 @@
1
+ """Formatters for schema documentation.
2
+
3
+ This module provides utilities to format Schema objects
4
+ into different output formats (JSON, YAML).
5
+ """
6
+
7
+ import json
8
+ from typing import Any
9
+
10
+ from better_notion._cli.docs.base import Schema
11
+
12
+
13
+ def format_schema_json(schema: Schema, *, pretty: bool = True) -> str:
14
+ """Format a Schema as JSON.
15
+
16
+ Args:
17
+ schema: Schema object to format
18
+ pretty: Whether to pretty-print with indentation
19
+
20
+ Returns:
21
+ JSON string representation of the schema
22
+ """
23
+ schema_dict = schema.to_dict()
24
+ if pretty:
25
+ return json.dumps(schema_dict, indent=2)
26
+ return json.dumps(schema_dict)
27
+
28
+
29
+ def format_schema_yaml(schema: Schema) -> str:
30
+ """Format a Schema as YAML.
31
+
32
+ Args:
33
+ schema: Schema object to format
34
+
35
+ Returns:
36
+ YAML string representation of the schema
37
+ """
38
+ try:
39
+ import yaml
40
+
41
+ return yaml.dump(schema.to_dict(), default_flow_style=False)
42
+ except ImportError:
43
+ # Fall back to JSON if pyyaml not installed
44
+ logger = __import__("logging").getLogger(__name__)
45
+ logger.warning("PyYAML not installed, falling back to JSON")
46
+ return format_schema_json(schema)
47
+
48
+
49
+ def format_schema_pretty(schema: Schema) -> str:
50
+ """Format a Schema as human-readable text with sections.
51
+
52
+ This provides a more readable format for human consumption
53
+ while maintaining machine-parsable structure.
54
+
55
+ Args:
56
+ schema: Schema object to format
57
+
58
+ Returns:
59
+ Formatted text string
60
+ """
61
+ lines = []
62
+ data = schema.to_dict()
63
+
64
+ # Header
65
+ lines.append(f"# {schema.name.upper()} SCHEMA")
66
+ lines.append(f"Version: {schema.version}")
67
+ lines.append(f"Description: {schema.description}")
68
+ lines.append("")
69
+
70
+ # Concepts
71
+ if data["concepts"]:
72
+ lines.append("## CONCEPTS")
73
+ for concept in data["concepts"]:
74
+ lines.append(f"### {concept['name']}")
75
+ lines.append(f"{concept['description']}")
76
+ if concept.get("properties"):
77
+ lines.append("**Properties:**")
78
+ for key, value in concept["properties"].items():
79
+ lines.append(f" - {key}: {value}")
80
+ if concept.get("relationships"):
81
+ lines.append("**Relationships:**")
82
+ for key, value in concept["relationships"].items():
83
+ lines.append(f" - {key}: {value}")
84
+ lines.append("")
85
+
86
+ # Workflows
87
+ if data["workflows"]:
88
+ lines.append("## WORKFLOWS")
89
+ for workflow in data["workflows"]:
90
+ lines.append(f"### {workflow['name']}")
91
+ lines.append(f"{workflow['description']}")
92
+ if workflow.get("steps"):
93
+ lines.append("**Steps:**")
94
+ for i, step in enumerate(workflow["steps"], 1):
95
+ if isinstance(step, dict):
96
+ lines.append(f" {i}. {step.get('description', step)}")
97
+ else:
98
+ lines.append(f" {i}. {step}")
99
+ if workflow.get("commands"):
100
+ lines.append("**Commands:**")
101
+ for cmd in workflow["commands"]:
102
+ lines.append(f" - {cmd}")
103
+ lines.append("")
104
+
105
+ # Commands
106
+ if data["commands"]:
107
+ lines.append("## COMMANDS")
108
+ for cmd_name, cmd in data["commands"].items():
109
+ lines.append(f"### {cmd_name}")
110
+ lines.append(f"**Purpose:** {cmd.get('purpose', 'N/A')}")
111
+ if cmd.get("flags"):
112
+ lines.append("**Flags:**")
113
+ for flag, purpose in cmd["flags"].items():
114
+ lines.append(f" - {flag}: {purpose}")
115
+ if cmd.get("when_to_use"):
116
+ lines.append("**When to use:**")
117
+ for usage in cmd["when_to_use"]:
118
+ lines.append(f" - {usage}")
119
+ lines.append("")
120
+
121
+ # Best Practices
122
+ if data.get("best_practices"):
123
+ lines.append("## BEST PRACTICES")
124
+ for practice in data["best_practices"]:
125
+ lines.append(f"- {practice}")
126
+ lines.append("")
127
+
128
+ return "\n".join(lines)
@@ -0,0 +1,82 @@
1
+ """Schema registry for plugin documentation.
2
+
3
+ This module provides a central registry where plugins can register
4
+ their documentation schemas for AI agent consumption.
5
+ """
6
+
7
+ import logging
8
+ from typing import Any
9
+
10
+ from better_notion._cli.docs.base import Schema
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class SchemaRegistry:
16
+ """Registry for plugin documentation schemas.
17
+
18
+ This class maintains a collection of plugin schemas that
19
+ AI agents can query to understand the system.
20
+
21
+ Example:
22
+ >>> # Register a plugin schema
23
+ >>> SchemaRegistry.register("agents", AGENTS_SCHEMA)
24
+ >>>
25
+ >>> # Query for a plugin schema
26
+ >>> schema = SchemaRegistry.get("agents")
27
+ >>>
28
+ >>> # List all available schemas
29
+ >>> all_schemas = SchemaRegistry.list_all()
30
+ """
31
+
32
+ _schemas: dict[str, Schema] = {}
33
+
34
+ @classmethod
35
+ def register(cls, plugin_name: str, schema: Schema) -> None:
36
+ """Register a plugin schema.
37
+
38
+ Args:
39
+ plugin_name: Name of the plugin (e.g., "agents")
40
+ schema: Schema object containing plugin documentation
41
+ """
42
+ cls._schemas[plugin_name] = schema
43
+ logger.info(f"Registered schema for plugin: {plugin_name}")
44
+
45
+ @classmethod
46
+ def get(cls, plugin_name: str) -> Schema | None:
47
+ """Get a plugin schema by name.
48
+
49
+ Args:
50
+ plugin_name: Name of the plugin
51
+
52
+ Returns:
53
+ Schema object if found, None otherwise
54
+ """
55
+ return cls._schemas.get(plugin_name)
56
+
57
+ @classmethod
58
+ def list_all(cls) -> dict[str, Schema]:
59
+ """List all registered plugin schemas.
60
+
61
+ Returns:
62
+ Dict mapping plugin names to Schema objects
63
+ """
64
+ return cls._schemas.copy()
65
+
66
+ @classmethod
67
+ def get_all_names(cls) -> list[str]:
68
+ """Get list of all registered plugin names.
69
+
70
+ Returns:
71
+ List of plugin names
72
+ """
73
+ return list(cls._schemas.keys())
74
+
75
+ @classmethod
76
+ def clear(cls) -> None:
77
+ """Clear all registered schemas.
78
+
79
+ This is primarily useful for testing.
80
+ """
81
+ cls._schemas.clear()
82
+ logger.debug("Cleared schema registry")