mammoth-cli 2.2.13__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.13 → mammoth_cli-2.2.14}/PKG-INFO +2 -2
  2. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/__init__.py +1 -1
  3. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/browse.py +27 -3
  4. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/dataset.py +74 -9
  5. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/registry.py +1 -1
  6. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/schema.py +2 -1
  7. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/view.py +62 -5
  8. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/positionals.py +3 -2
  9. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/read_queries.py +42 -3
  10. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/pyproject.toml +2 -2
  11. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/dataset.yaml +4 -3
  12. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/sdk-methods.yaml +1 -1
  13. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/.gitignore +0 -0
  14. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/LICENSE +0 -0
  15. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/README.md +0 -0
  16. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/__main__.py +0 -0
  17. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/app.py +0 -0
  18. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +0 -0
  19. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/about-mammoth.md +0 -0
  20. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
  21. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +0 -0
  22. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +0 -0
  23. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +0 -0
  24. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
  25. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
  26. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
  27. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
  28. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
  29. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
  30. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +0 -0
  31. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
  32. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
  33. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
  34. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/calc.md +0 -0
  35. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
  36. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
  37. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
  38. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
  39. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
  40. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
  41. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-qa.md +0 -0
  42. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-style.md +0 -0
  43. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-template.md +0 -0
  44. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
  45. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
  46. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
  47. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
  48. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
  49. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
  50. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
  51. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
  52. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/link.md +0 -0
  53. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
  54. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
  55. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
  56. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
  57. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
  58. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
  59. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
  60. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
  61. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
  62. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
  63. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
  64. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
  65. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
  66. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
  67. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
  68. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view-transform.md +0 -0
  69. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +0 -0
  70. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
  71. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
  72. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +0 -0
  73. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
  74. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
  75. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
  76. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
  77. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
  78. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
  79. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
  80. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
  81. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/database-import.md +0 -0
  82. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +0 -0
  83. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +0 -0
  84. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
  85. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +0 -0
  86. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +0 -0
  87. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/scheduling.md +0 -0
  88. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +0 -0
  89. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
  90. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
  91. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +0 -0
  92. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
  93. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
  94. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
  95. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/__init__.py +0 -0
  96. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/activity.py +0 -0
  97. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/addon.py +0 -0
  98. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/agent.py +0 -0
  99. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/ai.py +0 -0
  100. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/annotation.py +0 -0
  101. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/auth.py +0 -0
  102. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/automation.py +0 -0
  103. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/batch.py +0 -0
  104. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/billing.py +0 -0
  105. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/calc.py +0 -0
  106. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/capability.py +0 -0
  107. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/client_app.py +0 -0
  108. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/completion.py +0 -0
  109. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/config.py +0 -0
  110. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/connector.py +0 -0
  111. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/context.py +0 -0
  112. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/dashboard.py +0 -0
  113. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/data_app.py +0 -0
  114. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/doctor.py +0 -0
  115. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/external_key.py +0 -0
  116. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/file.py +0 -0
  117. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/folder.py +0 -0
  118. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/job.py +0 -0
  119. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/link.py +0 -0
  120. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/notification.py +0 -0
  121. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/parameter.py +0 -0
  122. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/project.py +0 -0
  123. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/report.py +0 -0
  124. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/schedule.py +0 -0
  125. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/skill.py +0 -0
  126. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/snippet.py +0 -0
  127. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/support.py +0 -0
  128. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/template.py +0 -0
  129. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/trash.py +0 -0
  130. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/upgrade.py +0 -0
  131. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/user.py +0 -0
  132. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/view_ops.py +0 -0
  133. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/view_profile.py +0 -0
  134. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/webhook.py +0 -0
  135. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/workflow.py +0 -0
  136. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/commands/workspace.py +0 -0
  137. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/context/__init__.py +0 -0
  138. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/context/credentials.py +0 -0
  139. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/context/endpoint.py +0 -0
  140. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/context/profiles.py +0 -0
  141. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/context/resolver.py +0 -0
  142. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/contracts/__init__.py +0 -0
  143. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/contracts/auth.py +0 -0
  144. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/embed.py +0 -0
  145. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/errors/__init__.py +0 -0
  146. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/errors/envelope.py +0 -0
  147. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/manifest/__init__.py +0 -0
  148. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/manifest/loader.py +0 -0
  149. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/messages/__init__.py +0 -0
  150. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/output/__init__.py +0 -0
  151. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/output/envelope.py +0 -0
  152. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/output/normalize.py +0 -0
  153. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/output/policy.py +0 -0
  154. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/output/progress.py +0 -0
  155. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/output/render.py +0 -0
  156. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/py.typed +0 -0
  157. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/__init__.py +0 -0
  158. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/confirm.py +0 -0
  159. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/dataset_health.py +0 -0
  160. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/dryrun.py +0 -0
  161. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/dryrun_targets.py +0 -0
  162. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/embedded.py +0 -0
  163. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/executor.py +0 -0
  164. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/input_loader.py +0 -0
  165. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/intent_only.py +0 -0
  166. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/invocation.py +0 -0
  167. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/new_data.py +0 -0
  168. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/options.py +0 -0
  169. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/parents.py +0 -0
  170. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/runlog.py +0 -0
  171. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/session.py +0 -0
  172. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/state.py +0 -0
  173. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/strict.py +0 -0
  174. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/updates.py +0 -0
  175. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/validate.py +0 -0
  176. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/runtime/verify.py +0 -0
  177. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/__init__.py +0 -0
  178. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/argspec.py +0 -0
  179. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/board_values.py +0 -0
  180. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/coerce.py +0 -0
  181. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/command_contract.py +0 -0
  182. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/conditions.py +0 -0
  183. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/dashboard_filters.py +0 -0
  184. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/dashboard_pages.py +0 -0
  185. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/dashboard_review.py +0 -0
  186. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/data_profile.py +0 -0
  187. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/data_quality.py +0 -0
  188. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/dispatch.py +0 -0
  189. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/factory.py +0 -0
  190. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/input_fields.py +0 -0
  191. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/listing.py +0 -0
  192. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/mapping.py +0 -0
  193. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/openapi_types.py +0 -0
  194. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/protocol.py +0 -0
  195. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/sdk_service.py +0 -0
  196. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/stored_stats.py +0 -0
  197. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/testing.py +0 -0
  198. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/text_dates.py +0 -0
  199. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/type_system.py +0 -0
  200. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/services/write_impact.py +0 -0
  201. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/skills/__init__.py +0 -0
  202. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/skills/installer.py +0 -0
  203. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/skills/steering.py +0 -0
  204. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/mammoth_cli/testing.py +0 -0
  205. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/activity.yaml +0 -0
  206. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/addon.yaml +0 -0
  207. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/agent.yaml +0 -0
  208. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/ai.yaml +0 -0
  209. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/annotation.yaml +0 -0
  210. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/auth.yaml +0 -0
  211. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/automation.yaml +0 -0
  212. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/batch.yaml +0 -0
  213. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/billing.yaml +0 -0
  214. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/browse.yaml +0 -0
  215. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/calc.yaml +0 -0
  216. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/capability.yaml +0 -0
  217. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/client-app.yaml +0 -0
  218. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/completion.yaml +0 -0
  219. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/config.yaml +0 -0
  220. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/connector.yaml +0 -0
  221. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/context.yaml +0 -0
  222. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/dashboard.yaml +0 -0
  223. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/data-app.yaml +0 -0
  224. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/doctor.yaml +0 -0
  225. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/external-key.yaml +0 -0
  226. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/file.yaml +0 -0
  227. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/folder.yaml +0 -0
  228. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/job.yaml +0 -0
  229. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/link.yaml +0 -0
  230. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/log.yaml +0 -0
  231. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/notification.yaml +0 -0
  232. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/parameter.yaml +0 -0
  233. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/project.yaml +0 -0
  234. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/report.yaml +0 -0
  235. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/schedule.yaml +0 -0
  236. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/schema.yaml +0 -0
  237. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/skill.yaml +0 -0
  238. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/snippet.yaml +0 -0
  239. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/support.yaml +0 -0
  240. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/template.yaml +0 -0
  241. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/trash.yaml +0 -0
  242. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/upgrade.yaml +0 -0
  243. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/user.yaml +0 -0
  244. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/version.yaml +0 -0
  245. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/view.yaml +0 -0
  246. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/webhook.yaml +0 -0
  247. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/workflow.yaml +0 -0
  248. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/commands/workspace.yaml +0 -0
  249. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/edits-target.source.yaml +0 -0
  250. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/openapi-operations.yaml +0 -0
  251. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/schema-v1.json +0 -0
  252. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/manifests/sdk-catalog.source.yaml +0 -0
  253. {mammoth_cli-2.2.13 → mammoth_cli-2.2.14}/spec/openapi/metadata.json +0 -0
  254. {mammoth_cli-2.2.13 → 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.13
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.13
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.13"
9
+ __version__ = "2.2.14"
10
10
 
11
11
  # The versioned machine output envelope contract.
12
12
  SCHEMA_VERSION = 1
@@ -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,
@@ -306,7 +306,8 @@ _COMMAND_DISCOVERY_PURPOSES = {
306
306
  "view.data.explore": (
307
307
  "explore trend trends trending over time per day week month quarter year by date "
308
308
  "distribution spread histogram top most common frequent values breakdown share "
309
- "percentage profile period year quarter month date range coverage figure"
309
+ "percentage profile period year quarter month date range coverage figure "
310
+ "cumulative"
310
311
  ),
311
312
  # "Give the West team their own copy they can change" / "duplicate this
312
313
  # dataset as an independent copy" / "clone it without changing the
@@ -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
@@ -1690,6 +1691,7 @@ def view_data_aggregate(invocation: Invocation) -> HandlerResult:
1690
1691
  TEXT-date) column groups by the named part of the date -- ``Monday``..``Sunday``,
1691
1692
  ``January``..``December``, ``Q1``..``Q4``, the year -- in calendar order: the
1692
1693
  read-only way to answer by-weekday and by-month questions.
1694
+ Figures are rounded for display (2 decimals; 4 below 1).
1693
1695
  Never use ``view transform pivot`` just to read a number -- it mutates the
1694
1696
  view's pipeline.
1695
1697
  """
@@ -1745,6 +1747,15 @@ def view_data_aggregate(invocation: Invocation) -> HandlerResult:
1745
1747
  return data, meta
1746
1748
 
1747
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
+
1748
1759
  def _compare_key_and_value_columns(document: dict[str, Any]) -> tuple[list[str], list[str]]:
1749
1760
  """Return the (key, value) display-column names an aggregate call over
1750
1761
  ``document`` will produce, without making the call -- mirrors the label
@@ -1930,7 +1941,9 @@ def _explore_text_dates(
1930
1941
  condition=condition,
1931
1942
  )
1932
1943
  page = (document.get("offset"), document.get("limit"))
1933
- 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
+ )
1934
1947
  return {**response, "data": rows}
1935
1948
 
1936
1949
 
@@ -1953,7 +1966,13 @@ def view_data_explore(invocation: Invocation) -> HandlerResult:
1953
1966
  An optional ``metric`` ``{"column": ..., "function": ...}`` (SUM, COUNT,
1954
1967
  AVG, MIN, MAX, STDDEV or DISTINCT_COUNT) adds a second aggregate per bucket over another column,
1955
1968
  and an optional ``condition`` filters rows first -- same as ``view data
1956
- 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
1957
1976
  ``view transform pivot`` just to explore a column; it mutates the
1958
1977
  pipeline.
1959
1978
  """
@@ -1989,6 +2008,8 @@ def view_data_explore(invocation: Invocation) -> HandlerResult:
1989
2008
  if isinstance(metric, dict):
1990
2009
  resolved_metric = _resolved_aggregate_item(metric, display_to_internal)
1991
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)"
1992
2013
  if bucket_dates:
1993
2014
  data = _explore_text_dates(reads, document, internal_column, resolved_metric)
1994
2015
  else:
@@ -2003,7 +2024,7 @@ def view_data_explore(invocation: Invocation) -> HandlerResult:
2003
2024
  data = read_queries.with_assumptions(reads, data)
2004
2025
  if not bucket_dates:
2005
2026
  data = read_queries.with_variant_hint(reads, data, column_arg)
2006
- return data, meta
2027
+ return read_queries.round_result_rows(data), meta
2007
2028
 
2008
2029
 
2009
2030
  def _explore_on_backend(
@@ -2028,7 +2049,9 @@ def _explore_on_backend(
2028
2049
  kwargs[CONDITION_KWARG] = compile_condition(spec).build(
2029
2050
  reads.display_to_internal or None, reads.column_types or None
2030
2051
  )
2031
- _forward_optional(document, kwargs, ("level", "sequence", "limit", "offset", "sort"))
2052
+ _forward_optional(
2053
+ document, kwargs, ("level", "sequence", "limit", "offset", "sort", "cumulative")
2054
+ )
2032
2055
  return reads.service.call(_symbol(invocation), **kwargs)
2033
2056
 
2034
2057
 
@@ -3474,7 +3497,14 @@ def view_export_specialized(invocation: Invocation) -> HandlerResult:
3474
3497
  int(target_ds_id),
3475
3498
  kwargs.get("column_mapping"),
3476
3499
  )
3477
- 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
+ )
3478
3508
  if is_dataset_route and isinstance(data, int):
3479
3509
  # The SDK returns the bare id of the dataset written to; name it, and
3480
3510
  # say which project it landed in, so the agent's next read is obvious.
@@ -3535,6 +3565,33 @@ def view_export_specialized(invocation: Invocation) -> HandlerResult:
3535
3565
  return data, _meta(invocation, auth.workspace_id, project_id)
3536
3566
 
3537
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
+
3538
3595
  _EXPORTS_LIST_SYMBOL = "mammoth.api.exports.ExportsAPI.list"
3539
3596
  _INTERNAL_DATASET_HANDLER_TYPE = "internal_dataset"
3540
3597
 
@@ -644,8 +644,9 @@ POSITIONAL_OVERRIDES: dict[str, tuple[PositionalSpec, ...]] = {
644
644
  PositionalSpec(
645
645
  name="name_substring",
646
646
  type=str,
647
- required=True,
648
- help="Case-insensitive substring to match against dataset names.",
647
+ required=False,
648
+ help="Case-insensitive substring to match against dataset names; optional "
649
+ "when --input gives 'columns'.",
649
650
  example_value="sales",
650
651
  ),
651
652
  ),
@@ -19,13 +19,18 @@ from dataclasses import dataclass, field
19
19
  from datetime import date
20
20
  from typing import Any
21
21
 
22
- from mammoth.api.dataviews import _add_explore_percentages, _explore_sort_and_limit
22
+ from mammoth.api.dataviews import (
23
+ _add_explore_cumulative,
24
+ _add_explore_percentages,
25
+ _explore_sort_and_limit,
26
+ )
23
27
 
24
28
  from mammoth_cli.errors.envelope import (
25
29
  CODE_INVALID_ARGUMENTS,
26
30
  EXIT_USAGE,
27
31
  CliError,
28
32
  )
33
+ from mammoth_cli.output.normalize import DataRows
29
34
  from mammoth_cli.services import data_profile as dp
30
35
  from mammoth_cli.services import text_dates
31
36
  from mammoth_cli.services.conditions import CONDITION_KWARG, _resolve_operator
@@ -382,10 +387,15 @@ def pivot_with_text_dates(
382
387
 
383
388
 
384
389
  def apply_explore_order(
385
- rows: list[dict[str, Any]], sort: str | None, page: tuple[int | None, int | None]
390
+ rows: list[dict[str, Any]],
391
+ sort: str | None,
392
+ page: tuple[int | None, int | None],
393
+ cumulative: bool = False,
386
394
  ) -> list[dict[str, Any]]:
387
- """Percentages, order and paging for a bucketed explore, like the SDK's own."""
395
+ """Percentages, running total, order and paging for a bucketed explore, like the SDK's own."""
388
396
  _add_explore_percentages(rows)
397
+ if cumulative:
398
+ _add_explore_cumulative(rows)
389
399
  return _explore_sort_and_limit(rows, "DATE", sort, page)
390
400
 
391
401
 
@@ -628,3 +638,32 @@ def with_assumptions(ctx: ReadContext, data: Any) -> Any:
628
638
  if not ctx.assumptions or not isinstance(data, dict):
629
639
  return data
630
640
  return {**data, "text_dates": list(ctx.assumptions.values())}
641
+
642
+
643
+ # ---------------------------------------------------------------------------
644
+ # Display rounding
645
+ # ---------------------------------------------------------------------------
646
+
647
+
648
+ def _round_for_display(value: Any) -> Any:
649
+ """A float rounded to what a person reads: 2 decimals, 4 below 1 so a rate survives."""
650
+ if isinstance(value, bool) or not isinstance(value, float):
651
+ return value
652
+ return round(value, 2 if abs(value) >= 1 else 4)
653
+
654
+
655
+ def round_result_rows(data: Any) -> Any:
656
+ """``data`` with every float in its result rows rounded for display.
657
+
658
+ Sums and averages come back with float noise (``428257.2699000002``) that
659
+ would be quoted to a user as is. Only the answer rows are rounded; a caller
660
+ that joins or diffs figures reads the unrounded handler instead.
661
+ """
662
+ rows = data.get("data") if isinstance(data, dict) else None
663
+ if not isinstance(rows, list):
664
+ return data
665
+ rounded = [
666
+ {k: _round_for_display(v) for k, v in row.items()} if isinstance(row, dict) else row
667
+ for row in rows
668
+ ]
669
+ return {**data, "data": DataRows(rounded) if isinstance(rows, DataRows) else rounded}
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "mammoth-cli"
3
- version = "2.2.13"
3
+ version = "2.2.14"
4
4
  description = "Command-line interface for the Mammoth Analytics platform"
5
5
  authors = [{name = "Mammoth Analytics", email = "support@mammoth.io"}]
6
6
  readme = "README.md"
7
7
  license = "LicenseRef-Proprietary"
8
8
  requires-python = ">=3.12,<3.15"
9
9
  dependencies = [
10
- "mammoth-io (>=0.8.13,<0.9)",
10
+ "mammoth-io (>=0.8.14,<0.9)",
11
11
  "typer (>=0.27,<0.28)",
12
12
  "rich (>=15,<16)",
13
13
  "platformdirs (>=4.10,<5)",
@@ -524,10 +524,11 @@ commands:
524
524
  positionals:
525
525
  - name: name_substring
526
526
  type: str
527
- required: true
527
+ required: false
528
528
  metavar: NAME_SUBSTRING
529
529
  falls_back_to_field: null
530
- help: Case-insensitive substring to match against dataset names.
530
+ help: Case-insensitive substring to match against dataset names; optional when --input
531
+ gives 'columns'.
531
532
  options: []
532
533
  sdk_symbol: mammoth_cli.commands.dataset.find
533
534
  sdk_conversion: Call mammoth_cli.commands.dataset.find with validated request fields.
@@ -543,7 +544,7 @@ commands:
543
544
  contract_fixture: null
544
545
  required_fixture_guard: null
545
546
  secret_fields: []
546
- human_example: mammoth dataset find NAME_SUBSTRING --help
547
+ human_example: mammoth dataset find --help
547
548
  agent_example: mammoth dataset find sales
548
549
  unit_tests:
549
550
  - UT-DATASET-FIND
@@ -3997,7 +3997,7 @@ methods:
3997
3997
  reviewed_by: primary
3998
3998
  - sdk_symbol: mammoth.api.dataviews.DataviewsAPI.explore
3999
3999
  implementation_origin: mammoth.api.dataviews.DataviewsAPI.explore
4000
- signature: 'explore(self, dataset_id: ''int'', dataview_id: ''int'', column: ''str'', column_type: ''str | None'' = None, level: ''str | None'' = None, metric: ''dict[str, Any] | None'' = None, condition: ''dict[str, Any] | None'' = None, sequence: ''int | None'' = None, limit: ''int | None'' = None, offset: ''int | None'' = None, sort: ''str | None'' = None, workspace_id: ''int | None'' = None, project_id: ''int | None'' = None, timeout: ''int | None'' = None, poll_interval: ''int'' = 2) -> ''dict[str, Any]'''
4000
+ signature: 'explore(self, dataset_id: ''int'', dataview_id: ''int'', column: ''str'', column_type: ''str | None'' = None, level: ''str | None'' = None, metric: ''dict[str, Any] | None'' = None, condition: ''dict[str, Any] | None'' = None, sequence: ''int | None'' = None, limit: ''int | None'' = None, offset: ''int | None'' = None, sort: ''str | None'' = None, cumulative: ''bool'' = False, workspace_id: ''int | None'' = None, project_id: ''int | None'' = None, timeout: ''int | None'' = None, poll_interval: ''int'' = 2) -> ''dict[str, Any]'''
4001
4001
  openapi_operation_ids: []
4002
4002
  canonical_command: view.data.explore
4003
4003
  alias_of: null
File without changes
File without changes
File without changes