mammoth-cli 2.2.12__tar.gz → 2.2.14__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 (254) hide show
  1. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/PKG-INFO +2 -2
  2. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/__init__.py +1 -1
  3. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +3 -3
  4. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/browse.py +27 -3
  5. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/dataset.py +74 -9
  6. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/registry.py +1 -1
  7. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/schedule.py +12 -8
  8. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/schema.py +23 -3
  9. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/view.py +112 -17
  10. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/dryrun_targets.py +84 -1
  11. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/command_contract.py +3 -0
  12. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/data_quality.py +7 -9
  13. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/input_fields.py +3 -0
  14. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/listing.py +6 -2
  15. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/positionals.py +3 -2
  16. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/read_queries.py +42 -3
  17. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/pyproject.toml +2 -2
  18. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/dataset.yaml +4 -3
  19. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/schedule.yaml +1 -1
  20. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/view.yaml +3 -3
  21. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/sdk-methods.yaml +1 -1
  22. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/.gitignore +0 -0
  23. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/LICENSE +0 -0
  24. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/README.md +0 -0
  25. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/__main__.py +0 -0
  26. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/app.py +0 -0
  27. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +0 -0
  28. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/about-mammoth.md +0 -0
  29. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
  30. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +0 -0
  31. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +0 -0
  32. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +0 -0
  33. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
  34. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
  35. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
  36. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
  37. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
  38. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
  39. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +0 -0
  40. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
  41. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
  42. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
  43. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/calc.md +0 -0
  44. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
  45. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
  46. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
  47. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
  48. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
  49. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
  50. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-qa.md +0 -0
  51. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-style.md +0 -0
  52. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-template.md +0 -0
  53. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
  54. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
  55. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
  56. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
  57. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
  58. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
  59. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
  60. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
  61. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/link.md +0 -0
  62. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
  63. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
  64. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
  65. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
  66. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
  67. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
  68. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
  69. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
  70. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
  71. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
  72. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
  73. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
  74. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
  75. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
  76. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
  77. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view-transform.md +0 -0
  78. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
  79. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
  80. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +0 -0
  81. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
  82. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
  83. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
  84. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
  85. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
  86. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
  87. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
  88. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
  89. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/database-import.md +0 -0
  90. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +0 -0
  91. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +0 -0
  92. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
  93. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +0 -0
  94. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +0 -0
  95. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/scheduling.md +0 -0
  96. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +0 -0
  97. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
  98. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
  99. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +0 -0
  100. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
  101. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
  102. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
  103. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/__init__.py +0 -0
  104. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/activity.py +0 -0
  105. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/addon.py +0 -0
  106. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/agent.py +0 -0
  107. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/ai.py +0 -0
  108. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/annotation.py +0 -0
  109. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/auth.py +0 -0
  110. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/automation.py +0 -0
  111. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/batch.py +0 -0
  112. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/billing.py +0 -0
  113. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/calc.py +0 -0
  114. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/capability.py +0 -0
  115. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/client_app.py +0 -0
  116. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/completion.py +0 -0
  117. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/config.py +0 -0
  118. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/connector.py +0 -0
  119. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/context.py +0 -0
  120. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/dashboard.py +0 -0
  121. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/data_app.py +0 -0
  122. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/doctor.py +0 -0
  123. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/external_key.py +0 -0
  124. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/file.py +0 -0
  125. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/folder.py +0 -0
  126. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/job.py +0 -0
  127. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/link.py +0 -0
  128. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/notification.py +0 -0
  129. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/parameter.py +0 -0
  130. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/project.py +0 -0
  131. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/report.py +0 -0
  132. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/skill.py +0 -0
  133. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/snippet.py +0 -0
  134. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/support.py +0 -0
  135. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/template.py +0 -0
  136. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/trash.py +0 -0
  137. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/upgrade.py +0 -0
  138. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/user.py +0 -0
  139. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/view_ops.py +0 -0
  140. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/view_profile.py +0 -0
  141. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/webhook.py +0 -0
  142. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/workflow.py +0 -0
  143. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/commands/workspace.py +0 -0
  144. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/context/__init__.py +0 -0
  145. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/context/credentials.py +0 -0
  146. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/context/endpoint.py +0 -0
  147. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/context/profiles.py +0 -0
  148. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/context/resolver.py +0 -0
  149. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/contracts/__init__.py +0 -0
  150. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/contracts/auth.py +0 -0
  151. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/embed.py +0 -0
  152. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/errors/__init__.py +0 -0
  153. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/errors/envelope.py +0 -0
  154. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/manifest/__init__.py +0 -0
  155. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/manifest/loader.py +0 -0
  156. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/messages/__init__.py +0 -0
  157. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/output/__init__.py +0 -0
  158. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/output/envelope.py +0 -0
  159. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/output/normalize.py +0 -0
  160. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/output/policy.py +0 -0
  161. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/output/progress.py +0 -0
  162. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/output/render.py +0 -0
  163. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/py.typed +0 -0
  164. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/__init__.py +0 -0
  165. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/confirm.py +0 -0
  166. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/dataset_health.py +0 -0
  167. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/dryrun.py +0 -0
  168. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/embedded.py +0 -0
  169. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/executor.py +0 -0
  170. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/input_loader.py +0 -0
  171. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/intent_only.py +0 -0
  172. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/invocation.py +0 -0
  173. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/new_data.py +0 -0
  174. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/options.py +0 -0
  175. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/parents.py +0 -0
  176. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/runlog.py +0 -0
  177. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/session.py +0 -0
  178. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/state.py +0 -0
  179. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/strict.py +0 -0
  180. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/updates.py +0 -0
  181. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/validate.py +0 -0
  182. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/runtime/verify.py +0 -0
  183. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/__init__.py +0 -0
  184. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/argspec.py +0 -0
  185. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/board_values.py +0 -0
  186. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/coerce.py +0 -0
  187. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/conditions.py +0 -0
  188. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/dashboard_filters.py +0 -0
  189. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/dashboard_pages.py +0 -0
  190. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/dashboard_review.py +0 -0
  191. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/data_profile.py +0 -0
  192. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/dispatch.py +0 -0
  193. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/factory.py +0 -0
  194. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/mapping.py +0 -0
  195. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/openapi_types.py +0 -0
  196. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/protocol.py +0 -0
  197. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/sdk_service.py +0 -0
  198. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/stored_stats.py +0 -0
  199. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/testing.py +0 -0
  200. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/text_dates.py +0 -0
  201. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/type_system.py +0 -0
  202. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/services/write_impact.py +0 -0
  203. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/skills/__init__.py +0 -0
  204. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/skills/installer.py +0 -0
  205. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/skills/steering.py +0 -0
  206. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/mammoth_cli/testing.py +0 -0
  207. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/activity.yaml +0 -0
  208. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/addon.yaml +0 -0
  209. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/agent.yaml +0 -0
  210. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/ai.yaml +0 -0
  211. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/annotation.yaml +0 -0
  212. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/auth.yaml +0 -0
  213. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/automation.yaml +0 -0
  214. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/batch.yaml +0 -0
  215. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/billing.yaml +0 -0
  216. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/browse.yaml +0 -0
  217. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/calc.yaml +0 -0
  218. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/capability.yaml +0 -0
  219. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/client-app.yaml +0 -0
  220. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/completion.yaml +0 -0
  221. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/config.yaml +0 -0
  222. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/connector.yaml +0 -0
  223. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/context.yaml +0 -0
  224. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/dashboard.yaml +0 -0
  225. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/data-app.yaml +0 -0
  226. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/doctor.yaml +0 -0
  227. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/external-key.yaml +0 -0
  228. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/file.yaml +0 -0
  229. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/folder.yaml +0 -0
  230. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/job.yaml +0 -0
  231. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/link.yaml +0 -0
  232. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/log.yaml +0 -0
  233. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/notification.yaml +0 -0
  234. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/parameter.yaml +0 -0
  235. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/project.yaml +0 -0
  236. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/report.yaml +0 -0
  237. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/schema.yaml +0 -0
  238. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/skill.yaml +0 -0
  239. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/snippet.yaml +0 -0
  240. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/support.yaml +0 -0
  241. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/template.yaml +0 -0
  242. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/trash.yaml +0 -0
  243. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/upgrade.yaml +0 -0
  244. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/user.yaml +0 -0
  245. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/version.yaml +0 -0
  246. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/webhook.yaml +0 -0
  247. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/workflow.yaml +0 -0
  248. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/commands/workspace.yaml +0 -0
  249. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/edits-target.source.yaml +0 -0
  250. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/openapi-operations.yaml +0 -0
  251. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/schema-v1.json +0 -0
  252. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/manifests/sdk-catalog.source.yaml +0 -0
  253. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/openapi/metadata.json +0 -0
  254. {mammoth_cli-2.2.12 → mammoth_cli-2.2.14}/spec/openapi/openapi.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mammoth-cli
