gravity-cli 0.7.6__tar.gz → 0.9.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 (290) hide show
  1. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/.env.example +4 -4
  2. gravity_cli-0.9.0/.github/workflows/composio-watch.yml +47 -0
  3. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/AGENT_STANDARD.md +3 -0
  4. gravity_cli-0.9.0/AGENT_STANDARD_V2.md +425 -0
  5. gravity_cli-0.7.6/README.md → gravity_cli-0.9.0/PKG-INFO +37 -4
  6. gravity_cli-0.7.6/PKG-INFO → gravity_cli-0.9.0/README.md +20 -21
  7. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/RELEASING.md +2 -0
  8. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/TEMPLATES.md +6 -0
  9. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/__init__.py +214 -0
  10. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/built_ins.py +32 -0
  11. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/catalog.yaml +18 -0
  12. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/contract.py +19 -2
  13. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/describe.py +707 -0
  14. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/errors.py +10 -0
  15. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/export.py +10 -5
  16. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/gen_vocabulary.py +250 -0
  17. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/instance.py +484 -0
  18. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/manifest.py +537 -0
  19. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/manifest_v2.py +628 -0
  20. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/rules.py +25 -4
  21. gravity_cli-0.7.6/packages/gravity-schema/gravity_schema/manifest.py → gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/specs.py +8 -455
  22. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/validation.py +35 -8
  23. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/__init__.py +365 -0
  24. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/__main__.py +35 -0
  25. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/capabilities.yaml +6598 -0
  26. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/airtable.yaml +524 -0
  27. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/asana.yaml +2481 -0
  28. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/browser_tool.yaml +117 -0
  29. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/composio_search.yaml +381 -0
  30. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/dropbox.yaml +1837 -0
  31. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/exa.yaml +284 -0
  32. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/excel.yaml +1018 -0
  33. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/firecrawl.yaml +402 -0
  34. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/github.yaml +13718 -0
  35. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/gmail.yaml +1016 -0
  36. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/googlecalendar.yaml +691 -0
  37. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/googledocs.yaml +670 -0
  38. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/googledrive.yaml +1549 -0
  39. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/googlesheets.yaml +886 -0
  40. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/googleslides.yaml +152 -0
  41. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/googletasks.yaml +281 -0
  42. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/hackernews.yaml +185 -0
  43. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/hubspot.yaml +3468 -0
  44. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/instagram.yaml +563 -0
  45. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/jira.yaml +1570 -0
  46. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/linear.yaml +842 -0
  47. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/linkedin.yaml +366 -0
  48. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/microsoft_teams.yaml +2924 -0
  49. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/notion.yaml +921 -0
  50. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/outlook.yaml +3627 -0
  51. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/perplexityai.yaml +140 -0
  52. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/pinterest.yaml +526 -0
  53. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/reddit.yaml +563 -0
  54. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/slack.yaml +2160 -0
  55. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/tavily.yaml +104 -0
  56. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/connectors/youtube.yaml +1221 -0
  57. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/core_shapes.yaml +492 -0
  58. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/generated_shapes.yaml +3231 -0
  59. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/policy.yaml +51 -0
  60. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/airtable.json +27 -0
  61. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/asana.json +158 -0
  62. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/browser_tool.json +7 -0
  63. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/composio_search.json +23 -0
  64. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/dropbox.json +177 -0
  65. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/exa.json +21 -0
  66. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/excel.json +57 -0
  67. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/firecrawl.json +31 -0
  68. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/github.json +877 -0
  69. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/gmail.json +63 -0
  70. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/googlecalendar.json +49 -0
  71. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/googledocs.json +48 -0
  72. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/googledrive.json +94 -0
  73. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/googlesheets.json +52 -0
  74. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/googleslides.json +9 -0
  75. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/googletasks.json +18 -0
  76. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/hackernews.json +16 -0
  77. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/hubspot.json +283 -0
  78. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/instagram.json +34 -0
  79. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/jira.json +100 -0
  80. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/linear.json +49 -0
  81. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/linkedin.json +27 -0
  82. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/microsoft_teams.json +171 -0
  83. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/notion.json +59 -0
  84. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/outlook.json +296 -0
  85. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/perplexityai.json +11 -0
  86. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/pinterest.json +29 -0
  87. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/reddit.json +31 -0
  88. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/slack.json +163 -0
  89. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/tavily.json +7 -0
  90. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas/youtube.json +59 -0
  91. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/schemas.py +158 -0
  92. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/ochat.yaml +88 -0
  93. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/ocrm.yaml +158 -0
  94. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/ogh.yaml +518 -0
  95. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/oms.yaml +166 -0
  96. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/oweb.yaml +231 -0
  97. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/owork.yaml +234 -0
  98. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/shared.yaml +307 -0
  99. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/sync.py +228 -0
  100. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/ochat.yaml +47 -0
  101. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/ocrm.yaml +59 -0
  102. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/ogh.yaml +169 -0
  103. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/oms.yaml +34 -0
  104. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/oweb.yaml +55 -0
  105. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/owork.yaml +43 -0
  106. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rchat.yaml +24 -0
  107. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rfiles.yaml +39 -0
  108. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rgh.yaml +20 -0
  109. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rtrack.yaml +26 -0
  110. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rwork.yaml +40 -0
  111. gravity_cli-0.9.0/packages/gravity-schema/gravity_schema/vocabulary/verbs.yaml +208 -0
  112. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/pyproject.toml +1 -1
  113. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/schema/manifest.schema.json +684 -143
  114. gravity_cli-0.9.0/packages/gravity-schema/tests/conftest.py +84 -0
  115. gravity_cli-0.9.0/packages/gravity-schema/tests/fixtures/demo_manifests.yaml +153 -0
  116. gravity_cli-0.9.0/packages/gravity-schema/tests/test_describe.py +239 -0
  117. gravity_cli-0.9.0/packages/gravity-schema/tests/test_generated_tables.py +58 -0
  118. gravity_cli-0.9.0/packages/gravity-schema/tests/test_instance.py +437 -0
  119. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_json_schema.py +33 -9
  120. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_manifest.py +12 -1
  121. gravity_cli-0.9.0/packages/gravity-schema/tests/test_manifest_v2.py +301 -0
  122. gravity_cli-0.9.0/packages/gravity-schema/tests/test_place_maker.py +15 -0
  123. gravity_cli-0.9.0/packages/gravity-schema/tests/test_slots.py +104 -0
  124. gravity_cli-0.9.0/packages/gravity-schema/tests/test_sync.py +85 -0
  125. gravity_cli-0.9.0/packages/gravity-schema/tests/test_vocabulary.py +146 -0
  126. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/pyproject.toml +2 -2
  127. gravity_cli-0.9.0/scripts/composio-watch.sh +79 -0
  128. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/BUILDER_GUIDE.md +37 -1
  129. gravity_cli-0.9.0/src/gravity_cli/BUILDER_GUIDE_V2.md +469 -0
  130. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/CHANGELOG.md +18 -0
  131. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/_runner_script.py +15 -1
  132. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/cli.py +34 -9
  133. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/adapt.py +3 -0
  134. gravity_cli-0.9.0/src/gravity_cli/commands/capabilities.py +124 -0
  135. gravity_cli-0.9.0/src/gravity_cli/commands/check.py +279 -0
  136. gravity_cli-0.9.0/src/gravity_cli/commands/connect.py +207 -0
  137. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/dev.py +23 -2
  138. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/docs.py +1 -1
  139. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/guide.py +14 -5
  140. gravity_cli-0.9.0/src/gravity_cli/commands/help.py +117 -0
  141. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/init.py +27 -4
  142. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/login.py +5 -0
  143. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/run.py +174 -14
  144. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/runs.py +2 -2
  145. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/schedule.py +26 -10
  146. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/validate.py +89 -17
  147. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/dev.py +98 -22
  148. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/dev_page/index.html +38 -17
  149. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/docs/Gravity.agent.md +424 -109
  150. gravity_cli-0.9.0/src/gravity_cli/docs/Gravity.getting-started.md +199 -0
  151. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/docs/problem-to-agent.md +222 -137
  152. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/inputs.py +4 -3
  153. gravity_cli-0.9.0/src/gravity_cli/manifest.py +24 -0
  154. gravity_cli-0.9.0/src/gravity_cli/templates/v2/chat/.gitignore +6 -0
  155. gravity_cli-0.9.0/src/gravity_cli/templates/v2/chat/manifest.yaml +42 -0
  156. gravity_cli-0.9.0/src/gravity_cli/templates/v2/chat/src/agent.py +71 -0
  157. gravity_cli-0.9.0/src/gravity_cli/templates/v2/chat/tests/test_agent.py +2 -0
  158. gravity_cli-0.9.0/src/gravity_cli/templates/v2/deepagent/.gitignore +6 -0
  159. gravity_cli-0.9.0/src/gravity_cli/templates/v2/deepagent/manifest.yaml +42 -0
  160. gravity_cli-0.9.0/src/gravity_cli/templates/v2/deepagent/requirements.txt +4 -0
  161. gravity_cli-0.9.0/src/gravity_cli/templates/v2/deepagent/src/agent.py +46 -0
  162. gravity_cli-0.9.0/src/gravity_cli/templates/v2/deepagent/tests/test_agent.py +2 -0
  163. gravity_cli-0.9.0/src/gravity_cli/templates/v2/minimal/.gitignore +6 -0
  164. gravity_cli-0.9.0/src/gravity_cli/templates/v2/minimal/manifest.yaml +43 -0
  165. gravity_cli-0.9.0/src/gravity_cli/templates/v2/minimal/requirements.txt +3 -0
  166. gravity_cli-0.9.0/src/gravity_cli/templates/v2/minimal/src/agent.py +50 -0
  167. gravity_cli-0.9.0/src/gravity_cli/templates/v2/minimal/tests/test_agent.py +8 -0
  168. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/.gitignore +6 -0
  169. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/manifest.yaml +47 -0
  170. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/requirements.txt +3 -0
  171. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/src/__init__.py +0 -0
  172. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/src/agent.py +15 -0
  173. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/src/gateway.py +20 -0
  174. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/src/nodes/__init__.py +0 -0
  175. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/src/nodes/agent.py +20 -0
  176. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/src/prompts.py +6 -0
  177. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/src/state.py +10 -0
  178. gravity_cli-0.9.0/src/gravity_cli/templates/v2/structured/tests/test_agent.py +2 -0
  179. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/timeline.py +1 -1
  180. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/ui.py +7 -1
  181. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/workspace.py +17 -6
  182. gravity_cli-0.9.0/starter/requirements.txt +3 -0
  183. gravity_cli-0.9.0/starter/src/summary.py +8 -0
  184. gravity_cli-0.9.0/starter/tests/test_summary.py +11 -0
  185. gravity_cli-0.9.0/starter-v2/manifest.yaml +55 -0
  186. gravity_cli-0.9.0/starter-v2/requirements.txt +3 -0
  187. gravity_cli-0.9.0/starter-v2/src/agent.py +71 -0
  188. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_agent_guide.py +64 -3
  189. gravity_cli-0.9.0/tests/test_check.py +103 -0
  190. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_connect.py +6 -0
  191. gravity_cli-0.9.0/tests/test_connect_v2.py +185 -0
  192. gravity_cli-0.9.0/tests/test_dev_v2.py +318 -0
  193. gravity_cli-0.9.0/tests/test_run_v2.py +188 -0
  194. gravity_cli-0.9.0/tests/test_schedule_v2.py +84 -0
  195. gravity_cli-0.9.0/tests/test_templates_v2.py +210 -0
  196. gravity_cli-0.9.0/tests/test_v2_cli.py +160 -0
  197. gravity_cli-0.9.0/tests/test_validate_v2.py +184 -0
  198. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_workspace.py +4 -4
  199. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/uv.lock +2 -2
  200. gravity_cli-0.7.6/packages/gravity-schema/gravity_schema/__init__.py +0 -114
  201. gravity_cli-0.7.6/packages/gravity-schema/tests/conftest.py +0 -47
  202. gravity_cli-0.7.6/packages/gravity-schema/tests/test_slots.py +0 -52
  203. gravity_cli-0.7.6/src/gravity_cli/commands/connect.py +0 -99
  204. gravity_cli-0.7.6/src/gravity_cli/manifest.py +0 -22
  205. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/.github/workflows/ci.yml +0 -0
  206. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/.github/workflows/release.yml +0 -0
  207. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/.gitignore +0 -0
  208. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/LICENSE +0 -0
  209. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/NOTICE +0 -0
  210. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/LICENSE +0 -0
  211. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/NOTICE +0 -0
  212. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/README.md +0 -0
  213. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/__main__.py +0 -0
  214. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/catalog.py +0 -0
  215. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/catalog_imported.yaml +0 -0
  216. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/cron.py +0 -0
  217. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/gen_catalog.py +0 -0
  218. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/rules_cases.json +0 -0
  219. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/gravity_schema/source_scan.py +0 -0
  220. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_accounts.py +0 -0
  221. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_actions_memory.py +0 -0
  222. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_catalog_parity.py +0 -0
  223. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_cron.py +0 -0
  224. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_errors.py +0 -0
  225. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_kind_outputs.py +0 -0
  226. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_rules.py +0 -0
  227. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_source_scan.py +0 -0
  228. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/packages/gravity-schema/tests/test_validation.py +0 -0
  229. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/__init__.py +0 -0
  230. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/__main__.py +0 -0
  231. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/api.py +0 -0
  232. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/changelog.py +0 -0
  233. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/__init__.py +0 -0
  234. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/build.py +0 -0
  235. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/changelog.py +0 -0
  236. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/memory.py +0 -0
  237. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/push.py +0 -0
  238. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/tools.py +0 -0
  239. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/commands/update.py +0 -0
  240. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/config.py +0 -0
  241. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/localrun.py +0 -0
  242. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/project.py +0 -0
  243. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/chat/.gitignore +0 -0
  244. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/chat/manifest.yaml +0 -0
  245. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/chat/requirements.txt +0 -0
  246. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/chat/src/agent.py +0 -0
  247. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/deepagent/.gitignore +0 -0
  248. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/deepagent/manifest.yaml +0 -0
  249. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/deepagent/requirements.txt +0 -0
  250. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/deepagent/src/agent.py +0 -0
  251. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/minimal/.gitignore +0 -0
  252. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/minimal/manifest.yaml +0 -0
  253. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/minimal/requirements.txt +0 -0
  254. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/minimal/src/agent.py +0 -0
  255. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/structured/.gitignore +0 -0
  256. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/structured/manifest.yaml +0 -0
  257. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/structured/requirements.txt +0 -0
  258. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/structured/src/agent.py +0 -0
  259. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/structured/src/gateway.py +0 -0
  260. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/structured/src/nodes/agent.py +0 -0
  261. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/structured/src/prompts.py +0 -0
  262. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/templates/structured/src/state.py +0 -0
  263. {gravity_cli-0.7.6/starter → gravity_cli-0.9.0/src/gravity_cli/templates/v2/chat}/requirements.txt +0 -0
  264. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/src/gravity_cli/updater.py +0 -0
  265. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/starter/manifest.yaml +0 -0
  266. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/starter/src/agent.py +0 -0
  267. {gravity_cli-0.7.6/starter → gravity_cli-0.9.0/starter-v2}/src/summary.py +0 -0
  268. {gravity_cli-0.7.6/starter → gravity_cli-0.9.0/starter-v2}/tests/test_summary.py +0 -0
  269. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/conftest.py +0 -0
  270. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_adapt.py +0 -0
  271. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_agents.py +0 -0
  272. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_api.py +0 -0
  273. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_build_push.py +0 -0
  274. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_changelog.py +0 -0
  275. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_dev.py +0 -0
  276. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_gateway_token.py +0 -0
  277. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_inputs_memory.py +0 -0
  278. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_localrun.py +0 -0
  279. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_manifest_integration.py +0 -0
  280. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_run.py +0 -0
  281. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_runs.py +0 -0
  282. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_schedule.py +0 -0
  283. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_session.py +0 -0
  284. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_templates.py +0 -0
  285. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_timeline.py +0 -0
  286. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_tools.py +0 -0
  287. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_ui.py +0 -0
  288. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_updater.py +0 -0
  289. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_validate.py +0 -0
  290. {gravity_cli-0.7.6 → gravity_cli-0.9.0}/tests/test_welcome.py +0 -0
