gravity-cli 0.5.4__tar.gz → 0.5.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 (114) hide show
  1. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/PKG-INFO +3 -2
  2. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/README.md +1 -0
  3. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/manifest.py +35 -0
  4. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/pyproject.toml +1 -1
  5. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/schema/manifest.schema.json +97 -0
  6. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/test_manifest.py +21 -0
  7. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/pyproject.toml +2 -2
  8. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/uv.lock +6 -6
  9. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/.env.example +0 -0
  10. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/.github/workflows/ci.yml +0 -0
  11. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/.github/workflows/release.yml +0 -0
  12. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/.gitignore +0 -0
  13. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/AGENT_STANDARD.md +0 -0
  14. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/LICENSE +0 -0
  15. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/NOTICE +0 -0
  16. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/RELEASING.md +0 -0
  17. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/TEMPLATES.md +0 -0
  18. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/LICENSE +0 -0
  19. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/NOTICE +0 -0
  20. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/README.md +0 -0
  21. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/__init__.py +0 -0
  22. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/__main__.py +0 -0
  23. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/catalog.py +0 -0
  24. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/catalog.yaml +0 -0
  25. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/catalog_imported.yaml +0 -0
  26. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/contract.py +0 -0
  27. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/cron.py +0 -0
  28. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/errors.py +0 -0
  29. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/export.py +0 -0
  30. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/gen_catalog.py +0 -0
  31. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/source_scan.py +0 -0
  32. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/gravity_schema/validation.py +0 -0
  33. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/conftest.py +0 -0
  34. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/test_catalog_parity.py +0 -0
  35. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/test_cron.py +0 -0
  36. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/test_errors.py +0 -0
  37. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/test_json_schema.py +0 -0
  38. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/test_kind_outputs.py +0 -0
  39. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/test_slots.py +0 -0
  40. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/test_source_scan.py +0 -0
  41. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/packages/gravity-schema/tests/test_validation.py +0 -0
  42. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/BUILDER_GUIDE.md +0 -0
  43. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/__init__.py +0 -0
  44. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/__main__.py +0 -0
  45. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/_runner_script.py +0 -0
  46. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/api.py +0 -0
  47. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/cli.py +0 -0
  48. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/__init__.py +0 -0
  49. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/adapt.py +0 -0
  50. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/build.py +0 -0
  51. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/connect.py +0 -0
  52. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/dev.py +0 -0
  53. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/guide.py +0 -0
  54. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/init.py +0 -0
  55. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/login.py +0 -0
  56. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/push.py +0 -0
  57. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/run.py +0 -0
  58. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/runs.py +0 -0
  59. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/schedule.py +0 -0
  60. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/tools.py +0 -0
  61. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/commands/validate.py +0 -0
  62. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/config.py +0 -0
  63. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/dev.py +0 -0
  64. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/dev_page/index.html +0 -0
  65. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/localrun.py +0 -0
  66. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/manifest.py +0 -0
  67. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/project.py +0 -0
  68. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/chat/.gitignore +0 -0
  69. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/chat/manifest.yaml +0 -0
  70. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/chat/requirements.txt +0 -0
  71. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/chat/src/agent.py +0 -0
  72. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/deepagent/.gitignore +0 -0
  73. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/deepagent/manifest.yaml +0 -0
  74. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/deepagent/requirements.txt +0 -0
  75. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/deepagent/src/agent.py +0 -0
  76. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/minimal/.gitignore +0 -0
  77. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/minimal/manifest.yaml +0 -0
  78. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/minimal/requirements.txt +0 -0
  79. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/minimal/src/agent.py +0 -0
  80. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/structured/.gitignore +0 -0
  81. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/structured/manifest.yaml +0 -0
  82. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/structured/requirements.txt +0 -0
  83. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/structured/src/agent.py +0 -0
  84. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/structured/src/gateway.py +0 -0
  85. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/structured/src/nodes/agent.py +0 -0
  86. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/structured/src/prompts.py +0 -0
  87. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/templates/structured/src/state.py +0 -0
  88. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/timeline.py +0 -0
  89. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/src/gravity_cli/ui.py +0 -0
  90. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/starter/manifest.yaml +0 -0
  91. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/starter/requirements.txt +0 -0
  92. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/starter/src/agent.py +0 -0
  93. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/starter/src/summary.py +0 -0
  94. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/starter/tests/test_summary.py +0 -0
  95. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/conftest.py +0 -0
  96. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_adapt.py +0 -0
  97. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_agents.py +0 -0
  98. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_api.py +0 -0
  99. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_build_push.py +0 -0
  100. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_connect.py +0 -0
  101. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_dev.py +0 -0
  102. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_gateway_token.py +0 -0
  103. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_localrun.py +0 -0
  104. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_manifest_integration.py +0 -0
  105. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_run.py +0 -0
  106. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_runs.py +0 -0
  107. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_schedule.py +0 -0
  108. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_session.py +0 -0
  109. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_templates.py +0 -0
  110. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_timeline.py +0 -0
  111. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_tools.py +0 -0
  112. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_ui.py +0 -0
  113. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_validate.py +0 -0
  114. {gravity_cli-0.5.4 → gravity_cli-0.5.5}/tests/test_welcome.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: gravity-cli