3
- Version: 2.2.12
3
+ Version: 2.2.14
4
4
  Summary: Command-line interface for the Mammoth Analytics platform
5
5
  Project-URL: homepage, https://mammoth.io
6
6
  Project-URL: repository, https://github.com/EdgeMetric/mammothsdk
@@ -17,7 +17,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
17
  Requires-Python: <3.15,>=3.12
18
18
  Requires-Dist: jsonschema>=4.20
19
19
  Requires-Dist: keyring<26,>=25.7
20
- Requires-Dist: mammoth-io<0.9,>=0.8.12
20
+ Requires-Dist: mammoth-io<0.9,>=0.8.14
21
21
  Requires-Dist: platformdirs<5,>=4.10
22
22
  Requires-Dist: pydantic<3,>=2.12.5
23
23
  Requires-Dist: pyyaml<7,>=6
@@ -6,7 +6,7 @@ not implement a second HTTP client and does not call private SDK members.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- __version__ = "2.2.12"
9
+ __version__ = "2.2.14"
10
10
 
11
11
  # The versioned machine output envelope contract.
12
12
  SCHEMA_VERSION = 1
@@ -878,11 +878,11 @@ Status on release: ran once on CLI 2.0.14 — write sweep 2026-09-18: exit 0 on
878
878
 
879
879
  Run: `mammoth view update`. Exact input fields: `mammoth schema get view.update`.
880
880
 
881
- Example: `mammoth view update 123 123 --input '{"patch_data": [{"sample_key": "Status"}]}'`. Discovery only: this command is fail-closed and must not dispatch a request.
881
+ Example: `mammoth view update 123 123 --input '{"name": "Revenue report"}'`. Placeholders are illustrative; resolve IDs and input from observed reads.
882
882
 