@@ -2,7 +2,7 @@
2
2
  # Every gravity command loads that file. Never commit the filled-in copy.
3
3
  # What each variable does: README.md, "Environment variables".
4
4
 
5
- # --- gravity run / schedule / adapt -------------------------------------
5
+ # --- gravity run / dev / schedule / check / connect -----------------------
6
6
  # A gateway token. Leave unset: gravity login stores one for you.
7
7
  # Set it only for a local gateway (it prints one at startup, or uses its LOCAL_DEV_TOKEN).
8
8
  # GRAVITY_DEV_TOKEN=
@@ -14,9 +14,9 @@
14
14
  # The model endpoint. Leave unset: it follows the gateway (<gateway>/v1).
15
15
  # GRAVITY_LLM_URL=
16
16
 
17
- # --- push / tools / agents / runs / logs / whoami ------------------------
18
- # The control plane. Leave unset for Gravity's; set it only for a local one.
19
- # GRAVITY_API_URL=http://localhost:3010
17
+ # --- push / tools / agents / runs / logs / whoami -------------------------
18
+ # The control plane. Leave unset for the default; set it for another one.
19
+ # GRAVITY_API_URL=http://127.0.0.1:3010
20
20
 
21
21
  # Development only: the control plane's dev token, instead of `gravity login`.