3
- Version: 0.5.4
3
+ Version: 0.5.5
4
4
  Summary: gravity cli — init, run, and push python agents to the Gravity marketplace
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
7
7
  License-File: NOTICE
8
8
  Requires-Python: >=3.12
9
- Requires-Dist: gravity-schema==0.5.4
9
+ Requires-Dist: gravity-schema==0.5.5
10
10
  Requires-Dist: httpx>=0.27.0
11
11
  Requires-Dist: keyring>=25.0.0
12
12
  Requires-Dist: python-dotenv>=1.0.0
@@ -792,6 +792,7 @@ Real tools act on a connected account. Connect one with `gravity-gateway connect
792
792
 
793
793
  ## What's new
794
794
 
795
+ - **0.5.5** `manifest.yaml` takes an optional `display:` hint for how a run's result shows: `view` (document, report, table, chart, code or files), `field` (the result key to show) and `chart` (`type: line` or `bar`, `x`, and up to three `y` fields). It is a hint, never a rule: an unknown view or key is ignored, so it never fails a push. 0.5.4 and earlier refuse a manifest that has it.
795
796
  - **0.5.4** `gravity agents` shows each agent's review: a REVIEW column (not submitted, submitted, approved, rejected), and under "From the Gravity team" the reviewer's notes and what to do next. An agent the Gravity team turned off shows as `off` with the reason. UPDATED reads "3 min ago" instead of a timestamp, and status and review are coloured. Also, from a full audit of every command: `gravity --version`. Clear messages instead of tracebacks for: a proxy or sign-in page answering instead of Gravity, a refused `GRAVITY_API_TOKEN` or `GRAVITY_DEV_TOKEN`, an expired sign-in code, a non-UTF-8 manifest, an out-of-range `--port`, a missing agent folder, a malformed session file. `gravity validate` now refuses what the build would refuse: a `graph` that is not an async factory, `os.environ` or `asyncio.run` at import, relative imports, unquoted `python: 3.12`, schedules faster than every 5 minutes or with both day fields, out-of-range cron fields; it accepts a re-exported `graph`. `gravity agents` shows the review status and failure reasons; `gravity runs` never shortens an id; `gravity logs` never wraps. `gravity push` refuses a bundle over 30 MB or a manifest over 12 KB before uploading, and says why when a failed version is re-pushed. `gravity build` ships `tools_needed.yaml`, leaves dotfiles out, and refuses to build without `requirements.lock`. `gravity adapt` leaves the folder untouched when a model call fails. `gravity schedule` checks inputs before the first tick and runs on Asia/Kolkata like the hosted schedules. `gravity run` deletes `.gravity/payload.json` after the run, warns when no `.venv` is present, and keeps a plain agent's `result`. `gravity connect <app>` refuses on the shared test account instead of attaching your account to it. The builder guide and agent standard describe the real flow (init, validate, run or dev, build, push, review on /app).
796
797
  - **0.5.3** `gravity dev` opens a local dashboard for your agent: a form from your manifest, a live timeline, approvals, the result and run history; runs from `gravity run` in the same folder show up in it live, and the other way round. WhatsApp joins the catalog (51 tools; 1,402 across 15 apps including the curated and built-in ones). Agents can return generated images: put them in a corpus section's `images` and they land in the Word, PowerPoint and Markdown outputs. The agent standard now shows how to generate images and embeddings through the gateway. `NEEDS_RECONNECT` on the shared test account tells you to ask Gravity, not to connect your own account.
797
798
  - **0.5.2** Jira, Confluence and Notion join the catalog: 1,351 tools across 11 apps. `get_store()` works in local runs, kept in `.gravity/store.json`. Renewing an expired sign-in keeps your gateway token, so `gravity run` keeps working after an hour. Commands start faster: the catalog loads in a quarter of the time.
@@ -775,6 +775,7 @@ Real tools act on a connected account. Connect one with `gravity-gateway connect
775
775
 
776
776
  ## What's new
777
777
 
