better-notion 2.0.1__tar.gz → 2.1.5__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 (203) hide show
  1. {better_notion-2.0.1 → better_notion-2.1.5}/PKG-INFO +1 -1
  2. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/official/agents.py +64 -2
  3. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/official/agents_cli.py +392 -25
  4. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/official/agents_sdk/managers.py +353 -0
  5. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/official/agents_sdk/models.py +273 -0
  6. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/agents/schemas.py +19 -5
  7. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/agents/workspace.py +232 -33
  8. {better_notion-2.0.1 → better_notion-2.1.5}/pyproject.toml +1 -1
  9. {better_notion-2.0.1 → better_notion-2.1.5}/.gitignore +0 -0
  10. {better_notion-2.0.1 → better_notion-2.1.5}/LICENSE +0 -0
  11. {better_notion-2.0.1 → better_notion-2.1.5}/README.md +0 -0
  12. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/__init__.py +0 -0
  13. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/__init__.py +0 -0
  14. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/client.py +0 -0
  15. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/collections/__init__.py +0 -0
  16. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/collections/blocks.py +0 -0
  17. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/collections/comments.py +0 -0
  18. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/collections/databases.py +0 -0
  19. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/collections/pages.py +0 -0
  20. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/collections/users.py +0 -0
  21. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/entities/__init__.py +0 -0
  22. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/entities/block.py +0 -0
  23. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/entities/comment.py +0 -0
  24. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/entities/database.py +0 -0
  25. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/entities/page.py +0 -0
  26. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/entities/user.py +0 -0
  27. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/errors.py +0 -0
  28. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/oauth.py +0 -0
  29. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/__init__.py +0 -0
  30. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/base.py +0 -0
  31. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/checkbox.py +0 -0
  32. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/date.py +0 -0
  33. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/email.py +0 -0
  34. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/number.py +0 -0
  35. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/phone.py +0 -0
  36. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/relation.py +0 -0
  37. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/rich_text.py +0 -0
  38. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/select.py +0 -0
  39. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/title.py +0 -0
  40. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/properties/url.py +0 -0
  41. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/utils/__init__.py +0 -0
  42. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_api/utils/pagination.py +0 -0
  43. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/__init__.py +0 -0
  44. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/async_typer.py +0 -0
  45. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/__init__.py +0 -0
  46. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/auth.py +0 -0
  47. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/blocks.py +0 -0
  48. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/comments.py +0 -0
  49. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/config.py +0 -0
  50. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/databases.py +0 -0
  51. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/pages.py +0 -0
  52. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/plugins.py +0 -0
  53. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/search.py +0 -0
  54. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/update.py +0 -0
  55. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/users.py +0 -0
  56. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/commands/workspace.py +0 -0
  57. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/config.py +0 -0
  58. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/display.py +0 -0
  59. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/docs/__init__.py +0 -0
  60. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/docs/base.py +0 -0
  61. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/docs/formatters.py +0 -0
  62. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/docs/registry.py +0 -0
  63. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/errors.py +0 -0
  64. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/main.py +0 -0
  65. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/markdown.py +0 -0
  66. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/response.py +0 -0
  67. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_cli/utils/__init__.py +0 -0
  68. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/__init__.py +0 -0
  69. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/base/__init__.py +0 -0
  70. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/base/entity.py +0 -0
  71. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/cache/__init__.py +0 -0
  72. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/cache/cache.py +0 -0
  73. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/client.py +0 -0
  74. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/managers/__init__.py +0 -0
  75. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/managers/block_manager.py +0 -0
  76. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/managers/comment_manager.py +0 -0
  77. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/managers/database_manager.py +0 -0
  78. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/managers/page_manager.py +0 -0
  79. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/managers/user_manager.py +0 -0
  80. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/__init__.py +0 -0
  81. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/block.py +0 -0
  82. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/__init__.py +0 -0
  83. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/audio.py +0 -0
  84. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/bookmark.py +0 -0
  85. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/breadcrumb.py +0 -0
  86. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/bullet.py +0 -0
  87. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/callout.py +0 -0
  88. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/code.py +0 -0
  89. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/column.py +0 -0
  90. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/column_list.py +0 -0
  91. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/divider.py +0 -0
  92. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/embed.py +0 -0
  93. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/equation.py +0 -0
  94. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/file.py +0 -0
  95. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/heading.py +0 -0
  96. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/image.py +0 -0
  97. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/numbered.py +0 -0
  98. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/paragraph.py +0 -0
  99. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/pdf.py +0 -0
  100. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/quote.py +0 -0
  101. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/synced_block.py +0 -0
  102. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/table.py +0 -0
  103. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/table_row.py +0 -0
  104. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/template.py +0 -0
  105. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/todo.py +0 -0
  106. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/toggle.py +0 -0
  107. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/blocks/video.py +0 -0
  108. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/comment.py +0 -0
  109. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/database.py +0 -0
  110. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/page.py +0 -0
  111. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/models/user.py +0 -0
  112. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/parents/__init__.py +0 -0
  113. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/plugins.py +0 -0
  114. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/properties/__init__.py +0 -0
  115. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/properties/formula.py +0 -0
  116. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/properties/parsers.py +0 -0
  117. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/properties/relation.py +0 -0
  118. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/query/__init__.py +0 -0
  119. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/query/database_query.py +0 -0
  120. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/_sdk/query/filter_translator.py +0 -0
  121. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/__init__.py +0 -0
  122. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/base.py +0 -0
  123. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/loader.py +0 -0
  124. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/official/__init__.py +0 -0
  125. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/official/agents_schema.py +0 -0
  126. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/official/agents_sdk/__init__.py +0 -0
  127. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/official/agents_sdk/plugin.py +0 -0
  128. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/official/productivity.py +0 -0
  129. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/plugins/state.py +0 -0
  130. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/__init__.py +0 -0
  131. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/agents/__init__.py +0 -0
  132. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/agents/auth.py +0 -0
  133. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/agents/dependency_resolver.py +0 -0
  134. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/agents/metadata.py +0 -0
  135. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/agents/project_context.py +0 -0
  136. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/agents/rbac.py +0 -0
  137. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/agents/state_machine.py +0 -0
  138. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/helpers.py +0 -0
  139. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/retry.py +0 -0
  140. {better_notion-2.0.1 → better_notion-2.1.5}/better_notion/utils/validators.py +0 -0
  141. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/base/test_entity.py +0 -0
  142. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/cache/test_cache.py +0 -0
  143. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/models/__init__.py +0 -0
  144. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/models/blocks/test_advanced_blocks.py +0 -0
  145. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/models/test_block.py +0 -0
  146. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/models/test_database.py +0 -0
  147. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/models/test_database_bug.py +0 -0
  148. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/models/test_page.py +0 -0
  149. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/models/test_user.py +0 -0
  150. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/properties/test_formula.py +0 -0
  151. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/properties/test_parsers.py +0 -0
  152. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/properties/test_relation.py +0 -0
  153. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/query/test_database_query.py +0 -0
  154. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/query/test_filter_translator.py +0 -0
  155. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/test_client.py +0 -0
  156. {better_notion-2.0.1 → better_notion-2.1.5}/tests/_sdk/test_comment.py +0 -0
  157. {better_notion-2.0.1 → better_notion-2.1.5}/tests/agents/__init__.py +0 -0
  158. {better_notion-2.0.1 → better_notion-2.1.5}/tests/agents/test_auth.py +0 -0
  159. {better_notion-2.0.1 → better_notion-2.1.5}/tests/agents/test_dependency_resolver.py +0 -0
  160. {better_notion-2.0.1 → better_notion-2.1.5}/tests/agents/test_plugin.py +0 -0
  161. {better_notion-2.0.1 → better_notion-2.1.5}/tests/agents/test_project_context.py +0 -0
  162. {better_notion-2.0.1 → better_notion-2.1.5}/tests/agents/test_rbac.py +0 -0
  163. {better_notion-2.0.1 → better_notion-2.1.5}/tests/agents/test_schemas.py +0 -0
  164. {better_notion-2.0.1 → better_notion-2.1.5}/tests/agents/test_state_machine.py +0 -0
  165. {better_notion-2.0.1 → better_notion-2.1.5}/tests/agents/test_workspace.py +0 -0
  166. {better_notion-2.0.1 → better_notion-2.1.5}/tests/cli/__init__.py +0 -0
  167. {better_notion-2.0.1 → better_notion-2.1.5}/tests/cli/test_async_typer.py +0 -0
  168. {better_notion-2.0.1 → better_notion-2.1.5}/tests/cli/test_config.py +0 -0
  169. {better_notion-2.0.1 → better_notion-2.1.5}/tests/cli/test_display.py +0 -0
  170. {better_notion-2.0.1 → better_notion-2.1.5}/tests/cli/test_errors.py +0 -0
  171. {better_notion-2.0.1 → better_notion-2.1.5}/tests/cli/test_main.py +0 -0
  172. {better_notion-2.0.1 → better_notion-2.1.5}/tests/cli/test_pages_commands.py +0 -0
  173. {better_notion-2.0.1 → better_notion-2.1.5}/tests/cli/test_response.py +0 -0
  174. {better_notion-2.0.1 → better_notion-2.1.5}/tests/cli/test_update.py +0 -0
  175. {better_notion-2.0.1 → better_notion-2.1.5}/tests/conftest.py +0 -0
  176. {better_notion-2.0.1 → better_notion-2.1.5}/tests/integration/conftest.py +0 -0
  177. {better_notion-2.0.1 → better_notion-2.1.5}/tests/integration/test_blocks.py +0 -0
  178. {better_notion-2.0.1 → better_notion-2.1.5}/tests/integration/test_databases.py +0 -0
  179. {better_notion-2.0.1 → better_notion-2.1.5}/tests/integration/test_pages.py +0 -0
  180. {better_notion-2.0.1 → better_notion-2.1.5}/tests/integration/test_search.py +0 -0
  181. {better_notion-2.0.1 → better_notion-2.1.5}/tests/integration/test_users.py +0 -0
  182. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/__init__.py +0 -0
  183. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_agents_cli.py +0 -0
  184. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_agents_sdk_integration.py +0 -0
  185. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_agents_sdk_managers.py +0 -0
  186. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_agents_sdk_models.py +0 -0
  187. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_base.py +0 -0
  188. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_loader.py +0 -0
  189. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_marketplace.py +0 -0
  190. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_plugin_commands_state.py +0 -0
  191. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_productivity_plugin.py +0 -0
  192. {better_notion-2.0.1 → better_notion-2.1.5}/tests/plugins/test_state.py +0 -0
  193. {better_notion-2.0.1 → better_notion-2.1.5}/tests/sdk/__init__.py +0 -0
  194. {better_notion-2.0.1 → better_notion-2.1.5}/tests/sdk/test_plugin_system.py +0 -0
  195. {better_notion-2.0.1 → better_notion-2.1.5}/tests/test_metadata.py +0 -0
  196. {better_notion-2.0.1 → better_notion-2.1.5}/tests/test_schema_command.py +0 -0
  197. {better_notion-2.0.1 → better_notion-2.1.5}/tests/unit/test_client.py +0 -0
  198. {better_notion-2.0.1 → better_notion-2.1.5}/tests/unit/test_collections.py +0 -0
  199. {better_notion-2.0.1 → better_notion-2.1.5}/tests/unit/test_entities.py +0 -0
  200. {better_notion-2.0.1 → better_notion-2.1.5}/tests/unit/test_errors.py +0 -0
  201. {better_notion-2.0.1 → better_notion-2.1.5}/tests/unit/test_helpers.py +0 -0
  202. {better_notion-2.0.1 → better_notion-2.1.5}/tests/unit/test_properties.py +0 -0
  203. {better_notion-2.0.1 → better_notion-2.1.5}/tests/utils/test_retry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: better-notion