22
22
  # GRAVITY_API_TOKEN=
@@ -0,0 +1,47 @@
1
+ name: Composio watch
2
+
3
+ # Every Monday: compare the Composio toolkit versions our connectors pin with what Composio serves, and open (or
4
+ # update) one issue when something needs review. scripts/composio-watch.sh says which cases alert and which don't.
5
+ on:
6
+ schedule:
7
+ - cron: "0 6 * * 1" # Mondays 06:00 UTC
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+ issues: write
13
+
14
+ concurrency:
15
+ group: composio-watch
16
+ cancel-in-progress: false
17
+
18
+ jobs:
19
+ watch:
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 30
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.12"
28
+
29
+ - name: Install gravity-schema
30
+ run: pip install -e packages/gravity-schema
31
+
32
+ - name: Check Composio
33
+ run: bash scripts/composio-watch.sh
34
+ env:
35
+ COMPOSIO_API_KEY: ${{ secrets.API_COMPOSIO_API_KEY }}
36
+ GH_TOKEN: ${{ github.token }}
37
+ WATCH_ASSIGNEE: ${{ vars.COMPOSIO_WATCH_ASSIGNEE || 'anwesha0123' }}
38
+ WATCH_OUT: ${{ runner.temp }}/composio-watch
39
+
40
+ - name: Keep the report
41
+ if: always()
42
+ uses: actions/upload-artifact@v4
43
+ with:
44
+ name: composio-watch-report
45
+ path: ${{ runner.temp }}/composio-watch
46
+ if-no-files-found: ignore
47
+ retention-days: 30
@@ -12,6 +12,9 @@ The manifest rules below are enforced by `python/gravity-schema`, the one
12
12
  model shared by the CLI, the runner and the server. Where this document and
13
13
  that package disagree, the package wins and this document has a bug.
14
14
 
15
+ Contract v2 (capabilities instead of tools, the person picks the app) is a preview with its own standard:
16
+ `AGENT_STANDARD_V2.md`. The CLI accepts both; a manifest without `contract` is v1.
17
+
15
18
  ## 1. Layout
