mammoth-cli 2.0.75__tar.gz → 2.0.76__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 (233) hide show
  1. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/PKG-INFO +2 -2
  2. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/__init__.py +1 -1
  3. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +12 -12
  4. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/about-mammoth.md +2 -1
  5. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +3 -2
  6. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +1 -1
  7. mammoth_cli-2.0.76/mammoth_cli/bundled_skill/mammoth-cli/references/commands/calc.md +13 -0
  8. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +10 -0
  9. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +2 -2
  10. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +20 -4
  11. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/scheduling.md +4 -1
  12. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +2 -0
  13. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/addon.py +17 -4
  14. mammoth_cli-2.0.76/mammoth_cli/commands/calc.py +124 -0
  15. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/dataset.py +83 -5
  16. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/registry.py +3 -0
  17. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/schema.py +124 -15
  18. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/view.py +123 -0
  19. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/workspace.py +5 -1
  20. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/output/normalize.py +10 -0
  21. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/command_contract.py +19 -0
  22. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/positionals.py +30 -0
  23. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/pyproject.toml +2 -2
  24. mammoth_cli-2.0.76/spec/manifests/commands/calc.yaml +41 -0
  25. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/dashboard.yaml +7 -2
  26. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/external-key.yaml +5 -2
  27. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/view.yaml +59 -2
  28. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/workspace.yaml +2 -2
  29. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/.gitignore +0 -0
  30. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/LICENSE +0 -0
  31. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/README.md +0 -0
  32. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/__main__.py +0 -0
  33. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/app.py +0 -0
  34. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
  35. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +0 -0
  36. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +0 -0
  37. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
  38. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
  39. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
  40. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
  41. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
  42. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
  43. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
  44. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
  45. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
  46. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
  47. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
  48. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
  49. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
  50. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
  51. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
  52. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-qa.md +0 -0
  53. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
  54. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
  55. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
  56. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
  57. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
  58. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
  59. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
  60. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
  61. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
  62. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
  63. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
  64. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
  65. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
  66. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
  67. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
  68. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
  69. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
  70. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
  71. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
  72. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
  73. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
  74. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
  75. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
  76. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view-transform.md +0 -0
  77. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
  78. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
  79. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
  80. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
  81. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
  82. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
  83. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
  84. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
  85. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
  86. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
  87. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +0 -0
  88. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
  89. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +0 -0
  90. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +0 -0
  91. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +0 -0
  92. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
  93. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
  94. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
  95. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
  96. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
  97. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/__init__.py +0 -0
  98. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/activity.py +0 -0
  99. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/agent.py +0 -0
  100. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/ai.py +0 -0
  101. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/annotation.py +0 -0
  102. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/auth.py +0 -0
  103. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/automation.py +0 -0
  104. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/batch.py +0 -0
  105. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/billing.py +0 -0
  106. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/browse.py +0 -0
  107. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/capability.py +0 -0
  108. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/client_app.py +0 -0
  109. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/completion.py +0 -0
  110. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/config.py +0 -0
  111. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/connector.py +0 -0
  112. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/context.py +0 -0
  113. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/dashboard.py +0 -0
  114. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/data_app.py +0 -0
  115. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/doctor.py +0 -0
  116. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/external_key.py +0 -0
  117. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/file.py +0 -0
  118. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/folder.py +0 -0
  119. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/job.py +0 -0
  120. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/notification.py +0 -0
  121. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/parameter.py +0 -0
  122. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/project.py +0 -0
  123. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/report.py +0 -0
  124. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/schedule.py +0 -0
  125. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/skill.py +0 -0
  126. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/snippet.py +0 -0
  127. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/support.py +0 -0
  128. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/template.py +0 -0
  129. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/trash.py +0 -0
  130. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/upgrade.py +0 -0
  131. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/user.py +0 -0
  132. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/view_ops.py +0 -0
  133. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/webhook.py +0 -0
  134. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/commands/workflow.py +0 -0
  135. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/context/__init__.py +0 -0
  136. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/context/credentials.py +0 -0
  137. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/context/endpoint.py +0 -0
  138. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/context/profiles.py +0 -0
  139. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/context/resolver.py +0 -0
  140. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/contracts/__init__.py +0 -0
  141. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/contracts/auth.py +0 -0
  142. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/embed.py +0 -0
  143. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/errors/__init__.py +0 -0
  144. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/errors/envelope.py +0 -0
  145. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/manifest/__init__.py +0 -0
  146. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/manifest/loader.py +0 -0
  147. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/messages/__init__.py +0 -0
  148. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/output/__init__.py +0 -0
  149. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/output/envelope.py +0 -0
  150. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/output/policy.py +0 -0
  151. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/output/progress.py +0 -0
  152. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/output/render.py +0 -0
  153. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/py.typed +0 -0
  154. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/__init__.py +0 -0
  155. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/confirm.py +0 -0
  156. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/dryrun.py +0 -0
  157. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/embedded.py +0 -0
  158. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/executor.py +0 -0
  159. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/input_loader.py +0 -0
  160. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/invocation.py +0 -0
  161. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/options.py +0 -0
  162. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/parents.py +0 -0
  163. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/runlog.py +0 -0
  164. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/session.py +0 -0
  165. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/strict.py +0 -0
  166. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/updates.py +0 -0
  167. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/validate.py +0 -0
  168. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/runtime/verify.py +0 -0
  169. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/__init__.py +0 -0
  170. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/argspec.py +0 -0
  171. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/coerce.py +0 -0
  172. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/conditions.py +0 -0
  173. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/dashboard_pages.py +0 -0
  174. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/dashboard_review.py +0 -0
  175. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/data_quality.py +0 -0
  176. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/dispatch.py +0 -0
  177. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/factory.py +0 -0
  178. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/input_fields.py +0 -0
  179. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/mapping.py +0 -0
  180. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/openapi_types.py +0 -0
  181. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/protocol.py +0 -0
  182. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/sdk_service.py +0 -0
  183. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/testing.py +0 -0
  184. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/services/type_system.py +0 -0
  185. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/skills/__init__.py +0 -0
  186. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/skills/installer.py +0 -0
  187. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/skills/steering.py +0 -0
  188. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/mammoth_cli/testing.py +0 -0
  189. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/activity.yaml +0 -0
  190. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/addon.yaml +0 -0
  191. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/agent.yaml +0 -0
  192. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/ai.yaml +0 -0
  193. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/annotation.yaml +0 -0
  194. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/auth.yaml +0 -0
  195. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/automation.yaml +0 -0
  196. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/batch.yaml +0 -0
  197. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/billing.yaml +0 -0
  198. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/browse.yaml +0 -0
  199. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/capability.yaml +0 -0
  200. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/client-app.yaml +0 -0
  201. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/completion.yaml +0 -0
  202. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/config.yaml +0 -0
  203. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/connector.yaml +0 -0
  204. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/context.yaml +0 -0
  205. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/data-app.yaml +0 -0
  206. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/dataset.yaml +0 -0
  207. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/doctor.yaml +0 -0
  208. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/file.yaml +0 -0
  209. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/folder.yaml +0 -0
  210. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/job.yaml +0 -0
  211. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/log.yaml +0 -0
  212. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/notification.yaml +0 -0
  213. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/parameter.yaml +0 -0
  214. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/project.yaml +0 -0
  215. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/report.yaml +0 -0
  216. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/schedule.yaml +0 -0
  217. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/schema.yaml +0 -0
  218. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/skill.yaml +0 -0
  219. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/snippet.yaml +0 -0
  220. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/support.yaml +0 -0
  221. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/template.yaml +0 -0
  222. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/trash.yaml +0 -0
  223. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/upgrade.yaml +0 -0
  224. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/user.yaml +0 -0
  225. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/version.yaml +0 -0
  226. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/webhook.yaml +0 -0
  227. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/commands/workflow.yaml +0 -0
  228. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/openapi-operations.yaml +0 -0
  229. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/schema-v1.json +0 -0
  230. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/sdk-catalog.source.yaml +0 -0
  231. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/manifests/sdk-methods.yaml +0 -0
  232. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/spec/openapi/metadata.json +0 -0
  233. {mammoth_cli-2.0.75 → mammoth_cli-2.0.76}/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.75