3
- Version: 2.0.1
3
+ Version: 2.1.5
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
@@ -910,8 +910,51 @@ class AgentsPlugin(CombinedPluginInterface):
910
910
  typer.echo(agents_cli.tasks_complete(task_id, actual_hours))
911
911
 
912
912
  @tasks_app.command("can-start")
913
- def tasks_can_start_cmd(task_id: str):
914
- typer.echo(agents_cli.tasks_can_start(task_id))
913
+ def tasks_can_start_cmd(
914
+ task_id: str,
915
+ explain: bool = typer.Option(False, "--explain", help="Show detailed explanation of blocking tasks")
916
+ ):
917
+ typer.echo(agents_cli.tasks_can_start(task_id, explain))
918
+
919
+ @tasks_app.command("deps")
920
+ def tasks_deps_cmd(task_id: str):
921
+ typer.echo(agents_cli.tasks_deps(task_id))
922
+
923
+ @tasks_app.command("ready")
924
+ def tasks_ready_cmd(
925
+ version_id: str = typer.Option(None, "--version-id", "-v", help="Filter by version ID")
926
+ ):
927
+ typer.echo(agents_cli.tasks_ready(version_id))
928
+
929
+ @tasks_app.command("assign")
930
+ def tasks_assign_cmd(
931
+ task_id: str,
932
+ to: str = typer.Option(..., "--to", help="Person to assign to")
933
+ ):
934
+ typer.echo(agents_cli.tasks_assign(task_id, to))
935
+
936
+ @tasks_app.command("unassign")
937
+ def tasks_unassign_cmd(task_id: str):
938
+ typer.echo(agents_cli.tasks_unassign(task_id))
939
+
940
+ @tasks_app.command("reassign")
941
+ def tasks_reassign_cmd(
942
+ task_id: str,
943
+ from_: str = typer.Option(..., "--from", help="Current assignee (for validation)"),
944
+ to: str = typer.Option(..., "--to", help="New assignee")
945
+ ):
946
+ typer.echo(agents_cli.tasks_reassign(task_id, from_, to))
947
+
948
+ @tasks_app.command("list-by-assignee")
949
+ def tasks_list_by_assignee_cmd(
950
+ assignee: str,
951
+ status: str = typer.Option(None, "--status", "-s", help="Filter by status")
952
+ ):
953
+ typer.echo(agents_cli.tasks_list_by_assignee(assignee, status))
954
+
955
+ @tasks_app.command("list-unassigned")
956
+ def tasks_list_unassigned_cmd():
957
+ typer.echo(agents_cli.tasks_list_unassigned())
915
958
 