16
19
 
17
20
  ```
@@ -0,0 +1,425 @@
1
+ # Agent submission standard — `contract: v2`
2
+
3
+ What a valid agent directory looks like, exactly what ships, and which check
4
+ catches which mistake. Follow this and `gravity build` passes, the deploy
5
+ succeeds, and the runtime loads it. Deviate and the failure happens at a stage
6
+ you can't see — after upload, on our infrastructure.
7
+
8
+ Start from `gravity init <name> --contract v2`; every v2 template already conforms
9
+ (`minimal`, `structured`, `deepagent`, `chat`).
10
+
11
+ The manifest rules below are enforced by `packages/gravity-schema`, the one
12
+ model shared by the CLI, the runner and the server. Where this document and
13
+ that package disagree, the package wins and this document has a bug.
14
+
15
+ **v2 names capabilities, never apps or tools.** An agent says what it reads
16
+ (`issue.list`) and what it changes (`issue.create`); the consumer picks the
17
+ app — Linear, Jira, Asana — when they set it up. `contract: v1` manifests
18
+ (tool names) are still accepted while the platform moves to v2; their standard is
19
+ AGENT_STANDARD.md. **v2 is a preview:** it runs only against a gateway that serves v2.
20
+
21
+ ## 1. Layout
22
+
23
+ ```
24
+ my-agent/
25
+ ├── manifest.yaml required the contract (§2)
26
+ ├── requirements.txt required your direct deps — may be empty, must exist
27
+ ├── requirements.lock generated by `gravity validate`/`build`, for the TARGET platform (§5)
28
+ ├── src/ required all your code; the entrypoint lives here
29
+ │ └── agent.py `graph` is defined here (§3)
30
+ └── tests/ optional shipped if present
31
+ ```
32
+
33
+ **Only these are bundled.** `gravity build` zips exactly `manifest.yaml`,
34
+ `requirements.txt`, `requirements.lock`, and the contents of `src/` and
35
+ `tests/` (minus dotfiles, `__pycache__` and bytecode). Anything else — `.venv/`, `build/`, notebooks,
36
+ a `data/` folder — is not shipped, and code that reads it will fail at runtime.
37
+
38
+ ## 2. `manifest.yaml`
39
+
40
+ ```yaml
41
+ contract: v2 # capabilities; the only contract accepted
42
+ name: my-agent # lowercase slug, ≤64 chars — appears in URLs
43
+ version: 1.0.0 # strict semver; bump to republish — a version can't be overwritten
44
+ description: One line. # ≤500 chars
45
+
46
+ runtime:
47
+ framework: langgraph # only value accepted
48
+ python: "3.12" # the platform runs 3.12; validate refuses any other
49
+ entrypoint: src/agent.py:graph # file:object — see §3
50
+ timeout_seconds: 300 # 10–900
51
+
52
+ dependencies:
53
+ lockfile: requirements.lock # leave as-is
54
+
55
+ inputs: # becomes the consumer's form; arrives as state["inputs"]
56
+ - name: query # the key in state["inputs"]
57
+ type: text # text | textarea | number | boolean | static-dropdown | email | url | date | secret | file
58
+ label: "What should I do?" # what the consumer sees
59
+ required: true
60
+ # options: [a, b] # static-dropdown only
61
+ # accept: [pdf, csv] # file only — extensions without the dot
62
+ # default: ... # never on a file input
63
+
64
+ models:
65
+ tier: standard # standard | premium
66
+
67
+ sources: # what the agent reads; the key is the name your code uses (§4)
68
+ tasks:
69
+ capability: issue.list # <shape>.<verb>, a read: list | search | get (`gravity capabilities`)
70
+ default_app: linear # the app it is built for (expected): setup starts with it, the consumer sees it before
71
+ # connecting anything, and chat prefers it; the consumer may change it
72
+ label: "Where your issues live" # the question the consumer answers at setup
73
+ window: 7d # optional: 24h, 7d, 4w or since_last_run; the consumer may change it
74
+ filters: {state: open} # optional: the shape's standard filters; the consumer may change them
75
+ # required: false # the agent runs without it if the consumer picks nothing
76
+ # apps: [linear, jira] # optional: limit the consumer's choice
77
+
78
+ writes: # what the agent changes while it runs, as often as it decides
79
+ follow_up:
80
+ capability: issue.create
81
+ label: "Where follow-ups go"
82
+
83
+ resources:
84
+ memory_mb: 512 # 128–4096; a request the platform clamps
85
+
86
+ triggers: # optional — what starts a run
87
+ manual: true # default
88
+ # schedule:
89
+ # cron: "0 9 * * 1" # 5 fields: digits, * / , - only (no @daily, no MON); every 5 minutes at the fastest; one day field at most; Asia/Kolkata
90
+ # consumer_can_change: true
91
+
92
+ approvals: # optional — writes that pause for the consumer's yes
93
+ required_for: [issue.create] # each call of these capabilities waits; a delete (any *.delete)
94
+ # is off by default and must be listed here. Delivering an
95
+ # output isn't held: the consumer's pick is the consent
96
+
97
+ # built_ins: [supadata.get_transcript] # optional — tools built into the gateway (no app to connect);
98
+ # # they join the run's grant. List them: gravity capabilities built_ins
99
+
100
+ # state: # optional — memory across runs, per consumer
101
+ # max_kb: 256 # 1–256; leave out and the agent gets none
102
+ ```
103
+
104
+ **`approvals` is enforced by the gateway.** A listed capability's call is held until a
105
+ human answers: in `gravity run` you're asked (`y approve · n reject · enter reject`,
106
+ default no; no answer is a no) and `gravity dev` shows Approve/Reject buttons; in the
107
+ product it's the consumer's approval inbox. Not
108
+ approved, the call returns `APPROVAL_REJECTED` (or `APPROVAL_TIMEOUT` after 4
109
+ minutes) and never runs — handle that and fall back, as `meeting-notes`
110
+ keeps the recap as a draft. Your code can't skip the question: the gateway
111
+ holds the call, not the agent. Hosted, with tools from `gravity.tools()`, the
112
+ run pauses durably instead of holding the call (§8).
113
+
114
+ `triggers` and `state` are part of the contract so a published agent never
115
+ has to change to use them. `gravity schedule` fires `triggers.schedule` locally, and an agent
116
+ that declares `state` gets `state["memory"]` from its last finished run (saved only when a run
117
+ finishes, never over `max_kb`); hosted, EventBridge fires the schedule and the gateway keeps the memory. An agent
118
+ that nothing can start (`manual: false` with no schedule) is rejected.
119
+
120
+ There are no per-app adapters: an agent declares the write once and the consumer picks the app.
121
+ Each run gets exactly the consumer's picks as its grant — the capabilities on the apps they chose,
122
+ nothing else.
123
+
124
+ The same schema is validated twice — by `gravity validate` on your machine
125
+ and again by the server on push — because an attacker won't use the CLI.
126
+
127
+ ## 3. The entrypoint
128
+
129
+ `runtime.entrypoint` names a file under `src/` and a module-level object in
130
+ it. The runtime accepts two forms:
131
+
132
+ ```python
133
+ async def graph(): # ✓ recommended — an async factory
134
+ ...
135
+ return workflow.compile()
136
+
137
+ graph = asyncio.run(_build()) # ✗ gravity validate refuses asyncio.run at import
138
+ graph = _build() # ✓ also fine — a coroutine is awaited
139
+ ```
140
+
141
+ **Prefer the factory**, which is what the templates do. The runner calls it
142
+ fresh for every run, on that run's own event loop, after the run's env vars
143
+ are set. Read the env vars *inside* it: helper modules under `src/` are
144
+ imported once and cached, so an env var read at their top level can outlive
145
+ the run it belonged to.
146
+
147
+ A graph compiled at import without `asyncio.run` (`graph = workflow.compile()`)
148
+ also works. `gravity validate` refuses `asyncio.run` and `os.environ` / `os.getenv`
149
+ at module level under `src/`, a plain `def graph()`, and a `graph` that is a bare
150
+ value: each of those passed a build and failed when the platform loaded it.
151
+
152
+ **State.** The runtime invokes `graph.astream({"inputs": {...}}, stream_mode="updates")`
153
+ — the keyword is passed only when your `astream` accepts it, so a hand-rolled
154
+ object with a plain `astream(state)` works too (accepting `**kwargs` is the
155
+ safe habit). The dict is the
156
+ dict is the consumer's form answers keyed by `inputs[].name`. Your state
157
+ therefore needs:
158
+
159
+ ```python
160
+ class State(TypedDict):
161
+ inputs: dict # required — the consumer's form answers
162
+ result: Any # required in the FINAL state — what the consumer gets
163
+ ... # anything else is yours
164
+ ```
165
+
166
+ **Result.** When the graph finishes, `state["result"]` is what the platform
167
+ returns to the consumer. Any JSON-serialisable value — a string, a dict. A
168
+ graph that finishes without setting `result` returns nothing.
169
+
170
+ **Conversation.** Declaring a `messages` key in your state opts the agent
171
+ into conversation: the platform passes the transcript in on every turn and
172
+ stores what comes back. Don't declare it in a one-shot agent — see the
173
+ `chat` template.
174
+
175
+ Optional convention the platform surfaces if present: `source: "live" | "stub"`
176
+ — whether real tool calls happened or a mock answered.
177
+
178
+ ## 4. Imports, tools, models
179
+
180
+ **Imports: absolute, rooted at `src/`.** The runtime puts `src/` on
181
+ `sys.path` and loads your entrypoint as a top-level module. So:
182
+
183
+ ```python
184
+ from tools.scoring import score # ✓ src/tools/scoring.py
185
+ from nodes.agent import build # ✓ src/nodes/agent.py
186
+ from .nodes.agent import build # ✗ relative imports don't resolve
187
+ from src.nodes.agent import build # ✗ src/ is the root, not a package
188
+ ```
189
+
190
+ `gravity run` loads the same way, so a local run is a faithful preview.
191
+
192
+ **Sources and writes** come only through the gateway, by the names the
193
+ manifest gives them. From code, with no model in between:
194
+
195
+ ```python
196
+ tasks = await gravity.read("tasks", filters={"labels": ["bug"]}) # {"records": [...], "complete": ...}
197
+ done = await gravity.act("follow_up", draft={"title": "Fix login"}) # the write's receipt: id, link, read-back
198
+ ```
199
+
200
+ Records come back in the shape's fields (`gravity capabilities issue.list`
201
+ says which), whichever app the consumer picked; the consumer's filters and
202
+ window always apply. To let a model choose, `await gravity.tools()` gives one
203
+ LangChain tool per source and write (`sources_tasks`, `writes_follow_up`),
204
+ or use your own MCP client against `GRAVITY_GATEWAY_URL` with the run token.
205
+ Outbound network from the sandbox is open today (it may be locked down later),
206
+ but anything that acts on a user's account must go through a source or write:
207
+ that is where the user's connected app is, and a direct call would have no
208
+ credentials. Declare what you need; don't reach around it.
209
+
210
+ **Models** go through the LLM gateway with the same token:
211
+
212
+ ```python
213
+ model = ChatOpenAI(model="openai/gpt-6-luna",
214
+ base_url=os.environ["GRAVITY_LLM_URL"],
215
+ api_key=os.environ["GRAVITY_RUN_TOKEN"])
216
+ ```
217
+
218
+ **Embeddings** use the same URL and token (`<GRAVITY_LLM_URL>/embeddings`), metered
219
+ and budgeted like chat calls:
220
+
221
+ ```python
222
+ emb = OpenAIEmbeddings(model="voyageai/voyage-4-lite", # or google/gemini-embedding-2
223
+ base_url=os.environ["GRAVITY_LLM_URL"],
224
+ api_key=os.environ["GRAVITY_RUN_TOKEN"],
225
+ check_embedding_ctx_length=False) # send text, not OpenAI token ids
226
+ vectors = await emb.aembed_documents(["first text", "second text"])
227
+ ```
228
+
229
+ **Images** come from an image model through the same URL and token: nothing to
230
+ declare. Ask for image output; the picture comes back as a data URL, which is
231
+ exactly what the corpus takes (§8):
232
+
233
+ ```python
234
+ async with httpx.AsyncClient(timeout=120) as http:
235
+ resp = await http.post(f"{os.environ['GRAVITY_LLM_URL']}/chat/completions",
236
+ headers={"Authorization": f"Bearer {os.environ['GRAVITY_RUN_TOKEN']}"},
237
+ json={"model": "google/gemini-2.5-flash-image", # or openai/gpt-5-image-mini
238
+ "modalities": ["image", "text"],
239
+ "messages": [{"role": "user", "content": "A flat illustration of ..., no text"}]})
240
+ resp.raise_for_status()
241
+ src = resp.json()["choices"][0]["message"]["images"][0]["image_url"]["url"] # data:image/png;base64,...
242
+ ```
243
+
244
+ An image is a few MB and the whole state is checkpointed after every step, so
245
+ make pictures in the **last** node (or the one that builds the corpus) and keep
246
+ them out of state until then. Each one is metered and counts toward the run's
247
+ budget like any model call.
248
+
249
+ Those three env vars — `GRAVITY_GATEWAY_URL`, `GRAVITY_LLM_URL`,
250
+ `GRAVITY_RUN_TOKEN` — are the entire Gravity surface, plus the `gravity`
251
+ package for tools on the platform (§8). No `OPENAI_API_KEY`: locally and in
252
+ production, models go through the gateway.
253
+
254
+ ## 5. Dependencies
255
+
256
+ List direct deps in `requirements.txt` with version ranges. `gravity validate`
257
+ compiles `requirements.lock` **for the target** — `aarch64-manylinux2014`,
258
+ Python `runtime.python`, binary wheels only — not for your laptop. The deploy
259
+ installs from the lock and nothing else.
260
+
261
+ Don't hand-edit the lock. Don't compile it yourself; a native compile on
262
+ Windows or macOS pins the wrong wheels and only fails at deploy.
263
+
264
+ ## 6. Local runs
265
+
266
+ `gravity run --input k=v` runs your graph in your own venv against a real
267
+ gateway, exactly as production does: tools over `GRAVITY_GATEWAY_URL`,
268
+ models over `GRAVITY_LLM_URL`, both with `GRAVITY_RUN_TOKEN`. `gravity login`
269
+ gives you a gateway token; each run trades it for a run token bound to your
270
+ picks, so anything undeclared is refused locally exactly as it will be when
271
+ hosted. Your agent only ever sees the run token. The gateway is the one Gravity
272
+ names (`GET /api/cli/config`); set `GRAVITY_GATEWAY_URL` (and `GRAVITY_DEV_TOKEN`,
273
+ in `~/.gravity/.env`) only for a gateway you run yourself.
274
+
275
+ You are the consumer locally: each source and write runs on its `default_app`
276
+ unless you pick another with `--use name=app[:resource=id,...]`
277
+ (`--use tasks=linear --use follow_up=jira:project=APP`) or a `--setup` file. The
278
+ picks are checked exactly as a consumer's setup is, and the apps must be
279
+ connected for the account your token acts as (`gravity connect`, or on the shared
280
+ test account, Gravity). Outputs are printed, not delivered: delivery is the
281
+ platform's. `gravity check <capability> --app <app>` tries one capability on your
282
+ account first, and says whose side a failure is on.
283
+
284
+ `gravity dev` opens a local dashboard over the same runs: a form from your
285
+ manifest, a picker for each source's and write's app, a live timeline,
286
+ approvals, the result and a history. A run from `gravity run` in the same folder
287
+ shows up in it, and the other way round (both leave their record in
288
+ `.gravity/runs/`; one run is live per folder).
289
+
290
+ ## 7. What's checked where
291
+
292
+ | Stage | Catches |
293
+ |---|---|
294
+ | `gravity validate` / `build` (local) | manifest schema · every capability exists, sources are reads, destinations take the output's rendering · filters are the shape's · blocked capabilities refused, deletes approved · `python: "3.12"` · schedules every 5 minutes at the fastest, one day field · entrypoint file + object exist, `graph` an async factory or a compiled graph (static) · no `os.environ` or `asyncio.run` at import, no relative imports · `requirements.txt` present · lockfile compiles for aarch64 · code reading or acting on a name the manifest doesn't declare (`gravity.read("x")`) · `build` refuses without the lockfile |
295
+ | `gravity push` (server) | manifest re-validated with the same rules · version not already published |
296
+ | setup (consumer) | each pick, and each extra app in its `also` list: the app serves the capability, the target it needs is picked (a channel; a table inside its base), recipients for an email are plain addresses |
297
+ | deploy | every pin in the lock installs on ARM64 |
298
+ | first run | module imports · `graph` resolves to something with `astream()` · state has `inputs` · final state has `result` |
299
+
300
+ The further right a failure lands, the longer you wait to see it. `build`
301
+ passing means everything in the first column is fine; it does not run your
302
+ code. `gravity run` does.
303
+
304
+ ## 8. On the platform: `import gravity`
305
+
306
+ Hosted runs are durable: they pause for approvals, survive a lost session,
307
+ and remember the thread between runs. The platform does that around your
308
+ graph. `gravity` is preinstalled in the image; don't put it in
309
+ `requirements.txt`.
310
+
311
+ **Tools: `await gravity.tools()`** instead of your own `MultiServerMCPClient`.
312
+ One LangChain tool per source and write (`sources_tasks`, `writes_follow_up`),
313
+ from the same env vars. Off the platform (`gravity run`, `gravity dev`, tests) it is exactly the client in §4,
314
+ but only if your venv has it: it stays out of `requirements.txt` and `gravity run`
315
+ doesn't add it, so install it yourself (`uv pip install -e <platform repo>/packages/gravity-sdk`)
316
+ or `gravity run` fails with `No module named 'gravity'`.
317
+ On the platform, each write whose capability is in `approvals.required_for` is wrapped: calling it
318
+ checkpoints the run and stops it until the consumer decides, with no
319
+ connection held open. Approved, the call runs with the arguments the consumer
320
+ saw. Declined, it returns
321
+ `APPROVAL_REJECTED: '<tool>' was not approved, so it did not run`, the same
322
+ text as today, so keep your fallback.
323
+
324
+ ```python
325
+ tools = {t.name: t for t in await gravity.tools()}
326
+ await tools["writes_follow_up"].ainvoke({"draft": {"title": "Fix login"}})
327
+ ```
328
+
329
+ When the run resumes, the node that made the call **runs again from its
330
+ start**: everything before the call happens twice.
331
+
332
+ - Put a gated call at the end of its own node, after nothing expensive or side-effecting.
333
+ - Several gated calls in one node work, each approved in turn. On each resume the
334
+ earlier calls are repeated, and the gateway answers a repeat with the stored result
335
+ instead of doing it again, so each side effect still happens once. Work *between*
336
+ the calls repeats too, so keep it cheap.
337
+ - Two approvals at once: make them parallel nodes. The consumer sees both together.
338
+ - Any `interrupt()` of your own fails the run with `UNSUPPORTED_INTERRUPT` (for now).
339
+
340
+ **Persistence is the platform's.** Compile with no checkpointer and no store
341
+ (`workflow.compile()`); the platform injects its own, and one you pass is
342
+ replaced. State is kept per thread. A key the next run doesn't send keeps its
343
+ value (a monitor's `seen`, a draft). For memory shared by one consumer's
344
+ threads, use `langgraph.config.get_store()` (`aget` / `aput` / `asearch` by
345
+ namespace and filter; no semantic search). It is kept per consumer and agent,
346
+ across runs and versions, until the agent deletes an item (`aput(ns, key, None)`);
347
+ store one item per record, not one large blob. `gravity run` gives you the same
348
+ store locally, saved in `.gravity/store.json` (delete it to start over).
349
+
350
+ **Conversation.** `messages` must use the `add_messages` reducer:
351
+ `messages: Annotated[list, add_messages]`. Each turn the platform sends only
352
+ the new user turn. The history comes from the thread's checkpoint, and a
353
+ plain `list` would replace it with that one message.
354
+
355
+ **`kind` and `outputs`.**
356
+
357
+ ```yaml
358
+ kind: transform # transform | interactive (default) | monitor
359
+ outputs: # what the consumer may ask the result to become
360
+ deck: {renderer: pptx, label: "Pitch deck", default: {destination: download}}
361
+ readout: {renderer: docx, label: "Read-out document", default: {destination: download}}
362
+ summary: {renderer: markdown, label: "Summary", destinations: [download, message.send, document.create],
363
+ default: {destination: message.send, app: gmail}}
364
+ ```
365
+
366
+ - `transform`: all input at the start, the result at the end. The platform
367
+ delivers it, so the agent needs no write tools.
368
+ - `interactive`: calls tools mid-flow and may converse over several turns.
369
+ - `monitor`: runs on a schedule or a webhook, on one thread, remembering the
370
+ last run. It needs `triggers.schedule` or a webhook.
371
+
372
+ `destinations` is where an output may go: `download` (the default), or a
373
+ capability that takes its rendering — markdown: `message.send`,
374
+ `message.create`, `document.create`, `issue.create`, `comment.create`,
375
+ `post.create`, `file.create`; docx and pptx: `file.create`, `message.send`
376
+ (and `presentation.create` for a deck); rows: `row.append`, `file.create`.
377
+ `default` (expected; `gravity validate` warns without it) is where it goes
378
+ unless the consumer picks otherwise: a download, or a destination and its
379
+ app. The consumer can change it, and picks the place (a Slack channel, a
380
+ Notion page, recipients for an email) at setup, or asks for it in chat. The
381
+ consumer may also send it to more places (`also`: an email and a Notion page),
382
+ and read several apps into one source; the agent sees one merged list, each
383
+ record tagged with its app in `extra.app`. The platform delivers it after the
384
+ run, not the agent, so the agent declares no write for it; an email goes at
385
+ most once per run and a thread sends at most 200 a day, extra places included.
386
+
387
+ Renderers: `markdown`, `docx`, `pptx`, `rows` (the first table, as CSV). Each
388
+ consumer picks outputs and destinations per run. The agent writes one
389
+ **corpus** into its final state, and every output is rendered from it:
390
+
391
+ ```python
392
+ corpus = gravity.Corpus(
393
+ title="Acme: seed round", subtitle="2026", summary="**Why now**: ...",
394
+ sections=[gravity.Section(
395
+ heading="Market", body="markdown", bullets=["..."],
396
+ facts=[gravity.Fact(label="TAM", value="$18B", source="s1")], # value: text or a number
397
+ table=gravity.Table(columns=["Segment", "Teams"], rows=[["Founders", "1.2M"]]),
398
+ notes="speaker notes / read-out text",
399
+ images=[gravity.Image(src=src, alt="server rack", caption="Option A")], # data URL, see §4
400
+ sections=[gravity.Section(heading="one level of nesting, same shape")],
401
+ )],
402
+ sources=[gravity.Source(id="s1", title="Report", url="https://example.com")],
403
+ )
404
+ return {**corpus.to_state(), "result": {"title": corpus.title}}
405
+ ```
406
+
407
+ A plain dict of the same shape works too. The models catch a typo when the
408
+ corpus is built rather than when it's rendered. Images (`png`, `jpeg`, `webp`
409
+ or `gif` data URLs, at most 8 MB each and 12 per corpus) are embedded in the
410
+ Word, PowerPoint and Markdown downloads and shown on `/app` and in `gravity
411
+ dev`; an emailed output names each one as `[image: alt — caption]` instead. Set
412
+ `result` as well: it's what the run returns.
413
+
414
+ ## 9. Checklist
415
+
416
+ - [ ] `manifest.yaml` with `contract: v2`: what the agent reads under `sources`, what it changes under `writes` (capabilities, never apps)
417
+ - [ ] `requirements.txt` exists (empty is fine)
418
+ - [ ] `src/agent.py` defines module-level `graph`: an `async def` factory (recommended) or a compiled graph
419
+ - [ ] env vars read inside `graph()`, not at module level; no `asyncio.run` at import; `python: "3.12"`
420
+ - [ ] state has `inputs`; final state sets `result`; `messages` only if the agent is conversational, with `add_messages`
421
+ - [ ] sources and writes through `gravity.read` / `gravity.act` (or `gravity.tools()`); compiled with no checkpointer; nothing expensive before a gated call (§8)
422
+ - [ ] all imports under `src/` are absolute from `src/`
423
+ - [ ] nothing acts on a user's account except through a source or write; models via the LLM URL
424
+ - [ ] nothing your code needs lives outside `src/` or `tests/`
425
+ - [ ] `gravity check --manifest .` and `gravity build` pass; `gravity run` (or `gravity dev`) produces a `result`
@@ -1,3 +1,20 @@
1
+ Metadata-Version: 2.5
2
+ Name: gravity-cli
3
+ Version: 0.9.0
4
+ Summary: gravity cli — init, run, and push python agents to the Gravity marketplace
5
+ License-Expression: Apache-2.0
6
+ License-File: LICENSE
7
+ License-File: NOTICE
8
+ Requires-Python: >=3.12
9
+ Requires-Dist: gravity-schema==0.9.0
10
+ Requires-Dist: httpx>=0.27.0
11
+ Requires-Dist: keyring>=25.0.0
12
+ Requires-Dist: python-dotenv>=1.0.0
13
+ Requires-Dist: rich>=13.9.0
14
+ Requires-Dist: typer>=0.15.0
15
+ Requires-Dist: uv>=0.8.0
16
+ Description-Content-Type: text/markdown
17
+
1
18
  <h1 align="center">Gravity CLI</h1>
2
19
 
3
20
  <p align="center">
@@ -194,7 +211,7 @@ Run `gravity help` for this list in the terminal, and add `-h` to any command fo
194
211
  | | [`gravity connect`](#gravity-connect) | Connect an account your agents act on (Gmail, Slack...) |
195
212
  | **Help** | [`gravity guide`](#gravity-guide) | Read the builder guide: how to build a good agent |
196
213
  | | [`gravity help`](#gravity-help) | Show the list of commands |
197
- | **Gravity CLI** | [`gravity docs`](#gravity-docs) | Write `Gravity.agent.md` for the coding agent in this folder |
214
+ | **Gravity CLI** | [`gravity docs`](#gravity-docs) | Write the Gravity guides for you and your coding agent in this folder |
198
215
  | | [`gravity update`](#gravity-update) | Update to the latest release and see what is new |
199
216
  | | [`gravity changelog`](#gravity-changelog) | What changed in each release |
200
217
 
@@ -490,7 +507,7 @@ gravity guide | less
490
507
 
491
508
  ### `gravity docs`
492
509
 
493
- Write or refresh the two files a coding agent needs to build for Gravity in this folder: `Gravity.agent.md` (how Gravity runs agents, the manifest, every tool this release knows, the output formats, the rules that fail a load) and `problem-to-agent.md` (the method for turning a problem statement into an agent that holds up).
510
+ Write or refresh the three files that help you and your coding agent build for Gravity in this folder: `Gravity.agent.md` (how Gravity runs agents, the manifest, every tool this release knows, the output formats, the rules that fail a load) `problem-to-agent.md` (the method for turning a problem statement into an agent that holds up, with the bar an agent must meet), and `Gravity.getting-started.md` (a plain-language overview of Gravity, agents and the CLI for someone new).
494
511
 
495
512
  ```