3
+ Version: 2.0.76
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.34
20
+ Requires-Dist: mammoth-io<0.8,>=0.7.35
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.0.75"
9
+ __version__ = "2.0.76"
10
10
 
11
11
  # The versioned machine output envelope contract.
12
12
  SCHEMA_VERSION = 1
@@ -29,16 +29,16 @@ mammoth doctor # auth, endpoint, connectivity, version;
29
29
  mammoth project ensure 'PROJECT NAME' # get-or-create; becomes the active project
30
30
  ```
31
31
 
32
- `doctor` failing is a precondition failure, not a reason to proceed anyway.
32
+ `doctor` failing is a precondition failure; never proceed anyway.
33
33
  When the connection check fails with a 502, 504 or timeout, `mammoth doctor
34
34
  --input '{"wait": 300}'` probes again for up to that many seconds; continue
35
35
  only once it passes. Production is the `app` endpoint; use `release` only
36
36
  when named, and check `meta.profile`/`auth status` `endpoint` match before
37
37
  continuing. If no profile has credentials, tell the operator to run
38
38
  `mammoth auth login` in their own terminal (add
39
- `--profile NAME` only for a profile other than `default`; [auth](references/auth.md)
39
+ `--profile NAME` only if not `default`; [auth](references/auth.md)
40
40
  says where the token comes from) and wait; never ask for the token in chat,
41
- never read one from a file or environment variable, never run `auth login`
41
+ never read one from a file/env var, never run `auth login`
42
42
  yourself. If any envelope carries `meta.update_available`, run its `command`
43
43
  before the next step.
44
44
 
@@ -51,8 +51,7 @@ before the next step.
51
51
  - The CLI remembers which dataset owns each view from any read (`view list