916
959
  agents_app.add_typer(tasks_app)
917
960
 
@@ -997,6 +1040,10 @@ class AgentsPlugin(CombinedPluginInterface):
997
1040
  def work_issues_blockers_cmd(project_id: str):
998
1041
  typer.echo(agents_cli.work_issues_blockers(project_id))
999
1042
 
1043
+ @work_issues_app.command("list-blocked-by")
1044
+ def work_issues_list_blocked_by_cmd(work_issue_id: str):
1045
+ typer.echo(agents_cli.work_issues_list_blocked_by(work_issue_id))
1046
+
1000
1047
  agents_app.add_typer(work_issues_app)
1001
1048
 
1002
1049
  # Incidents commands (under agents)
@@ -1041,6 +1088,21 @@ class AgentsPlugin(CombinedPluginInterface):
1041
1088
  def incidents_sla_violations_cmd():
1042
1089
  typer.echo(agents_cli.incidents_sla_violations())
1043
1090
 
1091
+ @incidents_app.command("link-to-work-issue")
1092
+ def incidents_link_to_work_issue_cmd(
1093
+ incident_id: str,
1094
+ work_issue_id: str
1095
+ ):
1096
+ typer.echo(agents_cli.incidents_link_to_work_issue(incident_id, work_issue_id))
1097
+
1098
+ @incidents_app.command("unlink-work-issue")
1099
+ def incidents_unlink_work_issue_cmd(incident_id: str):
1100
+ typer.echo(agents_cli.incidents_unlink_work_issue(incident_id))
1101
+
1102
+ @incidents_app.command("list-caused-by")
1103
+ def incidents_list_caused_by_cmd(work_issue_id: str):
1104
+ typer.echo(agents_cli.incidents_list_caused_by(work_issue_id))
1105
+
1044
1106
  agents_app.add_typer(incidents_app)