496
513
  gravity docs [--force]
@@ -500,7 +517,7 @@ gravity docs [--force]
500
517
  |---|---|
501
518
  | `--force` | Replace the files even where you edited them, or where a file Gravity did not write has the same name |
502
519
 
503
- You rarely need this. Every command writes the two files into the folder it runs in if they are missing (never into your home folder or a drive root; `gravity init` writes them into the new agent), and rewrites them when a newer release changes them. The first line of a file Gravity wrote names the release and a hash of the text after it: if you edit the file the hash no longer matches and Gravity leaves it alone. Your own `agent.md`, `AGENTS.md` and `CLAUDE.md` are never touched. Point your coding agent at `Gravity.agent.md` from them if it does not look there by itself. Set `GRAVITY_AGENT_DOCS=0` to stop the automatic writes.
520
+ You rarely need this. Every command writes the three files into the folder it runs in if they are missing (never into your home folder or a drive root; `gravity init` writes them into the new agent), and rewrites them when a newer release changes them. The first line of a file Gravity wrote names the release and a hash of the text after it: if you edit the file the hash no longer matches and Gravity leaves it alone. Your own `agent.md`, `AGENTS.md` and `CLAUDE.md` are never touched. Point your coding agent at `Gravity.agent.md` from them if it does not look there by itself. Set `GRAVITY_AGENT_DOCS=0` to stop the automatic writes.
504
521
 