778
+ - **0.5.5** `manifest.yaml` takes an optional `display:` hint for how a run's result shows: `view` (document, report, table, chart, code or files), `field` (the result key to show) and `chart` (`type: line` or `bar`, `x`, and up to three `y` fields). It is a hint, never a rule: an unknown view or key is ignored, so it never fails a push. 0.5.4 and earlier refuse a manifest that has it.
778
779
  - **0.5.4** `gravity agents` shows each agent's review: a REVIEW column (not submitted, submitted, approved, rejected), and under "From the Gravity team" the reviewer's notes and what to do next. An agent the Gravity team turned off shows as `off` with the reason. UPDATED reads "3 min ago" instead of a timestamp, and status and review are coloured. Also, from a full audit of every command: `gravity --version`. Clear messages instead of tracebacks for: a proxy or sign-in page answering instead of Gravity, a refused `GRAVITY_API_TOKEN` or `GRAVITY_DEV_TOKEN`, an expired sign-in code, a non-UTF-8 manifest, an out-of-range `--port`, a missing agent folder, a malformed session file. `gravity validate` now refuses what the build would refuse: a `graph` that is not an async factory, `os.environ` or `asyncio.run` at import, relative imports, unquoted `python: 3.12`, schedules faster than every 5 minutes or with both day fields, out-of-range cron fields; it accepts a re-exported `graph`. `gravity agents` shows the review status and failure reasons; `gravity runs` never shortens an id; `gravity logs` never wraps. `gravity push` refuses a bundle over 30 MB or a manifest over 12 KB before uploading, and says why when a failed version is re-pushed. `gravity build` ships `tools_needed.yaml`, leaves dotfiles out, and refuses to build without `requirements.lock`. `gravity adapt` leaves the folder untouched when a model call fails. `gravity schedule` checks inputs before the first tick and runs on Asia/Kolkata like the hosted schedules. `gravity run` deletes `.gravity/payload.json` after the run, warns when no `.venv` is present, and keeps a plain agent's `result`. `gravity connect <app>` refuses on the shared test account instead of attaching your account to it. The builder guide and agent standard describe the real flow (init, validate, run or dev, build, push, review on /app).
779
780
  - **0.5.3** `gravity dev` opens a local dashboard for your agent: a form from your manifest, a live timeline, approvals, the result and run history; runs from `gravity run` in the same folder show up in it live, and the other way round. WhatsApp joins the catalog (51 tools; 1,402 across 15 apps including the curated and built-in ones). Agents can return generated images: put them in a corpus section's `images` and they land in the Word, PowerPoint and Markdown outputs. The agent standard now shows how to generate images and embeddings through the gateway. `NEEDS_RECONNECT` on the shared test account tells you to ask Gravity, not to connect your own account.
780
781
  - **0.5.2** Jira, Confluence and Notion join the catalog: 1,351 tools across 11 apps. `get_store()` works in local runs, kept in `.gravity/store.json`. Renewing an expired sign-in keeps your gateway token, so `gravity run` keeps working after an hour. Commands start faster: the catalog loads in a quarter of the time.
@@ -14,6 +14,8 @@ from .errors import ErrorCode
14
14
 
15
15
  # Unknown fields are rejected, so a newer-contract field is reported, not dropped.
16
16
  _STRICT = ConfigDict(extra="forbid", str_strip_whitespace=True)
17
+ # Display hints only: an unknown key is dropped rather than refused (DisplaySpec).
18
+ _HINT = ConfigDict(extra="ignore", str_strip_whitespace=True)
17
19
 
18
20
 
19
21
  class InputType(str, Enum):
@@ -517,6 +519,37 @@ class SlotSpec(BaseModel):
517
519
  return self
518
520
 
519
521
 
522
+ class ChartHint(BaseModel):
523
+ """Which of the records' fields to plot: `x` along the bottom, `y` as the lines or bars."""
524
+
525
+ model_config = _HINT
526
+
527
+ type: Annotated[str, Field(max_length=C.MAX_NAME_LENGTH)] | None = None # line | bar
528
+ x: Annotated[str, Field(max_length=C.MAX_NAME_LENGTH)] | None = None
529
+ y: Annotated[list[Annotated[str, Field(max_length=C.MAX_NAME_LENGTH)]], Field(max_length=3)] = Field(
530
+ default_factory=list
531
+ )
532
+
533
+
534
+ class DisplaySpec(BaseModel):
535
+ """How the run's result shows on the page, when the builder wants to say so.
536
+
537
+ A hint, not a rule: without it the page reads the result's own shape, and a
538
+ value the page doesn't know (a typo, a newer view) is ignored the same way,
539
+ so it never fails a push or a run.
540
+
541
+ view: document | report | table | chart | code | files
542
+ field: the result key that is the main thing to show
543
+ chart: {type: line | bar, x: date, y: [reach, likes]}
544
+ """
545
+
546
+ model_config = _HINT
547
+
548
+ view: Annotated[str, Field(max_length=C.MAX_NAME_LENGTH)] | None = None
549
+ field: Annotated[str, Field(max_length=C.MAX_NAME_LENGTH)] | None = None
550
+ chart: ChartHint | None = None
551
+
552
+
520
553
  class Manifest(BaseModel):