883
- Execution is unavailable for the current contract and returns `unsupported_contract`. Do not infer request fields or retry it; use only a separately typed alternative.
883
+ Result: `ViewUpdateResult`; mutation `benign_mutation`, confirmation `none`, wait policy `not_async`.
884
884
 
885
- Known restriction: BLOCKED[B09 DATAVIEW_INPUT_UNTYPED]: patch_data is an arbitrary dictionary; reserved, not registered.
885
+ Status on release: untried; no live run recorded.
886
886
 
887
887
  ### `view.version.apply`
888
888
 
@@ -86,6 +86,26 @@ def _forward_optional(
86
86
  kwargs[field] = document[field]
87
87
 
88
88
 
89
+ #: The id a dataset or a view is known by elsewhere in the CLI; a hit's ``id`` is its tree id.
90
+ _OBJECT_ID_KEYS = {"datasource": "dataset_id", "dataview": "view_id"}
91
+
92
+
93
+ def _with_object_ids(data: Any) -> Any:
94
+ """Name the id a command takes: ``dataset_id`` / ``view_id`` beside the tree ``id``."""
95
+ rows = data.get("resources") if isinstance(data, dict) else None
96
+ if not isinstance(rows, list):
97
+ return data
98
+ named = [
99
+ (
100
+ {**row, key: row.get("object_id")}
101
+ if isinstance(row, dict) and (key := _OBJECT_ID_KEYS.get(str(row.get("resource_type"))))
102
+ else row
103
+ )
104
+ for row in rows
105
+ ]
106
+ return {**data, "resources": named}
107
+
108
+
89
109
  def browse_folder(invocation: Invocation) -> HandlerResult:
90
110
  """Browse resources inside one folder of the active project.
91
111
 
@@ -173,7 +193,7 @@ def browse_resources(invocation: Invocation) -> HandlerResult:
173
193
  )
174
194
  with open_service(invocation) as (service, auth):
175
195
  data = service.call(_symbol(invocation), **kwargs)
176
- return data, _meta(invocation, auth.workspace_id, project_id)
196
+ return _with_object_ids(data), _meta(invocation, auth.workspace_id, project_id)
177
197
 
178
198
 
179
199
  def browse_resource(invocation: Invocation) -> HandlerResult:
@@ -208,7 +228,11 @@ def browse_ancestors(invocation: Invocation) -> HandlerResult:
208
228
 
209
229
 
210
230
  def browse_search(invocation: Invocation) -> HandlerResult:
211
- """Search resources across every project of the workspace (resources v2)."""
231
+ """Search resources across every project of the workspace (resources v2).
232
+
233
+ ``resource_type`` ``dataset`` means the route's ``datasource``. Each dataset hit
234
+ carries ``dataset_id`` and each view hit ``view_id``: pass those, never the tree ``id``.
235
+ """
212
236
  document = invocation.load_input() or {}
213
237
  kwargs: dict[str, Any] = {}
214
238
  _forward_optional(
@@ -216,7 +240,7 @@ def browse_search(invocation: Invocation) -> HandlerResult:
216
240
  )
217
241
  with open_service(invocation) as (service, auth):
218
242
  data = service.call(_symbol(invocation), **kwargs)
219
- return data, _meta(invocation, auth.workspace_id, None)
243
+ return _with_object_ids(data), _meta(invocation, auth.workspace_id, None)
220
244
 
221
245
 
222
246
  def browse_resources_bulk(invocation: Invocation) -> HandlerResult:
@@ -33,6 +33,7 @@ from mammoth_cli.runtime.session import open_service, require_project
33
33
  from mammoth_cli.services.listing import (
34
34
  DATASET_ROW_FIELDS,
35
35
  ambiguity_note,
36
+ compact_columns,
36
37
  dataset_summary,
37
38
  fit_budget,
38
39
  name_hit,
@@ -202,7 +203,11 @@ _SEARCH_PAGE_SIZE = 100
202
203
 
203
204
 
204
205
  def search_hits(
205
- service: Any, resource_type: str, needle: str, project_id: int | None = None
206
+ service: Any,
207
+ resource_type: str,
208
+ needle: str,
209
+ project_id: int | None = None,
210
+ fields: str = "minimal",
206
211
  ) -> tuple[list[dict[str, Any]], bool]:
207
212
  """Resources of ``resource_type`` whose name contains ``needle``, from the search route.
208
213
 
@@ -222,11 +227,11 @@ def search_hits(
222
227
  for _ in range(_SEARCH_PAGES):
223
228
  page = service.call(
224
229
  symbol,
225
- search=needle,
230
+ search=needle or None,
226
231
  resource_type=resource_type,
227
232
  limit=_SEARCH_PAGE_SIZE,
228
233
  cursor=cursor,
229
- fields="minimal",
234
+ fields=fields,
230
235
  **scope,
231
236
  )
232
237
  rows += [r for r in page.get("resources", []) if isinstance(r, dict)]
@@ -274,6 +279,61 @@ def named_project(service: Any, project_id: int, visible: list[dict[str, Any]])
274
279
  return {"id": project_id, "name": record.get("name")}
275
280
 
276
281
 
282
+ def _requested_columns(document: dict[str, Any]) -> list[str]:
283
+ """The ``columns`` input as a list of names (a comma-separated string is split)."""
284
+ raw = document.get("columns")
285
+ if raw is None:
286
+ return []
287
+ names = raw.split(",") if isinstance(raw, str) else raw
288
+ if not isinstance(names, list) or not all(isinstance(n, str) for n in names):
289
+ raise CliError(
290
+ code=CODE_INVALID_ARGUMENT,
291
+ message="'columns' must be a list of column names (or one comma-separated string).",
292
+ exit_status=EXIT_USAGE,
293
+ )
294
+ return [n.strip() for n in names if n.strip()]
295
+
296
+
297
+ def _column_names(hit: dict[str, Any]) -> list[str]:
298
+ """Display names of the columns a full-field search hit carries."""
299
+ properties = hit.get("object_properties")
300
+ metadata = properties.get("metadata") if isinstance(properties, dict) else None
301
+ return [
302
+ str(c["display_name"])
303
+ for c in metadata or []
304
+ if isinstance(c, dict) and c.get("display_name")
305
+ ]
306
+
307
+
308
+ def _find_by_columns(
309
+ service: Any,
310
+ needle: str,
311
+ columns: list[str],
312
+ visible: list[dict[str, Any]],
313
+ ) -> tuple[list[dict[str, Any]], bool]:
314
+ """Datasets (named like ``needle``, when given) that have every one of ``columns``."""
315
+ hits, cut = search_hits(service, "datasource", needle, fields="full")
316
+ names = {p.get("id"): p.get("name") for p in visible}
317
+ wanted = [c.lower() for c in columns]
318
+ matches: list[dict[str, Any]] = []
319
+ for hit in hits:
320
+ have = _column_names(hit)
321
+ if not set(wanted) <= {c.lower() for c in have}:
322
+ continue
323
+ matches.append(
324
+ {
325
+ "project_id": hit.get("project_id"),
326
+ "project_name": names.get(hit.get("project_id")),
327
+ "id": hit.get("object_id"),
328
+ "name": hit.get("name"),
329
+ "rows": hit.get("row_count"),
330
+ "cols": len(have),
331
+ "columns": compact_columns([(c, None) for c in have], limit=None),
332
+ }
333
+ )
334
+ return matches, cut
335
+
336
+
277
337
  def dataset_find(invocation: Invocation) -> HandlerResult:
278
338
  """Search dataset names for a substring across every visible project.
279
339
 
@@ -326,9 +386,11 @@ def dataset_find(invocation: Invocation) -> HandlerResult:
326
386
  def dataset_list(invocation: Invocation) -> HandlerResult:
327
387
  """List datasets in the active project, newest first, each with what tells them apart.
328
388
 
329
- Every item carries its size, created/updated time, how its data arrived, and
330
- its column names and types (from the list route's stored ``stats``,
331
- ``sources`` and ``data_schema``), cut to fit the agent tool output cap.
389
+ Every item carries its created/updated time and how its data arrived (from the
390
+ list route's ``sources``), cut to fit the agent tool output cap. The list asks
391
+ only the cheap fields, so it holds no row counts or column names: ``view list
392
+ DATASET_ID`` shows a dataset's columns, and ``dataset find --input '{"columns":
393
+ [...]}'`` finds the dataset that has given columns.
332
394
  ``full: true`` returns the raw ``{id, name}`` list instead. ``name`` keeps only datasets
333
395
  whose name contains it (case-insensitive) across every page, as short rows without
334
396
  column lists; ``limit``/``offset`` then page over the matches.
@@ -347,7 +409,9 @@ def dataset_list(invocation: Invocation) -> HandlerResult:
347
409
  with open_service(invocation) as (service, auth):
348
410
  data = service.call(_symbol(invocation), **kwargs)
349
411
  if compact:
350
- data = _compact_dataset_list(data, kwargs.get("offset", 0), kwargs.get("sort"))
412
+ data = _compact_dataset_list(
413
+ data, kwargs.get("offset", 0), kwargs.get("sort"), kwargs.get("limit", 100)
414
+ )
351
415
  return data, _meta(invocation, auth.workspace_id, project_id)
352
416
 
353
417
 
@@ -388,7 +452,7 @@ def _dataset_name_search(
388
452
  return page, _meta(invocation, auth.workspace_id, project_id)
389
453
 
390
454
 
391
- def _compact_dataset_list(data: Any, offset: int, sort: str | None) -> Any:
455
+ def _compact_dataset_list(data: Any, offset: int, sort: str | None, limit: int) -> Any:
392
456
  """Summarise a dataset-list page and fit it to the tool output cap."""
393
457
  datasets = data.get("datasets") if isinstance(data, dict) else None
394
458
  if not isinstance(datasets, list):
@@ -404,7 +468,8 @@ def _compact_dataset_list(data: Any, offset: int, sort: str | None) -> Any:
404
468
  "stored sample_values per view (all_columns: true lists every column)."
405
469
  ),
406
470
  }
407
- if omitted or data.get("next"):
471
+ # The list route sends no ``next``: a page of ``limit`` rows may have a successor.
472
+ if omitted or data.get("next") or len(datasets) >= limit:
408
473
  result["more"] = True
409
474
  result["next_offset"] = int(offset) + len(kept)
410
475
  return result
@@ -718,7 +718,7 @@ HANDLERS: dict[str, Handler] = {
718
718
  "view.update": view_cmd.view_update,
719
719
  "view.data.get": view_cmd.view_data_get,
720
720
  "view.data.query": view_cmd.view_data_query,
721
- "view.data.aggregate": view_cmd.view_data_aggregate,
721
+ "view.data.aggregate": view_cmd.view_data_aggregate_rounded,
722
722
  "view.data.compare": view_cmd.view_data_compare,
723
723
  "view.data.explore": view_cmd.view_data_explore,
724
724
  "view.data.profile": view_profile_cmd.view_data_profile,
@@ -22,6 +22,7 @@ from mammoth_cli.errors.envelope import (
22
22
  CODE_SDK_SYMBOL_UNRESOLVED,
23
23
  EXIT_USAGE,
24
24
  CliError,
25
+ not_available_error,
25
26
  )
26
27
  from mammoth_cli.manifest.loader import command_by_id
27
28
  from mammoth_cli.runtime.confirm import (
@@ -154,14 +155,17 @@ def _meta(invocation: Invocation, workspace_id: int, project_id: int) -> dict[st
154
155
 
155
156
 
156
157
  def schedule_list(invocation: Invocation) -> HandlerResult:
157
- """List schedules in the active project. ``limit``/``offset`` are optional."""
158
- project_id = require_project(invocation)
159
- document = _bound_document(invocation)
160
- kwargs: dict[str, Any] = {"project_id": project_id}
161
- _forward_optional(document, kwargs, ("limit", "offset"))
162
- with open_service(invocation) as (service, auth):
163
- data = service.call(_symbol(invocation), **kwargs)
164
- return data, _meta(invocation, auth.workspace_id, project_id)
158
+ """Retired: the server does not implement listing a project's schedules.
159
+
160
+ ``GET /workspaces/{id}/projects/{id}/schedules`` always answers ``5GENR011
161
+ NOT_IMPLEMENTED`` (the server raises it on purpose). The command stays so a
162
+ caller gets a clear answer instead of a bare backend error.
163
+ """
164
+ raise not_available_error(
165
+ "schedule list",
166
+ web_path="the web app, which opens a schedule from the dataset or automation that owns it",
167
+ instead="`schedule get SCHEDULE_ID` reads one schedule by an id you already have.",
168
+ )
165
169
 
166
170
 
167
171
  def schedule_get(invocation: Invocation) -> HandlerResult:
@@ -74,6 +74,7 @@ _GROUP_DISCOVERY_PURPOSES = {
74
74
  }
75
75
 
76
76
  _COMMAND_DISCOVERY_PURPOSES = {
77
+ "view.update": "rename change name to a new name title relabel",
77
78
  "file.upload": (
78
79
  "upload import CSV spreadsheet XLSX source data append add rows union stack "
79
80
  "a file into an existing dataset excel workbook tabs sheets drop in"
@@ -305,7 +306,8 @@ _COMMAND_DISCOVERY_PURPOSES = {
305
306
  "view.data.explore": (
306
307
  "explore trend trends trending over time per day week month quarter year by date "
307
308
  "distribution spread histogram top most common frequent values breakdown share "
308
- "percentage profile"
309
+ "percentage profile period year quarter month date range coverage figure "
310
+ "cumulative"
309
311
  ),
310
312
  # "Give the West team their own copy they can change" / "duplicate this
311
313
  # dataset as an independent copy" / "clone it without changing the
@@ -323,7 +325,10 @@ _COMMAND_DISCOVERY_PURPOSES = {
323
325
  # value -- and neither can be dropped as a data word anyway, since
324
326
  # view.data.explore's own purpose text already uses both for its trend
325
327
  # feature.
326
- "view.data.aggregate": "group and sum totals by month week without changing the pipeline",
328
+ "view.data.aggregate": (
329
+ "group and sum totals by month week without changing the pipeline "
330
+ "sum total figure answer a question, read only"
331
+ ),
327
332
  # Goals stated as "what is in this data" / "why do customers churn": one
328
333
  # whole-view profile answers both, so the phrasing must reach it.
329
334
  "view.data.profile": (
@@ -1740,6 +1745,21 @@ def _inline_call_detail(entries: list[dict[str, Any]]) -> None:
1740
1745
  entry["agent_example"] = record["agent_example"]
1741
1746
 
1742
1747
 
1748
+ def _inline_picks(page: list[dict[str, Any]], offset: int) -> list[dict[str, Any]]:
1749
+ """The entries to inline: the top ones, plus read commands ranked below a write.
1750
+
1751
+ A read that answers the question is worth its fields even when a write such as
1752
+ ``view.transform.pivot`` outranks it; otherwise the caller needs a ``schema get``.
1753
+ """
1754
+ head = page[: max(0, _INLINE_DETAIL_COUNT - offset)]
1755
+ reads = [
1756
+ entry
1757
+ for entry in page[len(head) :]
1758
+ if (command_by_id(entry["command_id"]) or {}).get("mutation_class") == "read"
1759
+ ]
1760
+ return head + reads[:_INLINE_DETAIL_COUNT]
1761
+
1762
+
1743
1763
  #: How to drill down from a find: a family's full command list, or every family.
1744
1764
  _BROWSE_NEXT = (
1745
1765
  "mammoth schema list FAMILY lists every command in a family; mammoth schema list "
@@ -1902,7 +1922,7 @@ def find_schemas(
1902
1922
  )
1903
1923
  total_matches = len(ranked_matches)
1904
1924
  page = [match for _, match in ranked_matches[offset : offset + bounded_limit]]
1905
- _inline_call_detail(page[: max(0, _INLINE_DETAIL_COUNT - offset)])
1925
+ _inline_call_detail(_inline_picks(page, offset))
1906
1926
  has_more = offset + len(page) < total_matches
1907
1927
  continuation = (
1908
1928
  {
@@ -22,6 +22,7 @@ from __future__ import annotations
22
22
 
23
23
  import dataclasses
24
24
  import inspect
25
+ import shlex
25
26
  from datetime import UTC, datetime
26
27
  from decimal import Decimal, InvalidOperation
27
28
  from typing import Any
@@ -899,19 +900,45 @@ def view_impact(invocation: Invocation) -> HandlerResult:
899
900
 
900
901
 
901
902
  def view_update(invocation: Invocation) -> HandlerResult:
902
- """Reject free-form dataview patches until the API supplies typed variants."""
903
- raise CliError(
903
+ """Rename a view from the name input field; any other patch is refused.
904
+
905
+ The dataview patch route leaves op, path and value unconstrained, so the only
906
+ typed change offered is the rename (``replace`` on ``name``).
907
+ """
908
+ project_id = require_project(invocation)
909
+ dataview_id = _require_int_positional_at(invocation, 0, "view id")
910
+ document = invocation.load_input() or {}
911
+ name = document.get("name")
912
+ # ``dataview_id`` is the VIEW_ID positional, bound into the document by the contract.
913
+ allowed = {"name", _DATASET_ID_FIELD, "dataview_id"}
914
+ if set(document) - allowed or not isinstance(name, str) or not name.strip():
915
+ raise _untyped_patch_error(invocation)
916
+ with open_service(invocation) as (service, auth):
917
+ dataset_id = _resolve_dataset_id(service, invocation, dataview_id, document)
918
+ data = service.call(
919
+ _symbol(invocation),
920
+ dataset_id=dataset_id,
921
+ dataview_id=dataview_id,
922
+ patch_data=[{"op": "replace", "path": "name", "value": name.strip()}],
923
+ project_id=project_id,
924
+ )
925
+ return data, _meta(invocation, auth.workspace_id, project_id)
926
+
927
+
928
+ def _untyped_patch_error(invocation: Invocation) -> CliError:
929
+ """The refusal for a view patch that is not the typed rename."""
930
+ return CliError(
904
931
  code=CODE_UNSUPPORTED_CONTRACT,
905
932
  message="Raw dataview patch operations are not available through the CLI.",
906
933
  exit_status=EXIT_USAGE,
907
934
  hint=(
908
- "The OpenAPI operation leaves op, path, and value unconstrained. "
909
- "Use a separately typed view command when its schema covers the intended change."
935
+ "The OpenAPI operation leaves op, path, and value unconstrained. The typed "
936
+ 'change is the rename: view update VIEW_ID --input \'{"name": "New name"}\'.'
910
937
  ),
911
938
  details={
912
939
  "command_id": invocation.command_id,
913
940
  "blocker": "B09 DATAVIEW_INPUT_UNTYPED",
914
- "typed_alternatives": [],
941
+ "typed_alternatives": ['view update VIEW_ID --input \'{"name": "New name"}\''],
915
942
  },
916
943
  recovery_commands=[
917
944
  "mammoth schema find view",
@@ -1288,17 +1315,19 @@ def _relabel_and_check(
1288
1315
  ) -> Any:
1289
1316
  """Relabel a data page to display names and add ``column_warnings`` and ``duplicates``.
1290
1317
 
1318
+ Only read-only data reads call this, so a dates-as-text finding carries no convert fix.
1319
+
1291
1320
  The metadata read happens only when the page has rows and the caller has
1292
1321
  not read it already (one read serves both the names and the types).
1293
1322
  """
1294
1323
  rows = data.get(_ROWS_KEY) if isinstance(data, dict) else None
1295
1324
  if not isinstance(rows, list) or not rows:
1296
1325
  data = _relabel_columns(service, dataset_id, view_id, project_id, data, mapping)
1297
- return _with_column_warnings(data, types or {}, view_id, dataset_id)
1326
+ return _with_column_warnings(data, types or {}, view_id, dataset_id, read_only=True)
1298
1327
  if mapping is None or types is None:
1299
1328
  mapping, types = _column_profile(service, dataset_id, view_id, project_id)
1300
1329
  data = _relabel_columns(service, dataset_id, view_id, project_id, data, mapping)
1301
- data = _with_column_warnings(data, types, view_id, dataset_id)
1330
+ data = _with_column_warnings(data, types, view_id, dataset_id, read_only=True)
1302
1331
  return _with_duplicates_fact(data, view_id, dataset_id, whole_view)
1303
1332
 
1304
1333
 
@@ -1322,7 +1351,11 @@ COLUMN_CHECK_ISSUES = (
1322
1351
 
1323
1352
 
1324
1353
  def _with_column_warnings(
1325
- data: Any, types: dict[str, str], view_id: int, dataset_id: int | None = None
1354
+ data: Any,
1355
+ types: dict[str, str],
1356
+ view_id: int,
1357
+ dataset_id: int | None = None,
1358
+ read_only: bool = False,
1326
1359
  ) -> Any:
1327
1360
  """Add ``column_checks`` (always) and ``column_warnings`` (when found).
1328
1361
 
@@ -1332,13 +1365,19 @@ def _with_column_warnings(
1332
1365
  """
1333
1366
  if not isinstance(data, dict) or not isinstance(data.get(_ROWS_KEY, []), list):
1334
1367
  return data
1335
- checks, warnings = _check_columns(data.get(_ROWS_KEY) or [], types, view_id, dataset_id)
1368
+ checks, warnings = _check_columns(
1369
+ data.get(_ROWS_KEY) or [], types, view_id, dataset_id, read_only
1370
+ )
1336
1371
  out = {**data, "column_checks": checks}
1337
1372
  return {**out, "column_warnings": warnings} if warnings else out
1338
1373
 
1339
1374
 
1340
1375
  def _check_columns(
1341
- rows: list[Any], types: dict[str, str], view_id: int, dataset_id: int | None
1376
+ rows: list[Any],
1377
+ types: dict[str, str],
1378
+ view_id: int,
1379
+ dataset_id: int | None,
1380
+ read_only: bool = False,
1342
1381
  ) -> tuple[dict[str, Any], list[dict[str, Any]]]:
1343
1382
  """Run ``column_warnings`` and describe what was checked (never raises)."""
1344
1383
  checks: dict[str, Any] = {
@@ -1350,7 +1389,7 @@ def _check_columns(
1350
1389
  warnings: list[dict[str, Any]] = []
1351
1390
  if rows and types:
1352
1391
  try:
1353
- warnings = column_warnings(rows, types, view_id, dataset_id)
1392
+ warnings = column_warnings(rows, types, view_id, dataset_id, read_only)
1354
1393
  except Exception as exc: # noqa: BLE001 -- a presentation aid must not fail the read
1355
1394
  checks["checked"] = []
1356
1395
  checks["error"] = f"{type(exc).__name__}: {exc}"
@@ -1652,6 +1691,7 @@ def view_data_aggregate(invocation: Invocation) -> HandlerResult:
1652
1691
  TEXT-date) column groups by the named part of the date -- ``Monday``..``Sunday``,
1653
1692
  ``January``..``December``, ``Q1``..``Q4``, the year -- in calendar order: the
1654
1693
  read-only way to answer by-weekday and by-month questions.
1694
+ Figures are rounded for display (2 decimals; 4 below 1).
1655
1695
  Never use ``view transform pivot`` just to read a number -- it mutates the
1656
1696
  view's pipeline.
1657
1697
  """
@@ -1707,6 +1747,15 @@ def view_data_aggregate(invocation: Invocation) -> HandlerResult:
1707
1747
  return data, meta
1708
1748
 
1709
1749
 
1750
+ def view_data_aggregate_rounded(invocation: Invocation) -> HandlerResult:
1751
+ """``view data aggregate`` as the user reads it: floats rounded (2 decimals; 4 below 1).
1752
+
1753
+ ``view data compare`` calls :func:`view_data_aggregate` itself, at full precision.
1754
+ """
1755
+ data, meta = view_data_aggregate(invocation)
1756
+ return read_queries.round_result_rows(data), meta
1757
+
1758
+
1710
1759
  def _compare_key_and_value_columns(document: dict[str, Any]) -> tuple[list[str], list[str]]:
1711
1760
  """Return the (key, value) display-column names an aggregate call over
1712
1761
  ``document`` will produce, without making the call -- mirrors the label
@@ -1728,7 +1777,7 @@ def _run_aggregate_for_compare(
1728
1777
  ) -> tuple[list[dict[str, Any]], dict[str, Any]]:
1729
1778
  """Run ``view data aggregate``'s own handler against one view, for compare."""
1730
1779
  sub_invocation = dataclasses.replace(
1731
- invocation, command_id="view.data.aggregate", extra_args=[str(view_id)]
1780
+ invocation, command_id="view.data.aggregate", extra_args=[str(view_id)], positionals={}
1732
1781
  )
1733
1782
  data, meta = view_data_aggregate(sub_invocation)
1734
1783
  rows = data.get(_ROWS_KEY, [])
@@ -1892,7 +1941,9 @@ def _explore_text_dates(
1892
1941
  condition=condition,
1893
1942
  )
1894
1943
  page = (document.get("offset"), document.get("limit"))
1895
- rows = read_queries.apply_explore_order(response["data"], document.get("sort"), page)
1944
+ rows = read_queries.apply_explore_order(
1945
+ response["data"], document.get("sort"), page, bool(document.get("cumulative"))
1946
+ )
1896
1947
  return {**response, "data": rows}
1897
1948
 
1898
1949
 
@@ -1915,7 +1966,13 @@ def view_data_explore(invocation: Invocation) -> HandlerResult:
1915
1966
  An optional ``metric`` ``{"column": ..., "function": ...}`` (SUM, COUNT,
1916
1967
  AVG, MIN, MAX, STDDEV or DISTINCT_COUNT) adds a second aggregate per bucket over another column,
1917
1968
  and an optional ``condition`` filters rows first -- same as ``view data
1918
- aggregate``, which this command wraps for the raw PIVOT shape. Never use
1969
+ aggregate``, which this command wraps for the raw PIVOT shape. A date range
1970
+ is one ``and`` condition (``>=`` a start, ``<=`` an end); one year is
1971
+ ``{"column": ..., "operator": "=", "value": 2017, "component": "year"}``.
1972
+ ``cumulative: true`` adds a running total of the metric (of ``count`` without
1973
+ one) over the buckets in date order, whatever ``sort`` or ``limit`` shows:
1974
+ the answer to "cumulative / running total through X". Figures are rounded for
1975
+ display (2 decimals; 4 below 1). Never use
1919
1976
  ``view transform pivot`` just to explore a column; it mutates the
1920
1977
  pipeline.
1921
1978
  """
@@ -1951,6 +2008,8 @@ def view_data_explore(invocation: Invocation) -> HandlerResult:
1951
2008
  if isinstance(metric, dict):
1952
2009
  resolved_metric = _resolved_aggregate_item(metric, display_to_internal)
1953
2010
  as_map["agg_1"] = resolved_metric["as_name"]
2011
+ if document.get("cumulative"):
2012
+ as_map["cumulative"] = f"{as_map.get('agg_1', 'count')} (running total)"
1954
2013
  if bucket_dates:
1955
2014
  data = _explore_text_dates(reads, document, internal_column, resolved_metric)
1956
2015
  else:
@@ -1965,7 +2024,7 @@ def view_data_explore(invocation: Invocation) -> HandlerResult:
1965
2024
  data = read_queries.with_assumptions(reads, data)
1966
2025
  if not bucket_dates:
1967
2026
  data = read_queries.with_variant_hint(reads, data, column_arg)
1968
- return data, meta
2027
+ return read_queries.round_result_rows(data), meta
1969
2028
 
1970
2029
 
1971
2030
  def _explore_on_backend(
@@ -1990,7 +2049,9 @@ def _explore_on_backend(
1990
2049
  kwargs[CONDITION_KWARG] = compile_condition(spec).build(
1991
2050
  reads.display_to_internal or None, reads.column_types or None
1992
2051
  )
1993
- _forward_optional(document, kwargs, ("level", "sequence", "limit", "offset", "sort"))
2052
+ _forward_optional(
2053
+ document, kwargs, ("level", "sequence", "limit", "offset", "sort", "cumulative")
2054
+ )
1994
2055
  return reads.service.call(_symbol(invocation), **kwargs)
1995
2056
 
1996
2057
 
@@ -3436,7 +3497,14 @@ def view_export_specialized(invocation: Invocation) -> HandlerResult:
3436
3497
  int(target_ds_id),
3437
3498
  kwargs.get("column_mapping"),
3438
3499
  )
3439
- data = service.call_view(dataview_id, method, dataset_id=dataset_id, **kwargs)
3500
+ try:
3501
+ data = service.call_view(dataview_id, method, dataset_id=dataset_id, **kwargs)
3502
+ except CliError as error:
3503
+ if not (is_dataset_route and error.details.get("export_pending")):
3504
+ raise
3505
+ return _pending_dataset_export(error, dataview_id, result_project_id), _meta(
3506
+ invocation, auth.workspace_id, project_id
3507
+ )
3440
3508
  if is_dataset_route and isinstance(data, int):
3441
3509
  # The SDK returns the bare id of the dataset written to; name it, and
3442
3510
  # say which project it landed in, so the agent's next read is obvious.
@@ -3497,6 +3565,33 @@ def view_export_specialized(invocation: Invocation) -> HandlerResult:
3497
3565
  return data, _meta(invocation, auth.workspace_id, project_id)
3498
3566
 
3499
3567
 
3568
+ def _pending_dataset_export(error: CliError, view_id: int, project_id: int) -> dict[str, Any]:
3569
+ """A dataset export that was accepted but whose dataset id is not known yet.
3570
+
3571
+ The export was submitted and the server is writing it (or has written it); only
3572
+ the lookup of its id ran out of time. That is not a failure, so say what is known
3573
+ and how to read the dataset when it lands, never an error.
3574
+ """
3575
+ name = error.details.get("dataset_name")
3576
+ pending: dict[str, Any] = {
3577
+ "status": "pending",
3578
+ "source_view_id": view_id,
3579
+ "project_id": project_id,
3580
+ "refreshes_on_pipeline_run": True,
3581
+ "note": (
3582
+ "The export was submitted and is still being written, so its dataset id is not "
3583
+ "known yet. Do not export again: that would create a second dataset. Look it up "
3584
+ f"in a moment with the next command (its source reads 'export of view {view_id}')."
3585
+ ),
3586
+ }
3587
+ if name is not None:
3588
+ pending["dataset_name"] = name
3589
+ pending["next"] = f"mammoth dataset find {shlex.quote(str(name))} --project {project_id}"
3590
+ if error.details.get("dataset_id") is not None:
3591
+ pending["dataset_id"] = error.details["dataset_id"]
3592
+ return pending
3593
+
3594
+
3500
3595
  _EXPORTS_LIST_SYMBOL = "mammoth.api.exports.ExportsAPI.list"
3501
3596
  _INTERNAL_DATASET_HANDLER_TYPE = "internal_dataset"
3502
3597