505
522
  ### `gravity update`
506
523
 
@@ -584,7 +601,7 @@ Set `GRAVITY_API_URL` and `GRAVITY_GATEWAY_URL` only to work against services yo
584
601
  | `GRAVITY_API_TOKEN` | A control-plane dev token, used instead of `gravity login`. For development only. | none |
585
602
  | `GRAVITY_CONFIG_DIR` | Moves `~/.gravity` elsewhere. Useful for tests and CI. | `~/.gravity` |
586
603
  | `GRAVITY_AUTO_UPDATE` | When `0`, commands neither check for a newer release nor install one. Always off when `CI` is set. | `1` |
587
- | `GRAVITY_AGENT_DOCS` | When `0`, commands do not write `Gravity.agent.md` and `problem-to-agent.md` into the folder they run in. `gravity docs` still does. | `1` |
604
+ | `GRAVITY_AGENT_DOCS` | When `0`, commands do not write `Gravity.agent.md`, `problem-to-agent.md` and `Gravity.getting-started.md` into the folder they run in. `gravity docs` still does. | `1` |
588
605
  | `GRAVITY_UPDATE_URL` | Where the latest version is read from, a JSON document with `info.version`. For tests and mirrors. | PyPI |
589
606
  | `GRAVITY_UNATTENDED` | When `1`, calls that need approval are rejected without asking. `gravity schedule` sets it for you. | unset |