521
554
  """A complete agent declaration. Structural only: tool existence is checked in validation.py."""
522
555
 
@@ -541,6 +574,8 @@ class Manifest(BaseModel):
541
574
  kind: AgentKind = AgentKind.INTERACTIVE
542
575
  # Empty: the agent returns `result` only.
543
576
  outputs: dict[str, OutputSpec] = Field(default_factory=dict)
577
+ # How the result shows on screen; absent, the page decides from the result itself.
578
+ display: DisplaySpec | None = None
544
579
 
545
580
  @field_validator("contract")
546
581
  @classmethod
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "gravity-schema"
3
- version = "0.5.4"
3
+ version = "0.5.5"
4
4
  description = "Gravity agent manifest contract — models, validation, and JSON Schema export"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -26,6 +26,48 @@
26
26
  "title": "ApprovalsSpec",
27
27
  "type": "object"
28
28
  },
29
+ "ChartHint": {
30
+ "description": "Which of the records' fields to plot: `x` along the bottom, `y` as the lines or bars.",
31
+ "properties": {
32
+ "type": {
33
+ "anyOf": [
34
+ {
35
+ "maxLength": 64,
36
+ "type": "string"
37
+ },
38
+ {
39
+ "type": "null"
40
+ }
41
+ ],
42
+ "default": null,
43
+ "title": "Type"
44
+ },
45
+ "x": {
46
+ "anyOf": [
47
+ {
48
+ "maxLength": 64,
49
+ "type": "string"
50
+ },
51
+ {
52
+ "type": "null"
53
+ }
54
+ ],
55
+ "default": null,
56
+ "title": "X"
57
+ },
58
+ "y": {
59
+ "items": {
60
+ "maxLength": 64,
61
+ "type": "string"
62
+ },
63
+ "maxItems": 3,
64
+ "title": "Y",
65
+ "type": "array"
66
+ }
67
+ },
68
+ "title": "ChartHint",
69
+ "type": "object"
70
+ },
29
71
  "DependenciesSpec": {
30
72
  "additionalProperties": false,
31
73
  "properties": {
@@ -38,6 +80,50 @@
38
80
  "title": "DependenciesSpec",
39
81
  "type": "object"
40
82
  },
83
+ "DisplaySpec": {
84
+ "description": "How the run's result shows on the page, when the builder wants to say so.\n\nA hint, not a rule: without it the page reads the result's own shape, and a\nvalue the page doesn't know (a typo, a newer view) is ignored the same way,\nso it never fails a push or a run.\n\n view: document | report | table | chart | code | files\n field: the result key that is the main thing to show\n chart: {type: line | bar, x: date, y: [reach, likes]}",
85
+ "properties": {
86
+ "chart": {
87
+ "anyOf": [
88
+ {
89
+ "$ref": "#/$defs/ChartHint"
90
+ },
91
+ {
92
+ "type": "null"
93
+ }
94
+ ],
95
+ "default": null
96
+ },
97
+ "field": {
98
+ "anyOf": [
99
+ {
100
+ "maxLength": 64,
101
+ "type": "string"
102
+ },
103
+ {
104
+ "type": "null"
105
+ }
106
+ ],
107
+ "default": null,
108
+ "title": "Field"
109
+ },
110
+ "view": {
111
+ "anyOf": [
112
+ {
113
+ "maxLength": 64,
114
+ "type": "string"
115
+ },
116
+ {
117
+ "type": "null"
118
+ }
119
+ ],
120
+ "default": null,
121
+ "title": "View"
122
+ }
123
+ },
124
+ "title": "DisplaySpec",
125
+ "type": "object"
126
+ },
41
127
  "InputSpec": {
42
128
  "additionalProperties": false,
43
129
  "description": "One value the consumer supplies. Renders as one form field.",
@@ -381,6 +467,17 @@
381
467
  "title": "Description",
382
468
  "type": "string"
383
469
  },
470
+ "display": {
471
+ "anyOf": [
472
+ {
473
+ "$ref": "#/$defs/DisplaySpec"
474
+ },
475
+ {
476
+ "type": "null"
477
+ }
478
+ ],
479
+ "default": null
480
+ },
384
481
  "inputs": {
385
482
  "items": {
386
483
  "$ref": "#/$defs/InputSpec"
@@ -739,3 +739,24 @@ def test_a_secret_input_cannot_have_a_default(manifest_data):
739
739
  assert "cannot have a default" in str(e.value)
740
740
  del manifest_data["inputs"][0]["default"]
741
741
  assert validate_manifest(manifest_data).inputs[0].type.value == "secret"
742
+
743
+
744
+ # Display hints (same field as the platform's gravity-schema)
745
+
746
+
747
+ def test_display_is_optional(manifest_data):
748
+ assert validate_manifest(manifest_data).display is None
749
+
750
+
751
+ def test_display_hint_parses(manifest_data):
752
+ manifest_data["display"] = {"view": "chart", "field": "daily", "chart": {"type": "line", "x": "date", "y": ["reach"]}}
753
+ d = validate_manifest(manifest_data).display
754
+ assert (d.view, d.field, d.chart.x, d.chart.y) == ("chart", "daily", "date", ["reach"])
755
+
756
+
757
+ def test_display_never_fails_on_what_the_page_does_not_know(manifest_data):
758
+ # An unknown view is kept for the page to ignore; an unknown key is dropped.
759
+ manifest_data["display"] = {"view": "carousel", "colour": "blue"}
760
+ d = validate_manifest(manifest_data).display
761
+ assert d.view == "carousel"
762
+ assert "colour" not in d.model_dump()
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "gravity-cli"
3
- version = "0.5.4"
3
+ version = "0.5.5"
4
4
  description = "gravity cli — init, run, and push python agents to the Gravity marketplace"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
7
7
  license-files = ["LICENSE", "NOTICE"]
8
8
  requires-python = ">=3.12"
9
9
  dependencies = [
10
- "gravity-schema==0.5.4", # released in lockstep: always the same version as this package
10
+ "gravity-schema==0.5.5", # released in lockstep: always the same version as this package
11
11
  "typer>=0.15.0",
12
12
  "httpx>=0.27.0",
13
13
  "rich>=13.9.0",
@@ -59,7 +59,7 @@ name = "cffi"
59
59
  version = "2.1.1"
60
60
  source = { registry = "https://pypi.org/simple" }
61
61
  dependencies = [
62
- { name = "pycparser", marker = "implementation_name != 'PyPy' and sys_platform != 'win32'" },
62
+ { name = "pycparser", marker = "implementation_name != 'PyPy'" },
63
63
  ]
64
64
  sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" }
65
65
  wheels = [
@@ -123,7 +123,7 @@ name = "cryptography"
123
123
  version = "50.0.0"
124
124
  source = { registry = "https://pypi.org/simple" }
125
125
  dependencies = [
126
- { name = "cffi", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'win32'" },
126
+ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
127
127
  ]
128
128
  sdist = { url = "https://files.pythonhosted.org/packages/de/41/6cbdcf9142d00fe82836fbb51e503e58088575cf7a0fe1dbff6695bf0840/cryptography-50.0.0.tar.gz", hash = "sha256:eeac2acb5a20ed25e0ad6d1df9891a520b78b404266b6d11778f25d5d691a6c9", size = 880201, upload-time = "2026-07-31T14:25:10.11Z" }
129
129
  wheels = [
@@ -164,7 +164,7 @@ wheels = [
164
164
 
165
165
  [[package]]
166
166
  name = "gravity-cli"
167
- version = "0.5.4"
167
+ version = "0.5.5"
168
168
  source = { editable = "." }
169
169
  dependencies = [
170
170
  { name = "gravity-schema" },
@@ -201,7 +201,7 @@ dev = [
201
201
 
202
202
  [[package]]
203
203
  name = "gravity-schema"
204
- version = "0.5.4"
204
+ version = "0.5.5"
205
205
  source = { editable = "packages/gravity-schema" }
206
206
  dependencies = [
207
207
  { name = "pydantic" },
@@ -619,8 +619,8 @@ name = "secretstorage"
619
619
  version = "3.5.0"
620
620
  source = { registry = "https://pypi.org/simple" }
621
621
  dependencies = [
622
- { name = "cryptography", marker = "sys_platform != 'win32'" },
623
- { name = "jeepney", marker = "sys_platform != 'win32'" },
622
+ { name = "cryptography" },
623
+ { name = "jeepney" },
624
624
  ]
625
625
  sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" }
626
626
  wheels = [
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes