mammoth-cli 2.0.16__tar.gz → 2.0.17__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 (210) hide show
  1. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/PKG-INFO +2 -2
  2. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/__init__.py +1 -1
  3. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +20 -3
  4. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +5 -7
  5. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +3 -3
  6. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +6 -2
  7. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +44 -0
  8. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/file.py +53 -13
  9. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/runtime/strict.py +33 -2
  10. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/input_fields.py +23 -1
  11. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/sdk_service.py +44 -20
  12. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/pyproject.toml +2 -2
  13. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/view.yaml +7 -5
  14. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/.gitignore +0 -0
  15. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/LICENSE +0 -0
  16. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/README.md +0 -0
  17. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/__main__.py +0 -0
  18. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/app.py +0 -0
  19. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
  20. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +0 -0
  21. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
  22. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
  23. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
  24. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
  25. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
  26. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
  27. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +0 -0
  28. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
  29. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
  30. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
  31. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
  32. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
  33. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
  34. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
  35. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
  36. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
  37. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
  38. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
  39. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
  40. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
  41. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
  42. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
  43. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
  44. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
  45. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
  46. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
  47. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
  48. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
  49. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
  50. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
  51. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
  52. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
  53. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
  54. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
  55. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
  56. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
  57. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
  58. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
  59. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
  60. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
  61. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +0 -0
  62. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
  63. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
  64. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
  65. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
  66. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
  67. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
  68. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
  69. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
  70. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +0 -0
  71. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
  72. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +0 -0
  73. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
  74. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
  75. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
  76. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
  77. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
  78. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/__init__.py +0 -0
  79. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/activity.py +0 -0
  80. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/addon.py +0 -0
  81. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/agent.py +0 -0
  82. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/ai.py +0 -0
  83. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/annotation.py +0 -0
  84. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/auth.py +0 -0
  85. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/automation.py +0 -0
  86. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/batch.py +0 -0
  87. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/billing.py +0 -0
  88. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/browse.py +0 -0
  89. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/capability.py +0 -0
  90. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/client_app.py +0 -0
  91. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/completion.py +0 -0
  92. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/config.py +0 -0
  93. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/connector.py +0 -0
  94. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/context.py +0 -0
  95. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/dashboard.py +0 -0
  96. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/data_app.py +0 -0
  97. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/dataset.py +0 -0
  98. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/doctor.py +0 -0
  99. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/external_key.py +0 -0
  100. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/folder.py +0 -0
  101. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/job.py +0 -0
  102. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/notification.py +0 -0
  103. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/parameter.py +0 -0
  104. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/project.py +0 -0
  105. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/registry.py +0 -0
  106. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/report.py +0 -0
  107. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/schedule.py +0 -0
  108. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/schema.py +0 -0
  109. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/skill.py +0 -0
  110. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/snippet.py +0 -0
  111. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/support.py +0 -0
  112. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/template.py +0 -0
  113. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/trash.py +0 -0
  114. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/upgrade.py +0 -0
  115. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/user.py +0 -0
  116. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/view.py +0 -0
  117. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/view_ops.py +0 -0
  118. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/webhook.py +0 -0
  119. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/workflow.py +0 -0
  120. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/commands/workspace.py +0 -0
  121. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/context/__init__.py +0 -0
  122. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/context/credentials.py +0 -0
  123. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/context/endpoint.py +0 -0
  124. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/context/profiles.py +0 -0
  125. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/context/resolver.py +0 -0
  126. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/contracts/__init__.py +0 -0
  127. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/contracts/auth.py +0 -0
  128. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/errors/__init__.py +0 -0
  129. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/errors/envelope.py +0 -0
  130. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/manifest/__init__.py +0 -0
  131. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/manifest/loader.py +0 -0
  132. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/messages/__init__.py +0 -0
  133. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/output/__init__.py +0 -0
  134. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/output/envelope.py +0 -0
  135. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/output/normalize.py +0 -0
  136. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/output/policy.py +0 -0
  137. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/output/progress.py +0 -0
  138. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/output/render.py +0 -0
  139. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/py.typed +0 -0
  140. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/runtime/__init__.py +0 -0
  141. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/runtime/confirm.py +0 -0
  142. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/runtime/executor.py +0 -0
  143. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/runtime/input_loader.py +0 -0
  144. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/runtime/invocation.py +0 -0
  145. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/runtime/options.py +0 -0
  146. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/runtime/session.py +0 -0
  147. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/runtime/validate.py +0 -0
  148. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/__init__.py +0 -0
  149. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/argspec.py +0 -0
  150. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/coerce.py +0 -0
  151. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/command_contract.py +0 -0
  152. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/conditions.py +0 -0
  153. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/dispatch.py +0 -0
  154. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/factory.py +0 -0
  155. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/mapping.py +0 -0
  156. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/openapi_types.py +0 -0
  157. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/positionals.py +0 -0
  158. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/protocol.py +0 -0
  159. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/testing.py +0 -0
  160. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/services/type_system.py +0 -0
  161. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/skills/__init__.py +0 -0
  162. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/skills/installer.py +0 -0
  163. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/mammoth_cli/testing.py +0 -0
  164. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/activity.yaml +0 -0
  165. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/addon.yaml +0 -0
  166. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/agent.yaml +0 -0
  167. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/ai.yaml +0 -0
  168. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/annotation.yaml +0 -0
  169. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/auth.yaml +0 -0
  170. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/automation.yaml +0 -0
  171. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/batch.yaml +0 -0
  172. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/billing.yaml +0 -0
  173. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/browse.yaml +0 -0
  174. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/capability.yaml +0 -0
  175. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/client-app.yaml +0 -0
  176. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/completion.yaml +0 -0
  177. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/config.yaml +0 -0
  178. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/connector.yaml +0 -0
  179. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/context.yaml +0 -0
  180. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/dashboard.yaml +0 -0
  181. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/data-app.yaml +0 -0
  182. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/dataset.yaml +0 -0
  183. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/doctor.yaml +0 -0
  184. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/external-key.yaml +0 -0
  185. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/file.yaml +0 -0
  186. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/folder.yaml +0 -0
  187. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/job.yaml +0 -0
  188. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/notification.yaml +0 -0
  189. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/parameter.yaml +0 -0
  190. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/project.yaml +0 -0
  191. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/report.yaml +0 -0
  192. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/schedule.yaml +0 -0
  193. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/schema.yaml +0 -0
  194. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/skill.yaml +0 -0
  195. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/snippet.yaml +0 -0
  196. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/support.yaml +0 -0
  197. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/template.yaml +0 -0
  198. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/trash.yaml +0 -0
  199. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/upgrade.yaml +0 -0
  200. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/user.yaml +0 -0
  201. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/version.yaml +0 -0
  202. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/webhook.yaml +0 -0
  203. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/workflow.yaml +0 -0
  204. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/commands/workspace.yaml +0 -0
  205. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/openapi-operations.yaml +0 -0
  206. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/schema-v1.json +0 -0
  207. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/sdk-catalog.source.yaml +0 -0
  208. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/manifests/sdk-methods.yaml +0 -0
  209. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/openapi/metadata.json +0 -0
  210. {mammoth_cli-2.0.16 → mammoth_cli-2.0.17}/spec/openapi/openapi.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mammoth-cli
3
- Version: 2.0.16
3
+ Version: 2.0.17
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.8,>=0.7.8
20
+ Requires-Dist: mammoth-io<0.8,>=0.7.9
21
21
  Requires-Dist: platformdirs<5,>=4.10
22
22
  Requires-Dist: pydantic<3,>=2.13
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.0.16"
9
+ __version__ = "2.0.17"
10
10
 
11
11
  # The versioned machine output envelope contract.
12
12
  SCHEMA_VERSION = 1
@@ -38,11 +38,18 @@ the result.
38
38
 
39
39
  ## Working rules
40
40
 
41
+ - Every command takes its resource ids as positionals, its request fields as
42
+ one `--input` JSON document, plus the shared global options (`--project`,
43
+ `--profile`, `--output`, `--no-input`, `--yes`, `--confirm`, timeouts).
44
+ There are no per-field flags: `project create NAME`, not `project create
45
+ --name NAME`. `schema get COMMAND_ID` lists the positionals and input fields.
41
46
  - Resolve workspace/project/dataset/view parents from reads; pass observed IDs
42
47
  and `--project`. A dataset does not select a default view. Every `view`
43
48
  command that changes, exports, or deletes data requires the exact parent
44
- `DATASET_ID` (trailing positional or `dataset_id` input field); only reads
45
- may omit it and discover the parent. Get it from `mammoth view get VIEW_ID`.
49
+ `DATASET_ID`: `view transform *` and `view draft *` take it as the
50
+ `dataset_id` input field, every other `view` command as the trailing
51
+ positional after `VIEW_ID`; only reads may omit it and discover the parent.
52
+ Get it from `mammoth view get VIEW_ID`.
46
53
  - Uploads and dataset creation return a **dataset** id. Transforms, joins,
47
54
  exports, and previews need a **view** id: run `view list DATASET_ID
48
55
  --project PROJECT_ID` to get it. See
@@ -51,6 +58,13 @@ the result.
51
58
  never backend aliases.
52
59
  - Inspect the result after a mutation. A timeout, exit 7, or interruption does
53
60
  not prove it failed. Reconcile an `outcome_unknown` before replaying it.
61
+ - A success envelope is not proof the mutation did what you meant. After a
62
+ row-scoped change (set-values, filter, replace, join, fill) read rows back
63
+ with `view data get VIEW_ID DATASET_ID` and check both rows the condition
64
+ should have touched and rows it should not have. A uniform result (every
65
+ amount 0, every region "Unknown", most join rows unmatched) is a signal
66
+ that the previous step went wrong, not a fact about the source data: stop
67
+ and re-inspect that step before building anything on it.
54
68
  - Keep secrets out of argv, task notes, checkpoints, logs, and responses.
55
69
  - Preserve requested deliverables. Cleanup is exact-ID authorized and never means delete-all-owned-resources.
56
70
 
@@ -64,7 +78,10 @@ the result.
64
78
  or [recovery](references/recovery.md)
65
79
  - **Import, resources, transforms, pipelines, dashboards, exports, or cleanup:**
66
80
  [recipes](references/recipes/index.md) and [operations](references/operations.md)
67
- - **A known command family or exact command:** [command catalog](references/command-index.md)
81
+ - **A known command family or exact command:** [command catalog](references/command-index.md),
82
+ then check the same command in [capabilities](references/capabilities.md)
83
+ before composing input from its example (the catalog lists retired and
84
+ blocked routes with the same wording as working ones)
68
85
  - **Whether a route is proven, known-blocked, or untried on release:**
69
86
  [capabilities](references/capabilities.md) — read it before promising a
70
87
  deliverable or reporting a failure as a backend fault
@@ -1,7 +1,7 @@
1
1
  # What is proven on release
2
2
 
3
3
  Generated from `docs/release-capability-matrix.json`; do not edit by hand.
4
- 455 API operations have a CLI command. 225 were exercised successfully on release, 2 are not supported there, and the rest are untried. Untried is not broken: discover the contract with `mammoth schema get COMMAND_ID --output json --no-input`, run it, and treat the structured error envelope as the answer.
4
+ 455 API operations have a CLI command. 227 were exercised successfully on release, 2 are not supported there, and the rest are untried. Untried is not broken: discover the contract with `mammoth schema get COMMAND_ID --output json --no-input`, run it, and treat the structured error envelope as the answer.
5
5
 
6
6
  Status meanings:
7
7
 
@@ -18,7 +18,7 @@ The typed `view transform *` commands all submit through `view.task.add`; its ro
18
18
  | Family | Commands | Verified | Not supported | Untried |
19
19
  |---|---|---|---|---|
20
20
  | `dashboard` | 104 | 81 | 2 | 21 |
21
- | `view` | 62 | 50 | 0 | 12 |
21
+ | `view` | 62 | 52 | 0 | 10 |
22
22
  | `support` | 45 | 9 | 0 | 36 |
23
23
  | `billing` | 23 | 4 | 0 | 19 |
24
24
  | `connector` | 22 | 2 | 0 | 20 |
@@ -237,21 +237,19 @@ Verified: `user.get`, `user.preference.get`, `user.preference.update`
237
237
 
238
238
  ## `view`
239
239
 
240
- Verified: `view.active-user.list`, `view.active-user.mark`, `view.ai.generate-data`, `view.ai.profile`, `view.bulk-delete`, `view.checkpoint.create`, `view.checkpoint.delete`, `view.checkpoint.list`, `view.conditional-format.list`, `view.conditional-format.update`, `view.create`, `view.data-check.create`, `view.data-check.delete`, `view.data-check.get`, `view.data-check.list`, `view.data.get`, `view.data.query`, `view.delete`, `view.derivative.create`, `view.derivative.delete`, `view.derivative.list`, `view.derivative.update`, `view.draft.command`, `view.export.delete`, `view.export.get`, `view.export.list`, `view.export.publish-db`, `view.export.update`, `view.exportable-config.get`, `view.get`, `view.list`, `view.parameter-context`, `view.pipeline.edit`, `view.pipeline.get`, `view.pipeline.items`, `view.pipeline.rerun`, `view.preview`, `view.restore`, `view.task.add`, `view.task.delete`, `view.task.get`, `view.task.list`, `view.task.update`, `view.trash`, `view.version.apply`, `view.version.delete`, `view.version.get`, `view.version.list`, `view.version.update`
240
+ Verified: `view.active-user.list`, `view.active-user.mark`, `view.ai.generate-data`, `view.ai.profile`, `view.bulk-delete`, `view.checkpoint.create`, `view.checkpoint.delete`, `view.checkpoint.list`, `view.conditional-format.create`, `view.conditional-format.delete-all`, `view.conditional-format.list`, `view.conditional-format.update`, `view.create`, `view.data-check.create`, `view.data-check.delete`, `view.data-check.get`, `view.data-check.list`, `view.data.get`, `view.data.query`, `view.delete`, `view.derivative.create`, `view.derivative.delete`, `view.derivative.list`, `view.derivative.update`, `view.draft.command`, `view.export.delete`, `view.export.get`, `view.export.list`, `view.export.publish-db`, `view.export.update`, `view.exportable-config.get`, `view.get`, `view.list`, `view.parameter-context`, `view.pipeline.edit`, `view.pipeline.get`, `view.pipeline.items`, `view.pipeline.rerun`, `view.preview`, `view.restore`, `view.task.add`, `view.task.delete`, `view.task.get`, `view.task.list`, `view.task.update`, `view.trash`, `view.version.apply`, `view.version.delete`, `view.version.get`, `view.version.list`, `view.version.update`
241
241
 
242
242
  | Command | State | Note |
243
243
  |---|---|---|
244
244
  | `view.ai.generation-info` | observed blocker | backend: GET /workspaces/4/projects/24/datasets/54/dataviews/76/data/generate -> HTTP 400 5GENR011 NOT_IMPLEMENTED 'Not implemented', request_id:null |
245
245
  | `view.checkpoint.get` | observed blocker | backend: GET /workspaces/4/projects/24/datasets/54/dataviews/76/pipeline/checkpoints/2 -> HTTP 500, empty response_body:{}, request_id:null, backend code: none surfaced (generic ap |
246
246
  | `view.checkpoint.update` | observed blocker | backend_error: CLI-side fix (payload now carries value:null as required) held: the correctly-shaped request was dispatched and the backend returned HTTP 500 (not a CLI-side crash): |
247
- | `view.conditional-format.create` | observed blocker | cli_error: Skill doc (view.md) claims this route is 'fail-closed and must not dispatch a request' (BLOCKED B09 DATAVIEW_INPUT_UNTYPED) -- but live it DOES dispatch: HTTP 400 4GENR0 |
248
247
  | `view.data-check.update` | observed blocker | backend: PATCH .../pipeline/data-checks/3 -> HTTP 500, empty response_body, request_id:null, code:outcome_unknown |
249
248
  | `view.derivative.data` | observed blocker | backend: POST .../derivatives/4/data -> HTTP 500, empty response_body, request_id:null, code:outcome_unknown |
250
249
  | `view.export.create` | observed blocker | backend: CLI accepts the request (exit 0, job 358 accepted on POST /dataviews/76/actions), but job get 358 -> status:error, response:{"error":{"message":"'destination'"}} (a raw Py |
251
250
  | `view.exportable-config.apply` | observed blocker | cli_error: Schema's own runnable_example (config:{tasks:[]}) fails: job_failed, response:{reason:(quote)dependencies(quote)} -- a raw Python KeyError, not a structured validation m |
252
- | `view.conditional-format.delete-all` | CLI defect fixed, untried since | 2.0.16 (the handler now forwards rule_id from --input (2.0.15 accepted the field but dropped it before the SDK call)) |
251
+ | `view.task.preview` | observed blocker | backend_error: Fix held: the COPY task_spec is accepted and a task_preview job (406) is created; the job then fails backend-side with 'Object of type datetime is not JSON serializa |
253
252
  | `view.export.publish-db-update` | CLI defect fixed, untried since | 2.0.16 (example value is the documented {"odbc_type": "postgres"} object (a bare string is rejected)) |
254
- | `view.task.preview` | CLI defect fixed, untried since | 2.0.16 (example now uses the backend COPY param-template shape: list of {SOURCE, AS{COLUMN,TYPE,INTERNAL_NAME}}, VERSION 2 |
255
253
 
256
254
  ## `webhook`
257
255
 
@@ -267,4 +265,4 @@ Verified: `workflow.graph`, `workflow.list`, `workflow.workspace-datasets`, `wor
267
265
 
268
266
  Verified: `workspace.app-usage`, `workspace.get`, `workspace.list`, `workspace.segment.list`, `workspace.segment.update`, `workspace.storage-breakdown`, `workspace.user.list`
269
267
 
270
- Evidence version: CLI mammoth-cli 1.1.11; mammoth-io 0.7.1. Details: `docs/capability-evidence/` in the repository.
268
+ Evidence collected on CLI releases 1.1.5 through 2.0.17; each row's release is recorded in `docs/release-capability-matrix.json` (`evidence_version`). A row verified on an older release has not been re-run since unless its note says so. Details: `docs/capability-evidence/` in the repository.
@@ -92,7 +92,7 @@ Expected success: `ViewCheckpointUpdateResult` in the standard JSON envelope; mu
92
92
 
93
93
  Run: `mammoth view conditional-format create`. Exact input fields: `mammoth schema get view.conditional-format.create --output json --no-input`.
94
94
 
95
- Example: `mammoth view conditional-format create 123 123 --input '{"rule": {"sample_key": "Status"}}' --output json --no-input`. Runnable only after resolving schema-required IDs and input from observed reads.
95
+ Example: `mammoth view conditional-format create 123 123 --input '{"rule": {"cf_type": "RULE", "payload": {"FORMAT": {"name": "Flag open orders", "color": "red", "applies_to": "row", "column_ids": "[]"}, "CONDITION": {"OR": [{"column_1": {"CONTAINS": {"VALUE": ["Open"]}}}]}}}}' --output json --no-input`. Runnable only after resolving schema-required IDs and input from observed reads.
96
96
 
97
97
  Expected success: `ViewConditionalFormatCreateResult` in the standard JSON envelope; mutation `benign_mutation`, confirmation `none`, wait policy `not_async`. On nonzero exit, inspect the JSON error envelope and its `recovery_commands`; do not guess request fields. See [representative envelopes](../machine-output.md) for concrete success/error shapes.
98
98
 
@@ -100,7 +100,7 @@ Expected success: `ViewConditionalFormatCreateResult` in the standard JSON envel
100
100
 
101
101
  Run: `mammoth view conditional-format delete-all`. Exact input fields: `mammoth schema get view.conditional-format.delete-all --output json --no-input`.
102
102
 
103
- Example: `mammoth view conditional-format delete-all 123 123 --input '{"rule_id": "rule-1"}' --output json --no-input`. Illustrative only: append `--yes` after observing an owned target.
103
+ Example: `mammoth view conditional-format delete-all 123 123 --input '{"rule_id": "bca0ff33bd6f8ed1"}' --output json --no-input`. Illustrative only: append `--yes` after observing an owned target.
104
104
 
105
105
  Expected success: `ViewConditionalFormatDeleteAllResult` in the standard JSON envelope; mutation `destructive`, confirmation `prompt_or_yes`, wait policy `not_async`. On nonzero exit, inspect the JSON error envelope and its `recovery_commands`; do not guess request fields. See [representative envelopes](../machine-output.md) for concrete success/error shapes.
106
106
 
@@ -668,7 +668,7 @@ Expected success: `ViewTransformAddColumnResult` in the standard JSON envelope;
668
668
 
669
669
  Run: `mammoth view transform add-sql`. Exact input fields: `mammoth schema get view.transform.add-sql --output json --no-input`.
670
670
 
671
- Example: `mammoth view transform add-sql 123 --input '{"query": "SELECT region, SUM(revenue) FROM data GROUP BY region", "dataset_id": 456}' --output json --no-input`. Runnable only after resolving schema-required IDs and input from observed reads.
671
+ Example: `mammoth view transform add-sql 123 --input '{"query": "SELECT region, SUM(revenue) AS revenue FROM \"view:123\" GROUP BY region", "dataset_id": 456}' --output json --no-input`. Runnable only after resolving schema-required IDs and input from observed reads.
672
672
 
673
673
  Expected success: `ViewTransformAddSqlResult` in the standard JSON envelope; mutation `reversible_pipeline`, confirmation `none`, wait policy `always_wait`. On nonzero exit, inspect the JSON error envelope and its `recovery_commands`; do not guess request fields. See [representative envelopes](../machine-output.md) for concrete success/error shapes.
674
674
 
@@ -6,9 +6,11 @@ id instead. Run `view list DATASET_ID --project PROJECT_ID` to get it. Do not
6
6
  dig through `dataset get` and its `dependencies` field for a view id; `view
7
7
  list` is the supported route.
8
8
 
9
- Discover exact contracts, then upload and read back explicit parents:
9
+ Discover exact contracts, then upload and read back explicit parents. A new
10
+ project takes its name as the positional argument:
10
11
 
11
12
  ```bash
13
+ mammoth project create 'PROJECT NAME' --output json --no-input
12
14
  mammoth schema get file.upload --output json --no-input
13
15
  mammoth file upload ./SOURCE.csv --project PROJECT_ID --output json --no-input
14
16
  mammoth dataset list --project PROJECT_ID --output json --no-input
@@ -17,7 +19,9 @@ mammoth view get VIEW_ID --project PROJECT_ID --output json --no-input
17
19
  ```
18
20
 
19
21
  `file upload` takes the local path as its positional argument; there is no
20
- `--source`/`--file` option. `dataset delete` is asynchronous: re-read
22
+ `--source`/`--file` option. Its result carries the status the platform holds
23
+ for each created dataset: `ready`, or `need_action` with a `next_command`, in
24
+ which case follow [need-action](need-action.md) before looking for a view. `dataset delete` is asynchronous: re-read
21
25
  `dataset list` (the id disappears once the job completes) before reporting.
22
26
 
23
27
  Use display names from the exact view schema. For settings, folders and other
@@ -30,8 +30,14 @@ lists them. Pick the operation by what it does, not by its name:
30
30
  mammoth view transform set-values VIEW_ID --project PROJECT_ID \
31
31
  --input '{"dataset_id":DATASET_ID,"existing_column":"revenue","values":[{"value":0}],"condition":{"column":"revenue","operator":"IS_EMPTY"}}' \
32
32
  --output json --no-input
33
+ mammoth view data get VIEW_ID DATASET_ID --project PROJECT_ID --output json --no-input
33
34
  ```
34
35
 
36
+ Then confirm from the read-back that blank rows are now `0` and non-blank
37
+ rows kept their values. If non-matching rows changed too, the condition was
38
+ not applied: stop, do not build joins or summaries on this view, and report
39
+ it.
40
+
35
41
  - `filter` keeps matching rows by default (`filter_type: "SHOW"`); to drop
36
42
  rows, say so: `{"condition":{"column":"units","operator":"LT","value":0},"filter_type":"REMOVE"}`. For each operation, a successful result should contain a returned
37
43
  task/job reference or updated view envelope; then verify with `view task list`,
@@ -64,6 +70,44 @@ mammoth schema get view.transform.join --output json --no-input
64
70
  mammoth view transform join VIEW_ID --project PROJECT_ID --input INPUT_JSON --output json --no-input
65
71
  ```
66
72
 
73
+ ## Aggregate or summarise
74
+
75
+ For a grouped summary (totals per region, counts per status) use the typed
76
+ `pivot` when the live schema lists it, or a SQL task. A SQL task must be one
77
+ SELECT that names the view as the quoted table `"view:VIEW_ID"` (or its quoted
78
+ display name) with display-name columns; unquoted or placeholder table names
79
+ (`data`, `__TABLE__`) are rejected with "table name ... not found" or "only
80
+ select queries allowed". The result replaces the view's columns, so run it on
81
+ a copy (`view create` with `clone_from`) or as the last step:
82
+
83
+ ```bash
84
+ mammoth schema get view.transform.pivot --output json --no-input
85
+ mammoth view transform add-sql VIEW_ID --project PROJECT_ID \
86
+ --input '{"dataset_id":DATASET_ID,"query":"SELECT region, SUM(amount) AS total_amount, COUNT(*) AS order_count FROM \"view:VIEW_ID\" GROUP BY region"}' \
87
+ --output json --no-input
88
+ mammoth view data get VIEW_ID DATASET_ID --project PROJECT_ID --output json --no-input
89
+ ```
90
+
91
+ Read the data back after every value-changing step (`view data get`, or
92
+ `view preview`); a task that executed is not proof it changed the rows you
93
+ meant, and a join that matched nothing shows nulls, not a filled default. A
94
+ join that leaves most rows unmatched is not evidence about the source data
95
+ until you have sampled the key column on both sides (`view data get` on
96
+ each view) and confirmed an earlier step did not rewrite the key or the
97
+ values you are summing.
98
+
99
+ ## How to look at your data
100
+
101
+ - Schema and types: `view get VIEW_ID` (falls back to discovery) or
102
+ `dataset get DATASET_ID`; the column list with display names is what every
103
+ transform input must use.
104
+ - Rows and values: `view data get VIEW_ID DATASET_ID` (paged) or
105
+ `view preview VIEW_ID` for a sample; use these after every value-changing
106
+ step and before reporting any number.
107
+ - What actually ran: `view task list VIEW_ID`, `view task get VIEW_ID TASK_ID`,
108
+ `view pipeline get VIEW_ID` (state, auto_run, executing task).
109
+ - Async completion: `job get JOB_ID` / `job wait JOB_ID`.
110
+
67
111
  Reject malformed fields with the structured error envelope and stop rather than
68
112
  guessing names. Verify exact display names, join multiplicity, math values and
69
113
  remote task/pipeline readback. Draft submit is not proof all tasks persisted:
@@ -11,6 +11,7 @@ SDK method named by the command's reviewed manifest ``sdk_symbol``.
11
11
 
12
12
  from __future__ import annotations
13
13
 
14
+ from collections.abc import Callable
14
15
  from typing import Any
15
16
 
16
17
  from mammoth_cli.errors.envelope import (
@@ -214,25 +215,64 @@ def file_upload(invocation: Invocation) -> HandlerResult:
214
215
  )
215
216
  with open_service(invocation) as (service, auth):
216
217
  data = service.call(_symbol(invocation), **kwargs)
217
- # The SDK waits for the upload to finish and returns the created dataset
218
- # id(s) as a bare int/list. Wrap it in a labeled result so the output reads
219
- # as a finished dataset rather than an anonymous number. When the caller
220
- # opts out of waiting (``wait_for_completion: false``) the bare job id is
221
- # returned unchanged.
222
- if not document.get("wait_for_completion", True):
223
- return data, _meta(invocation, auth.workspace_id, resolved_project(invocation))
224
- return _upload_result(data), _meta(invocation, auth.workspace_id, resolved_project(invocation))
225
-
226
-
227
- def _upload_result(value: Any) -> dict[str, Any]:
228
- """Shape the SDK upload return (int | list[int] | None) into a labeled result."""
218
+ # The SDK waits for the upload job and returns the created dataset
219
+ # id(s) as a bare int/list. When the caller opts out of waiting
220
+ # (``wait_for_completion: false``) the bare job id is returned unchanged.
221
+ if not document.get("wait_for_completion", True):
222
+ return data, _meta(invocation, auth.workspace_id, resolved_project(invocation))
223
+ # A finished upload job does not mean a usable dataset: a CSV with an
224
+ # ambiguous date column lands in ``need_action`` with no view. Report
225
+ # the status the platform holds for each dataset, not an assumed one.
226
+ result = _upload_result(data, lambda dataset_id: _dataset_status(service, dataset_id))
227
+ return result, _meta(invocation, auth.workspace_id, resolved_project(invocation))
228
+
229
+
230
+ _DATASET_GET_SYMBOL = "mammoth.api.datasets.DatasetsAPI.get"
231
+
232
+
233
+ def _dataset_status(service: Any, dataset_id: int) -> tuple[str, dict[str, Any] | None]:
234
+ """Read ``(status, status_info)`` for one dataset; ``unknown`` if the read fails."""
235
+ try:
236
+ response = service.call(_DATASET_GET_SYMBOL, dataset_id=dataset_id)
237
+ except CliError:
238
+ return "unknown", None
239
+ dataset = response.get("dataset", response) if isinstance(response, dict) else {}
240
+ status = dataset.get("status") if isinstance(dataset, dict) else None
241
+ status_info = dataset.get("status_info") if isinstance(dataset, dict) else None
242
+ return (
243
+ status if isinstance(status, str) else "unknown",
244
+ status_info if isinstance(status_info, dict) else None,
245
+ )
246
+
247
+
248
+ def _upload_result(
249
+ value: Any, read_status: Callable[[int], tuple[str, dict[str, Any] | None]]
250
+ ) -> dict[str, Any]:
251
+ """Shape the SDK upload return (int | list[int] | None) into a labeled result.
252
+
253
+ ``status`` is ``ready`` only when every created dataset reads back as
254
+ ``ready``; otherwise it is the first non-ready status so a caller that
255
+ checks one field sees the dataset that still needs work. ``datasets``
256
+ carries the per-dataset status, and a ``need_action`` dataset also gets
257
+ the recovery route so the caller does not have to know the recipe.
258
+ """
229
259
  if isinstance(value, list):
230
260
  ids = [int(v) for v in value]
231
261
  elif isinstance(value, int):
232
262
  ids = [value]
233
263
  else:
234
264
  ids = []
235
- result: dict[str, Any] = {"status": "ready", "dataset_ids": ids}
265
+ datasets: list[dict[str, Any]] = []
266
+ for dataset_id in ids:
267
+ status, status_info = read_status(dataset_id)
268
+ entry: dict[str, Any] = {"id": dataset_id, "status": status}
269
+ if status_info:
270
+ entry["status_info"] = status_info
271
+ if status == "need_action":
272
+ entry["next_command"] = f"mammoth dataset file-settings get {dataset_id}"
273
+ datasets.append(entry)
274
+ overall = next((d["status"] for d in datasets if d["status"] != "ready"), "ready")
275
+ result: dict[str, Any] = {"status": overall, "dataset_ids": ids, "datasets": datasets}
236
276
  if len(ids) == 1:
237
277
  result["dataset_id"] = ids[0]
238
278
  return result
@@ -60,6 +60,36 @@ CODE_INVALID_INPUT_FIELD_TYPE = "invalid_input_field_type"
60
60
  _TRUE_STRINGS = frozenset({"true", "1", "yes", "y", "on"})
61
61
  _FALSE_STRINGS = frozenset({"false", "0", "no", "n", "off"})
62
62
 
63
+ def _unknown_option_hint(command_id: str, token: str) -> tuple[str, dict[str, Any]]:
64
+ """Name the accepted form when an unknown ``--option`` matches a real field.
65
+
66
+ Generic leaves take no per-field options, so ``--name`` on ``project
67
+ create`` is a guess at the positional ``name`` and ``--dataset-id`` on a
68
+ view command is a guess at the ``dataset_id`` input field. Saying which
69
+ lets a caller fix the call without a schema round-trip.
70
+ """
71
+ guessed = token.lstrip(_OPTION_PREFIX).split("=", 1)[0].replace("-", "_")
72
+ command = command_id.replace(".", " ")
73
+ if guessed:
74
+ for position, spec in enumerate(resolve_positionals(command_id)):
75
+ if spec.name == guessed:
76
+ return (
77
+ f"'{guessed}' is positional argument {position + 1} of '{command}', "
78
+ f"not an option: mammoth {command} {guessed.upper()}.",
79
+ {"positional": guessed},
80
+ )
81
+ contract = resolve_command_contract(command_id)
82
+ if contract is not None and any(
83
+ field.name == guessed for field in contract.accepted_fields
84
+ ):
85
+ return (
86
+ f"'{guessed}' is an --input field of '{command}', not an option: "
87
+ f"pass --input '{{\"{guessed}\": VALUE}}' after the positional arguments.",
88
+ {"input_field": guessed},
89
+ )
90
+ return "Check the command schema with 'mammoth schema get'.", {}
91
+
92
+
63
93
  def validate_extra_args(command_id: str, extra_args: Iterable[str]) -> None:
64
94
  """Reject unrecognized options and surplus positional tokens.
65
95
 
@@ -79,12 +109,13 @@ def validate_extra_args(command_id: str, extra_args: Iterable[str]) -> None:
79
109
  tokens = list(extra_args)
80
110
  for token in tokens:
81
111
  if token.startswith(_OPTION_PREFIX) and token != _OPTION_PREFIX:
112
+ hint, hint_details = _unknown_option_hint(command_id, token)
82
113
  raise CliError(
83
114
  code=CODE_UNKNOWN_OPTION,
84
115
  message=f"Unknown option '{token}' for '{command_id.replace('.', ' ')}'.",
85
116
  exit_status=EXIT_USAGE,
86
- hint="Check the command schema with 'mammoth schema get'.",
87
- details={"option": token},
117
+ hint=hint,
118
+ details={"option": token, **hint_details},
88
119
  )
89
120
 
90
121
  max_positionals = len(resolve_positionals(command_id))
@@ -173,7 +173,24 @@ _EXAMPLE_INPUT_HINTS: dict[str, dict[str, Any]] = {
173
173
  },
174
174
  "view.ai.profile": {"dataset_id": 456, "action": "insights"},
175
175
  "connector.query.generate": {"query": "Total sales for January"},
176
- "view.conditional-format.delete-all": {"rule_id": "rule-1"},
176
+ # HighlightEntry: cf_type + payload{FORMAT, CONDITION keyed by internal
177
+ # column name}; the create response and ``conditional-format list`` carry
178
+ # the generated rule_id that delete-all needs.
179
+ "view.conditional-format.create": {
180
+ "rule": {
181
+ "cf_type": "RULE",
182
+ "payload": {
183
+ "FORMAT": {
184
+ "name": "Flag open orders",
185
+ "color": "red",
186
+ "applies_to": "row",
187
+ "column_ids": "[]",
188
+ },
189
+ "CONDITION": {"OR": [{"column_1": {"CONTAINS": {"VALUE": ["Open"]}}}]},
190
+ },
191
+ }
192
+ },
193
+ "view.conditional-format.delete-all": {"rule_id": "bca0ff33bd6f8ed1"},
177
194
  "dataset.bulk-delete": {"dataset_ids": [456, 457]},
178
195
  "folder.move": {"resource_ids": [8024], "target_folder_resource_id": "root"},
179
196
  "project.update": {"name": "Renamed project"},
@@ -217,6 +234,11 @@ _EXAMPLE_INPUT_HINTS: dict[str, dict[str, Any]] = {
217
234
  }
218
235
  ]
219
236
  },
237
+ # The SQL task reads the view as the quoted table "view:<id>" (or its
238
+ # quoted display name); placeholder names such as ``data`` are rejected.
239
+ "view.transform.add-sql": {
240
+ "query": 'SELECT region, SUM(revenue) AS revenue FROM "view:123" GROUP BY region'
241
+ },
220
242
  "view.checkpoint.update": {
221
243
  "body": {"patches": [{"op": "command", "path": "approve", "value": None}]},
222
244
  },
@@ -129,6 +129,19 @@ class SdkMammothService:
129
129
  hint="Check the command schema with 'mammoth schema get'.",
130
130
  details={"reason": str(exc)},
131
131
  ) from exc
132
+ except ValueError as exc:
133
+ # ``ViewsResource.get`` and the view-scoped API methods reach the
134
+ # same project-wide parent discovery as ``call_view``; a miss must
135
+ # read as not_found here too, not "operation failed unexpectedly".
136
+ miss = self._discovery_miss_error(exc, kwargs.get("view_id", kwargs.get("dataview_id")))
137
+ if miss is not None:
138
+ raise miss from exc
139
+ raise map_sdk_exception(
140
+ exc,
141
+ profile=self._profile,
142
+ project_id=self._project_id,
143
+ workspace_id=self._workspace_id,
144
+ ) from exc
132
145
  except Exception as exc:
133
146
  raise map_sdk_exception(
134
147
  exc,
@@ -137,6 +150,34 @@ class SdkMammothService:
137
150
  workspace_id=self._workspace_id,
138
151
  ) from exc
139
152
 
153
+ def _discovery_miss_error(self, exc: ValueError, view_id: Any) -> CliError | None:
154
+ """Map the SDK's bare "not found in any dataset" ValueError to not_found.
155
+
156
+ Returns None when ``exc`` is some other ValueError so the caller can
157
+ apply the generic mapping.
158
+ """
159
+ if "not found in any dataset" not in str(exc):
160
+ return None
161
+ project = self._client.project_id
162
+ return CliError(
163
+ code=CODE_RESOURCE_NOT_FOUND,
164
+ message=(
165
+ f"View {view_id} was not found in any dataset of project {project}; "
166
+ "parent discovery walked every visible dataset and folder."
167
+ ),
168
+ exit_status=EXIT_NOT_FOUND,
169
+ hint=(
170
+ "Check the project (views live in exactly one project) and pass the "
171
+ "exact parent DATASET_ID from 'view list DATASET_ID' or a dataset "
172
+ "read; do not rely on discovery for large projects."
173
+ ),
174
+ details={"view_id": view_id, "project_id": project, "reason": str(exc)},
175
+ recovery_commands=[
176
+ f"mammoth dataset list --project {project} --output json --no-input",
177
+ "mammoth dataset find NAME_SUBSTRING --output json --no-input",
178
+ ],
179
+ )
180
+
140
181
  @staticmethod
141
182
  def _coerce_call_arguments(method: Any, kwargs: dict[str, Any]) -> dict[str, Any]:
142
183
  """Coerce generic-``call`` kwargs to the method's annotated types.
@@ -233,27 +274,10 @@ class SdkMammothService:
233
274
  # The SDK's project-wide parent discovery reports a miss as a bare
234
275
  # ValueError. Name it, and hand back the reads that settle it,
235
276
  # instead of flattening it into "operation failed unexpectedly".
236
- if "not found in any dataset" not in str(exc):
277
+ miss = self._discovery_miss_error(exc, view_id)
278
+ if miss is None:
237
279
  raise map_sdk_exception(exc) from exc
238
- project = self._client.project_id
239
- raise CliError(
240
- code=CODE_RESOURCE_NOT_FOUND,
241
- message=(
242
- f"View {view_id} was not found in any dataset of project {project}; "
243
- "parent discovery walked every visible dataset and folder."
244
- ),
245
- exit_status=EXIT_NOT_FOUND,
246
- hint=(
247
- "Check the project (views live in exactly one project) and pass the "
248
- "exact parent DATASET_ID from 'view list DATASET_ID' or a dataset "
249
- "read; do not rely on discovery for large projects."
250
- ),
251
- details={"view_id": view_id, "project_id": project, "reason": str(exc)},
252
- recovery_commands=[
253
- f"mammoth dataset list --project {project} --output json --no-input",
254
- "mammoth dataset find NAME_SUBSTRING --output json --no-input",
255
- ],
256
- ) from exc
280
+ raise miss from exc
257
281
  except Exception as exc:
258
282
  raise map_sdk_exception(exc) from exc
259
283
  if method.startswith("_"):
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "mammoth-cli"
3
- version = "2.0.16"
3
+ version = "2.0.17"
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.7.8,<0.8)",
10
+ "mammoth-io (>=0.7.9,<0.8)",
11
11
  "typer (>=0.27,<0.28)",
12
12
  "rich (>=15,<16)",
13
13
  "platformdirs (>=4.10,<5)",
@@ -546,8 +546,9 @@ commands:
546
546
  required_fixture_guard: null
547
547
  secret_fields: []
548
548
  human_example: mammoth view conditional-format create VIEW_ID --help
549
- agent_example: 'mammoth view conditional-format create 123 123 --input ''{"rule": {"sample_key": "Status"}}''
550
- --output json --no-input'
549
+ agent_example: 'mammoth view conditional-format create 123 123 --input ''{"rule": {"cf_type": "RULE",
550
+ "payload": {"FORMAT": {"name": "Flag open orders", "color": "red", "applies_to": "row", "column_ids":
551
+ "[]"}, "CONDITION": {"OR": [{"column_1": {"CONTAINS": {"VALUE": ["Open"]}}}]}}}}'' --output json --no-input'
551
552
  unit_tests:
552
553
  - UT-VIEW-CONDITIONAL-FORMAT-CREATE
553
554
  contract_tests:
@@ -597,8 +598,8 @@ commands:
597
598
  required_fixture_guard: null
598
599
  secret_fields: []
599
600
  human_example: mammoth view conditional-format delete-all VIEW_ID --help
600
- agent_example: 'mammoth view conditional-format delete-all 123 123 --input ''{"rule_id": "rule-1"}'' --output
601
- json --no-input'
601
+ agent_example: 'mammoth view conditional-format delete-all 123 123 --input ''{"rule_id": "bca0ff33bd6f8ed1"}''
602
+ --output json --no-input'
602
603
  unit_tests:
603
604
  - UT-VIEW-CONDITIONAL-FORMAT-DELETE-ALL
604
605
  contract_tests:
@@ -3699,7 +3700,8 @@ commands:
3699
3700
  required_fixture_guard: null
3700
3701
  secret_fields: []
3701
3702
  human_example: mammoth view transform add-sql VIEW_ID --help
3702
- agent_example: 'mammoth view transform add-sql 123 --input ''{"query": "SELECT region, SUM(revenue) FROM data GROUP BY region", "dataset_id": 456}'' --output json --no-input'
3703
+ agent_example: 'mammoth view transform add-sql 123 --input ''{"query": "SELECT region, SUM(revenue) AS
3704
+ revenue FROM \"view:123\" GROUP BY region", "dataset_id": 456}'' --output json --no-input'
3703
3705
  unit_tests:
3704
3706
  - UT-VIEW-TRANSFORM-ADD-SQL
3705
3707
  contract_tests:
File without changes
File without changes
File without changes