52
52
  DATASET_ID`, `view get VIEW_ID`, an upload). After that, no `dataset_id`
53
53
  on transforms, exports or deletes. If a command asks for the parent
54
- `DATASET_ID`, read the view once and repeat it; an explicit value always
55
- wins.
54
+ `DATASET_ID`, read the view once and repeat it; an explicit value wins.
56
55
  - Commands that start platform work wait up to 300 s for the job; on
57
56
  `timeout` use the `job get` recovery command printed, do not resubmit.
58
57
 
@@ -157,8 +156,8 @@ your report. If no column links the files, ask before you combine them.
157
156
  deliverables; cleanup is exact-ID authorized and
158
157
  never means delete-all-owned-resources: delete only ids this run created,
159
158
  one per call, and read back that they are gone.
160
- - A command whose schema lists `secret_fields` takes `--input FILE` (mode
161
- 0600); secrets never go in argv, notes, checkpoints or replies.
159
+ - `secret_fields` commands send secrets via `--input`: 0600 FILE (shell)
160
+ or JSON (embedded); never in replies, notes, checkpoints or run logs.
162
161
 
163
162
  ## Verify before you report
164
163
 
@@ -166,7 +165,7 @@ your report. If no column links the files, ask before you combine them.
166
165
  change (set-values, filter, replace, join, fill) run `view data get
167
166
  VIEW_ID` (50 rows by default, `limit` to change) and check rows the
168
167
  condition should and should not have touched. Sample the target column
169
- *before* the change for comparison.
168
+ before the change.
170
169
  - A uniform result (every amount 0, every region "Unknown", most join rows
171
170
  unmatched) means the previous step went wrong; stop and re-inspect it.
172
171
  - `column_warnings` on a data read and `join_check` on a join are findings,
@@ -175,13 +174,14 @@ your report. If no column links the files, ask before you combine them.
175
174
  - A timeout, exit 7 or interruption does not prove failure; reconcile an
176
175
  `outcome_unknown` (`job get`, `view task list`) before replaying.
177
176
  - Check an answer with no write against the question (a trend: time
178
- buckets, a partial period named); no `project check`.
177
+ buckets, a partial period named; no `project check`); a reported number
178
+ comes from `calc`/`view data compare`, never mental math.
179
179
  - After a write, run `mammoth project check PROJECT_ID` and fix each
180
- `to_report` line, or give it one line in the report.
180
+ `to_report` line, or note it in the report.
181
181
  - Run the [report checklist](references/report-checklist.md) before stating
182
182
  a number or calling a step done. When files disagree,
183
- [capabilities](references/capabilities.md) wins over a recipe, which wins
184
- over the generated catalog.
183
+ [capabilities](references/capabilities.md) wins over a recipe, then the
184
+ generated catalog.
185
185
 
186
186
  ## Route only what the task needs
187
187
 
@@ -129,7 +129,8 @@ sort):
129
129
  {"cust_id": "Customer ID"}}`. The column keeps its internal name, so
130
130
  earlier tasks keep working; later commands, data reads, exports and
131
131
  dashboards use the new name. To name a column you create, use its
132
- `new_column` or `as_name` field instead.
132
+ `new_column` or `as_name` field instead. Safe to call for a "just how it
133
+ looks" request -- it does not alter cell values.
133
134
  - **Sort the rows:** `view transform sort` with `{"order_by": [["Revenue",
134
135
  "DESC"]]}` (up to three columns; `[]` clears it). Data reads and exports
135
136
  return rows in this order. To keep only the top N rows, use `limit-rows`
@@ -1,6 +1,6 @@
1
1
  # Published CLI command catalog
2
2
 
3
- This generated catalog is a lookup table for every command in the published CLI manifest, currently 571; each entry carries its release status line. It is a command-contract index, not an assertion that every backend/OpenAPI operation has a CLI binding. For an exact local CLI contract, run `mammoth schema get COMMAND_ID`; `mammoth capability list` is an API-binding inventory and can omit typed/local CLI routes. For focused workflows, read the [recipes index](recipes/index.md). Sensitive structured input must come from a private file or pipe; never put secrets in literal argv.
3
+ This generated catalog is a lookup table for every command in the published CLI manifest, currently 573; each entry carries its release status line. It is a command-contract index, not an assertion that every backend/OpenAPI operation has a CLI binding. For an exact local CLI contract, run `mammoth schema get COMMAND_ID`; `mammoth capability list` is an API-binding inventory and can omit typed/local CLI routes. For focused workflows, read the [recipes index](recipes/index.md). Sensitive structured input must come from a private file or pipe; never put secrets in literal argv.
4
4
 
5
5
  Load only the applicable domain file:
6
6
 
@@ -14,6 +14,7 @@ Load only the applicable domain file:
14
14
  - [batch](commands/batch.md) — 7 published commands
15
15
  - [billing](commands/billing.md) — 23 published commands
16
16
  - [browse](commands/browse.md) — 4 published commands
17
+ - [calc](commands/calc.md) — 1 published commands
17
18
  - [capability](commands/capability.md) — 3 published commands
18
19
  - [client-app](commands/client-app.md) — 5 published commands
19
20
  - [completion](commands/completion.md) — 2 published commands
@@ -45,7 +46,7 @@ Load only the applicable domain file:
45
46
  - [user](commands/user.md) — 8 published commands
46
47
  - [version](commands/version.md) — 1 published commands
47
48
  - [view-transform](commands/view-transform.md) — 32 published commands
48
- - [view](commands/view.md) — 88 published commands
49
+ - [view](commands/view.md) — 89 published commands
49
50
  - [webhook](commands/webhook.md) — 7 published commands
50
51
  - [workflow](commands/workflow.md) — 16 published commands
51
52
  - [workspace](commands/workspace.md) — 20 published commands
@@ -10,7 +10,7 @@ Example: `mammoth automation create 'Revenue report' --input '{"description": "s
10
10
 
11
11
  Result: `AutomationCreateResult`; mutation `external_effect`, confirmation `yes_always`, wait policy `not_async`.
12
12
 
13
- Status on release: ran once on CLI 2.0.18 — fixture-lifecycle sweep 2026-09-19: exit 0 on release with CLI 2.0.18. Created automation id=1 after two failed attempts: agent_example's run_data_retrieval needs cloud-source dataset ids (4AUTO006), and send_an_alert needed attachments.dataview_ids (undocume…
13
+ Status on release: ran once on CLI 2.0.18 — fixture-lifecycle sweep 2026-09-19: exit 0 on CLI 2.0.18. Created automation id=1 after two failed attempts: run_data_retrieval needs cloud-source dataset ids (4AUTO006); send_an_alert needs attachments.dataview_ids, sent as CSV. Single invocation only.
14
14
 
15
15
  ### `automation.delete`
16
16
 
@@ -0,0 +1,13 @@
1
+ # `calc` commands
2
+
3
+ Every command returns the standard JSON envelope. On nonzero exit, read the error envelope and its `recovery_commands`; do not guess request fields. "Status on release" is joined from `docs/release-capability-matrix.json`: *ran once* means one bounded live run succeeded on the named CLI release, *untried* means nobody has run it, *not supported* means the backend refuses it. When this file disagrees with [capabilities](../capabilities.md) or a recipe, they win. Envelope shapes: [machine output](../machine-output.md).
4
+
5
+ ### `calc`
6
+
7
+ Run: `mammoth calc`. Exact input fields: `mammoth schema get calc`.
8
+
9
+ Example: `mammoth calc '2063664 - 1917815'`. Placeholders are illustrative; resolve IDs and input from observed reads.
10
+
11
+ Result: `CalcResult`; mutation `read`, confirmation `none`, wait policy `not_async`.
12
+
13
+ Status on release: untried; no live run recorded.
@@ -222,6 +222,16 @@ Result: `ViewDataAggregateResult`; mutation `read`, confirmation `none`, wait po
222
222
 
223
223
  Status on release: untried; no live run recorded.
224
224
 
225
+ ### `view.data.compare`
226
+
227
+ Run: `mammoth view data compare`. Exact input fields: `mammoth schema get view.data.compare`.
228
+
229
+ Example: `mammoth view data compare 111 222 --input '{"group_by": ["Campaign"], "aggregations": [{"column": "Spend", "function": "SUM", "as_name": "Spend"}]}'`. Placeholders are illustrative; resolve IDs and input from observed reads.
230
+
231
+ Result: `ViewDataCompareResult`; mutation `read`, confirmation `none`, wait policy `not_async`.
232
+
233
+ Status on release: untried; no live run recorded.
234
+
225
235
  ### `view.data.explore`
226
236
 
227
237
  Run: `mammoth view data explore`. Exact input fields: `mammoth schema get view.data.explore`.
@@ -138,9 +138,9 @@ Status on release: untried; no live run recorded.
138
138
 
139
139
  Run: `mammoth workspace user add`. Exact input fields: `mammoth schema get workspace.user.add`.
140
140
 
141
- Example: `mammoth workspace user add --input '{"email_ids": ["analyst@example.com"]}'`. Placeholders are illustrative; resolve IDs and input from observed reads.
141
+ Example: `mammoth workspace user add --yes --input '{"email_ids": ["analyst@example.com"]}'`. Illustrative only: append `--yes` after observing an owned target.
142
142
 
143
- Result: `WorkspaceUserAddResult`; mutation `benign_mutation`, confirmation `none`, wait policy `not_async`.
143
+ Result: `WorkspaceUserAddResult`; mutation `benign_mutation`, confirmation `yes_always`, wait policy `not_async`.
144
144
 
145
145
  Status on release: untried; no live run recorded.
146
146
 
@@ -45,6 +45,12 @@ mammoth view export dataset SOURCE_VIEW_ID SOURCE_DATASET_ID --yes \
45
45
  mammoth view export list SOURCE_VIEW_ID SOURCE_DATASET_ID # handler internal_dataset, status executed, TARGET_DS_ID N
46
46
  ```
47
47
 
48
+ The product's per-destination "Export Auto-Sync" toggle is this same
49
+ pipeline-step behavior seen from the UI: it is the CLI's `trigger_type`
50
+ (default `pipeline`; pass `"none"` to turn Auto-Sync off) and `run_immediately`
51
+ (whether it also executes once now) fields on the typed export commands —
52
+ there is no separate Auto-Sync endpoint or field to find.
53
+
48
54
  `target_ds_id` writes into an existing dataset instead of creating one
49
55
  (`save_as_mode` `REPLACE_IN_DS` or `APPEND_TO_DS`). Read the delivery back in
50
56
  the target project (`view list N --project P`, `view data get`) before
@@ -58,10 +64,20 @@ reporting it. Do not build this with `view export create`: the raw
58
64
  `schema get` lists `secret_fields` for every typed destination export
59
65
  (`postgres`, `mysql`, `mssql`, `redshift`, `elasticsearch`, `ftp`, `sftp`,
60
66
  `powerbi`, `tableau`, `azure-blob`, `onedrive`, `sharepoint`, `rest`). When
61
- that list is non-empty the request body is written by the operator to a
62
- `0600` file and passed as `--input FILE`; it is never an inline document and
63
- never appears in argv, the run log, or a checkpoint. The connector command is
64
- `external_effect` with `confirmation: yes_always`, so `--yes` is required.
67
+ that list is non-empty:
68
+
69
+ - In a shell, the operator writes the request body to a `0600` file and
70
+ passes it as `--input FILE` -- never an inline document, and never in
71
+ argv.
72
+ - Embedded in a product with no shell and no file system (see
73
+ `mammoth_cli.embed.invoke`), where every write is shown to the user on a
74
+ confirmation card before it runs, the secret goes in the `--input`
75
+ JSON's credential field instead: a password or token the user supplies
76
+ for their own destination is used there, behind the card.
77
+
78
+ In every case the secret never appears in a reply, a note, a checkpoint, or
79
+ the run log. The connector command is `external_effect` with
80
+ `confirmation: yes_always`, so `--yes` is required.
65
81
 
66
82
  ```bash
67
83
  mammoth schema get view.export.postgres # read secret_fields, required fields
@@ -52,7 +52,10 @@ automation.create` under `tasks[].details`:
52
52
 
53
53
  - `append_data`: `destination_dataset_ids` (required) plus either
54
54
  `source_folder_resource_id` or `source_dataset_id`.
55
- - `send_an_alert`: `alert_type` ("email"), `recipients`, `subject`.
55
+ - `send_an_alert`: `alert_type` ("email"), `recipients`, `subject`, and optional
56
+ `attachments.dataview_ids` (a list of view ids); each attached view is
57
+ emailed as a CSV file, combined row count capped at 100,000 across all
58
+ attachments.
56
59
  - `pull_cloud_files`: `connector_key`, `connection_key`,
57
60
  `cloud_source_folder_path`, `destination_folder_resource_id`.
58
61
 
@@ -16,5 +16,7 @@ Every "yes" must point at a command you ran in this task and its response.
16
16
  | List cleanup ids and read each one back | one id per destructive call, each followed by a `list`/`get` that no longer shows it; the final list of what remains |
17
17
  | Nothing in the report is a secret or an unredacted body | no keys, tokens, `--input` documents for `secret_fields` commands, or raw error bodies |
18
18
  | Name every unknown outcome | any exit 7 / `outcome_unknown` with the id or job it may have created |
19
+ | A "can X do Y" answer leads with the real limitation, not an unqualified "Yes" when only an alternative exists | the caveat or alternative is the first clause of the answer, not an afterthought |
20
+ | A capability you describe by a command you looked up names that command's own words | the reply uses the term from its purpose text or `action` field (e.g. `view ai profile` -> "profile"/"insights") so the user can find it in the app |
19
21
 
20
22
  If you cannot satisfy a row, say so in the report instead of omitting it.
@@ -20,6 +20,7 @@ from typing import Any
20
20
  from mammoth_cli.errors.envelope import (
21
21
  CODE_MISSING_FIELD,
22
22
  CODE_SDK_SYMBOL_UNRESOLVED,
23
+ CODE_UNSUPPORTED_CONTRACT,
23
24
  EXIT_USAGE,
24
25
  CliError,
25
26
  )
@@ -114,10 +115,22 @@ def addon_connector_remove(invocation: Invocation) -> HandlerResult:
114
115
 
115
116
 
116
117
  def addon_list(invocation: Invocation) -> HandlerResult:
117
- """List active addons for the workspace."""
118
- with open_service(invocation) as (service, auth):
119
- data = service.call(_symbol(invocation))
120
- return data, _meta(invocation, auth.workspace_id)
118
+ """List active addons for the workspace.
119
+
120
+ RCA T1-W-17: ``GET /workspaces/{id}/addons`` has no backing route on the
121
+ backend at all (a 404 from Litestar's own routing trie, not a typed
122
+ error) -- fail loud with that fact up front rather than surface the raw
123
+ 404 as if the call had merely found nothing.
124
+ """
125
+ raise CliError(
126
+ code=CODE_UNSUPPORTED_CONTRACT,
127
+ message=(
128
+ "addon list has no backend route (GET /workspaces/{workspace_id}/addons does not "
129
+ "exist) and always 404s; it is currently non-functional."
130
+ ),
131
+ exit_status=EXIT_USAGE,
132
+ hint="Use `billing chargebee-plan` or `billing subscription get` for plan/storage info.",
133
+ )
121
134
 
122
135
 
123
136
  def addon_storage_add(invocation: Invocation) -> HandlerResult:
@@ -0,0 +1,124 @@
1
+ """The ``calc`` command: local, read-only, exact arithmetic.
2
+
3
+ T2-WPP-W8: an agent ran ``view data aggregate`` on two views and subtracted
4
+ the totals mentally, reporting 45,849 where the true difference was 145,849
5
+ (2,063,664 - 1,917,815) -- a transcription/mental-math error a machine never
6
+ makes. Every number an agent reports must come from a tool result, never
7
+ mental arithmetic; ``calc`` is that tool for a single expression (``view
8
+ data compare`` is the tool for a per-key comparison across two views).
9
+
10
+ The expression is parsed with :mod:`ast` and only a small, explicitly
11
+ allowed set of node types is walked -- never Python's ``eval()``. All
12
+ arithmetic is :class:`decimal.Decimal`, so results are exact, not a float
13
+ approximation.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import ast
19
+ import re
20
+ from collections.abc import Callable
21
+ from decimal import ROUND_HALF_UP, Decimal, DivisionByZero, InvalidOperation
22
+ from typing import Any
23
+
24
+ from mammoth_cli.errors.envelope import CODE_INVALID_ARGUMENT, EXIT_USAGE, CliError
25
+ from mammoth_cli.runtime.invocation import Invocation
26
+
27
+ HandlerResult = tuple[Any, dict[str, Any]]
28
+
29
+ #: A trailing "N%" is rewritten to "(N/100)" before parsing -- ``%`` is not
30
+ #: valid Python expression syntax on its own.
31
+ _PERCENT_RE = re.compile(r"(\d+(?:\.\d+)?)\s*%")
32
+
33
+ _BINOPS: dict[type, Callable[[Decimal, Decimal], Decimal]] = {
34
+ ast.Add: lambda a, b: a + b,
35
+ ast.Sub: lambda a, b: a - b,
36
+ ast.Mult: lambda a, b: a * b,
37
+ ast.Div: lambda a, b: a / b,
38
+ }
39
+
40
+
41
+ def _unsupported(expression: str) -> CliError:
42
+ return CliError(
43
+ code=CODE_INVALID_ARGUMENT,
44
+ message=f"Unsupported syntax in {expression!r}.",
45
+ exit_status=EXIT_USAGE,
46
+ hint="calc supports + - * / and parentheses, unary +/-, a trailing "
47
+ "'%' (divides by 100), and round(x[, ndigits]).",
48
+ )
49
+
50
+
51
+ def _evaluate(node: ast.AST, expression: str) -> Decimal:
52
+ if isinstance(node, ast.Expression):
53
+ return _evaluate(node.body, expression)
54
+ if (
55
+ isinstance(node, ast.Constant)
56
+ and isinstance(node.value, (int, float))
57
+ and not isinstance(node.value, bool)
58
+ ):
59
+ return Decimal(str(node.value))
60
+ if isinstance(node, ast.BinOp) and type(node.op) in _BINOPS:
61
+ left = _evaluate(node.left, expression)
62
+ right = _evaluate(node.right, expression)
63
+ try:
64
+ return _BINOPS[type(node.op)](left, right)
65
+ except (InvalidOperation, DivisionByZero, ZeroDivisionError) as exc:
66
+ raise CliError(
67
+ code=CODE_INVALID_ARGUMENT,
68
+ message=f"Division by zero in {expression!r}.",
69
+ exit_status=EXIT_USAGE,
70
+ ) from exc
71
+ if isinstance(node, ast.UnaryOp) and isinstance(node.op, (ast.UAdd, ast.USub)):
72
+ value = _evaluate(node.operand, expression)
73
+ return value if isinstance(node.op, ast.UAdd) else -value
74
+ if (
75
+ isinstance(node, ast.Call)
76
+ and isinstance(node.func, ast.Name)
77
+ and node.func.id == "round"
78
+ and not node.keywords
79
+ and 1 <= len(node.args) <= 2
80
+ ):
81
+ value = _evaluate(node.args[0], expression)
82
+ ndigits = 0
83
+ if len(node.args) == 2:
84
+ digits_node = node.args[1]
85
+ if not (
86
+ isinstance(digits_node, ast.Constant)
87
+ and isinstance(digits_node.value, int)
88
+ and not isinstance(digits_node.value, bool)
89
+ ):
90
+ raise _unsupported(expression)
91
+ ndigits = digits_node.value
92
+ quantum = Decimal(1).scaleb(-ndigits)
93
+ return value.quantize(quantum, rounding=ROUND_HALF_UP)
94
+ raise _unsupported(expression)
95
+
96
+
97
+ def calc(invocation: Invocation) -> HandlerResult:
98
+ """Evaluate one arithmetic expression exactly.
99
+
100
+ The sole positional argument is the expression: ``+ - * /``,
101
+ parentheses, unary ``+``/``-``, a trailing ``%`` (divides by 100), and
102
+ ``round(x[, ndigits])``. Returns the expression and its exact
103
+ :class:`~decimal.Decimal` result as a string.
104
+ """
105
+ expression = invocation.extra_args[0] if invocation.extra_args else None
106
+ if not expression or not expression.strip():
107
+ raise CliError(
108
+ code=CODE_INVALID_ARGUMENT,
109
+ message="calc requires an expression argument, e.g. '2063664 - 1917815'.",
110
+ exit_status=EXIT_USAGE,
111
+ )
112
+ normalized = _PERCENT_RE.sub(r"(\1/100)", expression)
113
+ try:
114
+ tree = ast.parse(normalized, mode="eval")
115
+ except SyntaxError as exc:
116
+ raise CliError(
117
+ code=CODE_INVALID_ARGUMENT,
118
+ message=f"Could not parse {expression!r}: {exc.msg}.",
119
+ exit_status=EXIT_USAGE,
120
+ hint="calc supports + - * / and parentheses, unary +/-, a trailing "
121
+ "'%' (divides by 100), and round(x[, ndigits]).",
122
+ ) from exc
123
+ result = _evaluate(tree, expression)
124
+ return {"expression": expression, "result": str(result)}, {}
@@ -184,8 +184,9 @@ def dataset_find(invocation: Invocation) -> HandlerResult:
184
184
  return {
185
185
  "matches": matches,
186
186
  "projects_searched": len(projects),
187
- "projects_truncated": invocation.project is None
188
- and len(projects) >= _MAX_PROJECTS_SEARCHED,
187
+ "projects_truncated": (
188
+ invocation.project is None and len(projects) >= _MAX_PROJECTS_SEARCHED
189
+ ),
189
190
  }, meta
190
191
 
191
192
 
@@ -200,15 +201,82 @@ def dataset_list(invocation: Invocation) -> HandlerResult:
200
201
  return data, _meta(invocation, auth.workspace_id, project_id)
201
202
 
202
203
 
204
+ def _export_write_hint(data: dict[str, Any]) -> str | None:
205
+ """Name the recurring export that writes into this dataset, if any.
206
+
207
+ A dataset produced by ``view export dataset`` carries its source view and
208
+ export ids in ``additional_info`` (``DATAVIEW_ID``/``TRIGGER_ID`` — an
209
+ export is a ``DataviewActionTrigger`` row, so ``TRIGGER_ID`` is exactly the
210
+ ``export_id`` argument ``view export delete`` takes). Deleting the dataset
211
+ does not stop that export from writing into it again; name the export and
212
+ the command that stops it (T1-O-10: an agent deleted the dataset instead).
213
+ """
214
+ additional_info = data.get("additional_info")
215
+ if not isinstance(additional_info, dict):
216
+ return None
217
+ dataview_id = additional_info.get("DATAVIEW_ID")
218
+ export_id = additional_info.get("TRIGGER_ID")
219
+ if not isinstance(dataview_id, int) or not isinstance(export_id, int):
220
+ return None
221
+ return (
222
+ f"This dataset is written by a recurring export from view {dataview_id} "
223
+ f"(export {export_id}); deleting the dataset does not stop the export. "
224
+ f"Run 'mammoth view export delete {dataview_id} {export_id}' to stop it."
225
+ )
226
+
227
+
228
+ def _zero_view_hint(dataset_id: int) -> str:
229
+ """Name the fix for a dataset with no queryable views yet (T1-I-13).
230
+
231
+ Nothing is queryable until a view exists (transforms, joins, exports and
232
+ previews all take a view id, not a dataset id) — an agent that only reads
233
+ dataset-level metadata and never sees a zero view count can conclude "no
234
+ correction needed" while nothing it changed is visible anywhere.
235
+ """
236
+ return (
237
+ f"This dataset has no views yet; nothing is queryable until one exists. "
238
+ f"Run 'mammoth view create {dataset_id}' to create one."
239
+ )
240
+
241
+
203
242
  def dataset_get(invocation: Invocation) -> HandlerResult:
204
243
  """Get one dataset by id in the active project."""
205
244
  project_id = require_project(invocation)
206
245
  dataset_id = _require_int_positional(invocation, "dataset id")
207
246
  with open_service(invocation) as (service, auth):
208
247
  data = service.call(_symbol(invocation), dataset_id=dataset_id, project_id=project_id)
248
+ views = service.call(
249
+ "mammoth.api.dataviews.DataviewsAPI.list",
250
+ dataset_id=dataset_id,
251
+ project_id=project_id,
252
+ )
253
+ _strip_file_ingestion_automation_possible(data)
254
+ hint = _export_write_hint(data) if isinstance(data, dict) else None
255
+ if isinstance(data, dict) and isinstance(views, dict):
256
+ view_count = len(views.get("dataviews") or [])
257
+ data = {**data, "view_count": view_count}
258
+ if view_count == 0:
259
+ zero_hint = _zero_view_hint(dataset_id)
260
+ hint = f"{hint} {zero_hint}" if hint else zero_hint
261
+ if hint is not None:
262
+ data = {**data, "hint": hint}
209
263
  return data, _meta(invocation, auth.workspace_id, project_id)
210
264
 
211
265
 
266
+ def _strip_file_ingestion_automation_possible(data: Any) -> None:
267
+ """Drop ``automation_possible`` (T1-R-01/T1-R-07): CSV-ingestion metadata
268
+ about whether the header-parsing pipeline can auto-process this upload
269
+ (``api/api/file/unprocessed.py``), unrelated to whether the dataset has a
270
+ connector to put on a scheduled refresh. Left in, an agent checking a
271
+ dataset's automation options reads it as contradicting a correct "no
272
+ refreshable source" claim."""
273
+ if not isinstance(data, dict):
274
+ return
275
+ params = data.get("additional_info", {}).get("all_data_backup", {}).get("PARAMS", {})
276
+ if isinstance(params, dict):
277
+ params.pop("automation_possible", None)
278
+
279
+
212
280
  def dataset_data(invocation: Invocation) -> HandlerResult:
213
281
  """Fetch a dataset's data, waiting for the backing job to complete."""
214
282
  project_id = require_project(invocation)
@@ -432,11 +500,21 @@ def dataset_delete(invocation: Invocation) -> HandlerResult:
432
500
  """Permanently delete one dataset by id. Prompt or ``--yes`` required."""
433
501
  project_id = require_project(invocation)
434
502
  dataset_id = _require_int_positional(invocation, "dataset id")
435
- enforce_confirmation(
436
- invocation, policy=POLICY_PROMPT_OR_YES, action=f"delete dataset {dataset_id}"
437
- )
503
+ action = f"delete dataset {dataset_id}"
438
504
  with open_service(invocation) as (service, auth):
505
+ # A read, not a mutation: the dry-run gate lets it through so the
506
+ # confirmation message below can name the export writing into this
507
+ # dataset (T1-O-10), the same as a real run would see.
508
+ preview = service.call(
509
+ "mammoth.api.datasets.DatasetsAPI.get", dataset_id=dataset_id, project_id=project_id
510
+ )
511
+ hint = _export_write_hint(preview) if isinstance(preview, dict) else None
512
+ if hint is not None:
513
+ action = f"{action}. {hint}"
514
+ enforce_confirmation(invocation, policy=POLICY_PROMPT_OR_YES, action=action)
439
515
  data = service.call(_symbol(invocation), dataset_id=dataset_id, project_id=project_id)
516
+ if hint is not None and isinstance(data, dict):
517
+ data = {**data, "hint": hint}
440
518
  return data, _meta(invocation, auth.workspace_id, project_id)
441
519
 
442
520
 
@@ -26,6 +26,7 @@ from mammoth_cli.commands import automation as automation_cmd
26
26
  from mammoth_cli.commands import batch as batch_cmd
27
27
  from mammoth_cli.commands import billing as billing_cmd
28
28
  from mammoth_cli.commands import browse as browse_cmd
29
+ from mammoth_cli.commands import calc as calc_cmd
29
30
  from mammoth_cli.commands import capability as capability_cmd
30
31
  from mammoth_cli.commands import client_app as client_app_cmd
31
32
  from mammoth_cli.commands import completion as completion_cmd
@@ -231,6 +232,7 @@ HANDLERS: dict[str, Handler] = {
231
232
  "log.path": _log_path,
232
233
  "log.tail": _log_tail,
233
234
  "doctor": doctor_cmd.doctor,
235
+ "calc": calc_cmd.calc,
234
236
  "completion.show": completion_cmd.completion_show,
235
237
  "completion.install": completion_cmd.completion_install,
236
238
  "skill.agents-md.install": skill_cmd.skill_agents_md_install,
@@ -644,6 +646,7 @@ HANDLERS: dict[str, Handler] = {
644
646
  "view.data.get": view_cmd.view_data_get,
645
647
  "view.data.query": view_cmd.view_data_query,
646
648
  "view.data.aggregate": view_cmd.view_data_aggregate,
649
+ "view.data.compare": view_cmd.view_data_compare,
647
650
  "view.data.explore": view_cmd.view_data_explore,
648
651
  "view.exportable-config.get": view_cmd.view_exportable_config_get,
649
652
  "view.exportable-config.apply": view_cmd.view_exportable_config_apply,