590
607
 
@@ -739,6 +756,21 @@ outputs: # extra formats the platform renders and deliv
739
756
 
740
757
  Unknown fields are rejected rather than ignored, so a typo is reported instead of silently dropped.
741
758
 
759
+ ### Contract v2 (preview)
760
+
761
+ The CLI also reads `contract: v2` manifests, where an agent names **capabilities** (`message.list`, `issue.create`)
762
+ instead of tools, and the person picks the app when they set it up: Gmail or Outlook, Linear or Jira. What it reads
763
+ goes under `sources`, what it changes under `writes`; code calls `gravity.read("inbox")` and `gravity.act("send", ...)`.
764
+ v2 runs only against a gateway that serves it, and Gravity's hosted gateway runs v1 for now.
765
+
766
+ ```bash
767
+ gravity init my-agent --contract v2 # the v2 templates
768
+ gravity capabilities message # what exists, and which apps serve it
769
+ gravity check message.list --app gmail # try one on your own account (v2 gateway)
770
+ gravity run --use inbox=outlook # pick the app for a local run
771
+ gravity guide --contract v2 # the v2 guide; the rules are in AGENT_STANDARD_V2.md
772
+ ```
773
+
742
774
  ## An agent project
743
775
 
744
776
  ```
@@ -907,6 +939,7 @@ uv run python -m gravity_schema.gen_catalog --root <platform repo>/code-first
907
939
  | [Builder guide](src/gravity_cli/BUILDER_GUIDE.md) | How to build a good agent, start to finish, with a complete example. Also `gravity guide` |
908
940
  | [`Gravity.agent.md`](src/gravity_cli/docs/Gravity.agent.md) | The guide `gravity docs` writes for coding agents; its tool list is filled in from the catalog of the release that writes it |
909
941
  | [`problem-to-agent.md`](src/gravity_cli/docs/problem-to-agent.md) | The method for turning a problem statement into an agent that holds up |
942
+ | [`Gravity.getting-started.md`](src/gravity_cli/docs/Gravity.getting-started.md) | A plain-language overview of Gravity, agents and the CLI, for someone new |
910
943
  | [Agent standard](AGENT_STANDARD.md) | The exact rules an agent must follow |
911
944
  | [Templates](TEMPLATES.md) | The four templates and when to pick each |
912
945
  | [`manifest.schema.json`](packages/gravity-schema/schema/manifest.schema.json) | The manifest as a machine-readable JSON Schema |