1045
1107
 
1046
1108
  def register_sdk_models(self) -> dict[str, type]:
@@ -820,15 +820,17 @@ def tasks_complete(
820
820
  return asyncio.run(_complete())
821
821
 
822
822
 
823
- def tasks_can_start(task_id: str) -> str:
823
+ def tasks_can_start(task_id: str, explain: bool = False) -> str:
824
824
  """
825
825
  Check if a task can start (all dependencies completed).
826
826
 
827
827
  Args:
828
828
  task_id: Task page ID
829
+ explain: Show detailed explanation of blocking tasks
829
830
 
830
831
  Example:
831
832
  $ notion tasks can-start task_123
833
+ $ notion tasks can-start task_123 --explain
832
834
  """
833
835
  async def _can_start() -> str:
834
836
  try:
@@ -837,33 +839,17 @@ def tasks_can_start(task_id: str) -> str:
837
839
  # Register SDK plugin
838
840
  register_agents_sdk_plugin(client)
839
841
 
840
- # Get task and check
842
+ # Use manager method for detailed info
841
843
  manager = client.plugin_manager("tasks")
842
- task = await manager.get(task_id)
843
- can_start = await task.can_start()
844
-
845
- if not can_start:
846
- # Get incomplete dependencies
847
- incomplete = []
848
- for dep in await task.dependencies():
849
- if dep.status != "Completed":
850
- incomplete.append({
851
- "id": dep.id,
852
- "title": dep.title,
853
- "status": dep.status,
854
- })
844
+ result = await manager.can_start(task_id)
855
845
 
856
- return format_success({
857
- "task_id": task.id,
858
- "can_start": False,
859
- "incomplete_dependencies": incomplete,
860
- })
846
+ if explain and not result["can_start"]:
847
+ result["explanation"] = {
848
+ "blocking_tasks": result["incomplete_dependencies"],
849
+ "suggestion": "Wait for dependencies to complete before starting"
850
+ }
861
851
 
862
- return format_success({
863
- "task_id": task.id,
864
- "can_start": True,
865
- "message": "All dependencies are completed",
866
- })
852
+ return format_success(result)
867
853
 
868
854
  except Exception as e:
869
855
  return format_error("CAN_START_ERROR", str(e), retry=False)
@@ -871,6 +857,248 @@ def tasks_can_start(task_id: str) -> str:
871
857
  return asyncio.run(_can_start())
872
858
 
873
859
 
860
+ def tasks_deps(task_id: str) -> str:
861
+ """
862
+ List all dependencies of a task.
863
+
864
+ Args:
865
+ task_id: Task page ID
866
+
867
+ Example:
868
+ $ notion tasks deps task_123
869
+ """
870
+ async def _deps() -> str:
871
+ try:
872
+ client = get_client()
873
+
874
+ # Register SDK plugin
875
+ register_agents_sdk_plugin(client)
876
+
877
+ # Use manager method
878
+ manager = client.plugin_manager("tasks")
879
+ result = await manager.deps(task_id)
880
+
881
+ return format_success(result)
882
+
883
+ except Exception as e:
884
+ return format_error("DEPS_ERROR", str(e), retry=False)
885
+
886
+ return asyncio.run(_deps())
887
+
888
+
889
+ def tasks_ready(version_id: Optional[str] = None) -> str:
890
+ """
891
+ List all tasks ready to start (dependencies completed).
892
+
893
+ Args:
894
+ version_id: Filter by version ID
895
+
896
+ Example:
897
+ $ notion tasks ready
898
+ $ notion tasks ready --version-id ver_123
899
+ """
900
+ async def _ready() -> str:
901
+ try:
902
+ client = get_client()
903
+
904
+ # Register SDK plugin
905
+ register_agents_sdk_plugin(client)
906
+
907
+ # Use manager method
908
+ manager = client.plugin_manager("tasks")
909
+ tasks = await manager.ready(version_id)
910
+
911
+ return format_success({
912
+ "ready_tasks": [
913
+ {
914
+ "id": task.id,
915
+ "title": task.title,
916
+ "status": task.status,
917
+ "priority": task.priority,
918
+ }
919
+ for task in tasks
920
+ ],
921
+ "total": len(tasks)
922
+ })
923
+
924
+ except Exception as e:
925
+ return format_error("READY_ERROR", str(e), retry=False)
926
+
927
+ return asyncio.run(_ready())
928
+
929
+
930
+ def tasks_assign(task_id: str, to: str) -> str:
931
+ """
932
+ Assign a task to a person.
933
+
934
+ Args:
935
+ task_id: Task page ID
936
+ to: Name of the person to assign to
937
+
938
+ Example:
939
+ $ notion tasks assign task_123 --to "Alice Chen"
940
+ """
941
+ async def _assign() -> str:
942
+ try:
943
+ client = get_client()
944
+
945
+ # Register SDK plugin
946
+ register_agents_sdk_plugin(client)
947
+
948
+ # Use manager method
949
+ manager = client.plugin_manager("tasks")
950
+ result = await manager.assign(task_id, to)
951
+
952
+ return format_success(result)
953
+
954
+ except Exception as e:
955
+ return format_error("ASSIGN_ERROR", str(e), retry=False)
956
+
957
+ return asyncio.run(_assign())
958
+
959
+
960
+ def tasks_unassign(task_id: str) -> str:
961
+ """
962
+ Unassign a task.
963
+
964
+ Args:
965
+ task_id: Task page ID
966
+
967
+ Example:
968
+ $ notion tasks unassign task_123
969
+ """
970
+ async def _unassign() -> str:
971
+ try:
972
+ client = get_client()
973
+
974
+ # Register SDK plugin
975
+ register_agents_sdk_plugin(client)
976
+
977
+ # Use manager method
978
+ manager = client.plugin_manager("tasks")
979
+ result = await manager.unassign(task_id)
980
+
981
+ return format_success(result)
982
+
983
+ except Exception as e:
984
+ return format_error("UNASSIGN_ERROR", str(e), retry=False)
985
+
986
+ return asyncio.run(_unassign())
987
+
988
+
989
+ def tasks_reassign(task_id: str, from_: str, to: str) -> str:
990
+ """
991
+ Reassign a task from one person to another.
992
+
993
+ Args:
994
+ task_id: Task page ID
995
+ from_: Current assignee (for validation)
996
+ to: New assignee
997
+
998
+ Example:
999
+ $ notion tasks reassign task_123 --from "Alice" --to "Bob"
1000
+ """
1001
+ async def _reassign() -> str:
1002
+ try:
1003
+ client = get_client()
1004
+
1005
+ # Register SDK plugin
1006
+ register_agents_sdk_plugin(client)
1007
+
1008
+ # Use manager method
1009
+ manager = client.plugin_manager("tasks")
1010
+ result = await manager.reassign(task_id, from_, to)
1011
+
1012
+ return format_success(result)
1013
+
1014
+ except Exception as e:
1015
+ return format_error("REASSIGN_ERROR", str(e), retry=False)
1016
+
1017
+ return asyncio.run(_reassign())
1018
+
1019
+
1020
+ def tasks_list_by_assignee(
1021
+ assignee: str,
1022
+ status: Optional[str] = None
1023
+ ) -> str:
1024
+ """
1025
+ List tasks assigned to a person.
1026
+
1027
+ Args:
1028
+ assignee: Name of the assignee
1029
+ status: Optional status filter
1030
+
1031
+ Example:
1032
+ $ notion tasks list-by-assignee "Alice Chen"
1033
+ $ notion tasks list-by-assignee "Alice" --status "In Progress"
1034
+ """
1035
+ async def _list_by_assignee() -> str:
1036
+ try:
1037
+ client = get_client()
1038
+
1039
+ # Register SDK plugin
1040
+ register_agents_sdk_plugin(client)
1041
+
1042
+ # Use manager method
1043
+ manager = client.plugin_manager("tasks")
1044
+ tasks = await manager.list_by_assignee(assignee, status)
1045
+
1046
+ return format_success({
1047
+ "tasks": [
1048
+ {
1049
+ "id": task.id,
1050
+ "title": task.title,
1051
+ "status": task.status,
1052
+ "priority": task.priority,
1053
+ }
1054
+ for task in tasks
1055
+ ],
1056
+ "total": len(tasks)
1057
+ })
1058
+
1059
+ except Exception as e:
1060
+ return format_error("LIST_BY_ASSIGNEE_ERROR", str(e), retry=False)
1061
+
1062
+ return asyncio.run(_list_by_assignee())
1063
+
1064
+
1065
+ def tasks_list_unassigned() -> str:
1066
+ """
1067
+ List unassigned tasks.
1068
+
1069
+ Example:
1070
+ $ notion tasks list-unassigned
1071
+ """
1072
+ async def _list_unassigned() -> str:
1073
+ try:
1074
+ client = get_client()
1075
+
1076
+ # Register SDK plugin
1077
+ register_agents_sdk_plugin(client)
1078
+
1079
+ # Use manager method
1080
+ manager = client.plugin_manager("tasks")
1081
+ tasks = await manager.list_unassigned()
1082
+
1083
+ return format_success({
1084
+ "unassigned_tasks": [
1085
+ {
1086
+ "id": task.id,
1087
+ "title": task.title,
1088
+ "status": task.status,
1089
+ "priority": task.priority,
1090
+ }
1091
+ for task in tasks
1092
+ ],
1093
+ "total": len(tasks)
1094
+ })
1095
+
1096
+ except Exception as e:
1097
+ return format_error("LIST_UNASSIGNED_ERROR", str(e), retry=False)
1098
+
1099
+ return asyncio.run(_list_unassigned())
1100
+
1101
+
874
1102
  # ===== IDEAS =====
875
1103
 
876
1104
  def ideas_list(
@@ -1432,6 +1660,46 @@ def work_issues_blockers(project_id: str) -> str:
1432
1660
  return asyncio.run(_blockers())
1433
1661
 
1434
1662
 
1663
+ def work_issues_list_blocked_by(work_issue_id: str) -> str:
1664
+ """
1665
+ List tasks blocked by a work issue.
1666
+
1667
+ Args:
1668
+ work_issue_id: Work issue page ID
1669
+
1670
+ Example:
1671
+ $ notion work-issues list-blocked-by issue_456
1672
+ """
1673
+ async def _list_blocked_by() -> str:
1674
+ try:
1675
+ client = get_client()
1676
+
1677
+ # Register SDK plugin
1678
+ register_agents_sdk_plugin(client)
1679
+
1680
+ # Use manager method
1681
+ manager = client.plugin_manager("work_issues")
1682
+ tasks = await manager.list_blocked_by(work_issue_id)
1683
+
1684
+ return format_success({
1685
+ "blocked_tasks": [
1686
+ {
1687
+ "id": task.id,
1688
+ "title": task.title,
1689
+ "status": task.status,
1690
+ "priority": task.priority,
1691
+ }
1692
+ for task in tasks
1693
+ ],
1694
+ "total": len(tasks)
1695
+ })
1696
+
1697
+ except Exception as e:
1698
+ return format_error("LIST_BLOCKED_BY_ERROR", str(e), retry=False)
1699
+
1700
+ return asyncio.run(_list_blocked_by())
1701
+
1702
+
1435
1703
  # ===== INCIDENTS =====
1436
1704
 
1437
1705
  def incidents_list(
@@ -1726,3 +1994,102 @@ def incidents_sla_violations() -> str:
1726
1994
  return format_error("SLA_VIOLATIONS_ERROR", str(e), retry=False)
1727
1995
 
1728
1996
  return asyncio.run(_sla_violations())
1997
+
1998
+
1999
+ def incidents_link_to_work_issue(incident_id: str, work_issue_id: str) -> str:
2000
+ """
2001
+ Link an incident to a work issue (root cause).
2002
+
2003
+ Args:
2004
+ incident_id: Incident page ID
2005
+ work_issue_id: Work issue page ID
2006
+
2007
+ Example:
2008
+ $ notion incidents link-to-work-issue inc_123 issue_456
2009
+ """
2010
+ async def _link_to_work_issue() -> str:
2011
+ try:
2012
+ client = get_client()
2013
+
2014
+ # Register SDK plugin
2015
+ register_agents_sdk_plugin(client)
2016
+
2017
+ # Use manager method
2018
+ manager = client.plugin_manager("incidents")
2019
+ result = await manager.link_to_work_issue(incident_id, work_issue_id)
2020
+
2021
+ return format_success(result)
2022
+
2023
+ except Exception as e:
2024
+ return format_error("LINK_TO_WORK_ISSUE_ERROR", str(e), retry=False)
2025
+
2026
+ return asyncio.run(_link_to_work_issue())
2027
+
2028
+
2029
+ def incidents_unlink_work_issue(incident_id: str) -> str:
2030
+ """
2031
+ Unlink an incident from its work issue.
2032
+
2033
+ Args:
2034
+ incident_id: Incident page ID
2035
+
2036
+ Example:
2037
+ $ notion incidents unlink-work-issue inc_123
2038
+ """
2039
+ async def _unlink_work_issue() -> str:
2040
+ try:
2041
+ client = get_client()
2042
+
2043
+ # Register SDK plugin
2044
+ register_agents_sdk_plugin(client)
2045
+
2046
+ # Use manager method
2047
+ manager = client.plugin_manager("incidents")
2048
+ result = await manager.unlink_work_issue(incident_id)
2049
+
2050
+ return format_success(result)
2051
+
2052
+ except Exception as e:
2053
+ return format_error("UNLINK_WORK_ISSUE_ERROR", str(e), retry=False)
2054
+
2055
+ return asyncio.run(_unlink_work_issue())
2056
+
2057
+
2058
+ def incidents_list_caused_by(work_issue_id: str) -> str:
2059
+ """
2060
+ List all incidents caused by a work issue.
2061
+
2062
+ Args:
2063
+ work_issue_id: Work issue page ID
2064
+
2065
+ Example:
2066
+ $ notion incidents list-caused-by issue_456
2067
+ """
2068
+ async def _list_caused_by() -> str:
2069
+ try:
2070
+ client = get_client()
2071
+
2072
+ # Register SDK plugin
2073
+ register_agents_sdk_plugin(client)
2074
+
2075
+ # Use manager method
2076
+ manager = client.plugin_manager("incidents")
2077
+ incidents = await manager.list_caused_by(work_issue_id)
2078
+
2079
+ return format_success({
2080
+ "incidents": [
2081
+ {
2082
+ "id": incident.id,
2083
+ "title": incident.title,
2084
+ "severity": incident.severity,
2085
+ "status": incident.status,
2086
+ }
2087
+ for incident in incidents
2088
+ ],
2089
+ "total": len(incidents)
2090
+ })
2091
+
2092
+ except Exception as e:
2093
+ return format_error("LIST_CAUSED_BY_ERROR", str(e), retry=False)
2094
+
2095
+ return asyncio.run(_list_caused_by())