mammoth-cli 2.0.30__tar.gz → 2.0.32__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 (222) hide show
  1. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/PKG-INFO +11 -12
  2. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/README.md +9 -10
  3. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/__init__.py +1 -1
  4. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/app.py +162 -60
  5. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +7 -5
  6. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +10 -2
  7. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +1 -1
  8. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +1 -1
  9. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +12 -9
  10. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +5 -1
  11. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +38 -34
  12. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +2 -2
  13. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +2 -2
  14. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +1 -1
  15. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +4 -1
  16. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +2 -2
  17. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +25 -19
  18. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +4 -5
  19. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +4 -8
  20. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +8 -7
  21. mammoth_cli-2.0.32/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +19 -0
  22. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +3 -3
  23. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +7 -0
  24. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/auth.py +1 -5
  25. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/capability.py +10 -11
  26. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/completion.py +1 -4
  27. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/doctor.py +37 -7
  28. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/file.py +9 -6
  29. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/job.py +18 -12
  30. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/workflow.py +5 -2
  31. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/context/credentials.py +139 -19
  32. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/context/resolver.py +1 -3
  33. mammoth_cli-2.0.32/mammoth_cli/manifest/loader.py +164 -0
  34. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/executor.py +26 -0
  35. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/input_loader.py +4 -2
  36. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/invocation.py +1 -1
  37. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/strict.py +19 -4
  38. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/sdk_service.py +24 -2
  39. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/skills/installer.py +69 -2
  40. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/pyproject.toml +2 -2
  41. mammoth_cli-2.0.30/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +0 -19
  42. mammoth_cli-2.0.30/mammoth_cli/manifest/loader.py +0 -96
  43. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/.gitignore +0 -0
  44. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/LICENSE +0 -0
  45. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/__main__.py +0 -0
  46. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +0 -0
  47. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +0 -0
  48. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
  49. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
  50. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
  51. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
  52. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
  53. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
  54. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
  55. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
  56. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
  57. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
  58. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
  59. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
  60. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
  61. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
  62. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
  63. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
  64. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
  65. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
  66. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
  67. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
  68. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
  69. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
  70. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
  71. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
  72. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
  73. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
  74. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
  75. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
  76. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
  77. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
  78. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
  79. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
  80. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
  81. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
  82. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
  83. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
  84. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
  85. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
  86. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +0 -0
  87. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
  88. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
  89. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +0 -0
  90. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
  91. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
  92. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
  93. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
  94. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
  95. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/__init__.py +0 -0
  96. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/activity.py +0 -0
  97. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/addon.py +0 -0
  98. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/agent.py +0 -0
  99. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/ai.py +0 -0
  100. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/annotation.py +0 -0
  101. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/automation.py +0 -0
  102. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/batch.py +0 -0
  103. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/billing.py +0 -0
  104. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/browse.py +0 -0
  105. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/client_app.py +0 -0
  106. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/config.py +0 -0
  107. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/connector.py +0 -0
  108. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/context.py +0 -0
  109. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/dashboard.py +0 -0
  110. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/data_app.py +0 -0
  111. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/dataset.py +0 -0
  112. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/external_key.py +0 -0
  113. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/folder.py +0 -0
  114. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/notification.py +0 -0
  115. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/parameter.py +0 -0
  116. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/project.py +0 -0
  117. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/registry.py +0 -0
  118. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/report.py +0 -0
  119. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/schedule.py +0 -0
  120. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/schema.py +0 -0
  121. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/skill.py +0 -0
  122. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/snippet.py +0 -0
  123. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/support.py +0 -0
  124. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/template.py +0 -0
  125. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/trash.py +0 -0
  126. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/upgrade.py +0 -0
  127. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/user.py +0 -0
  128. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/view.py +0 -0
  129. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/view_ops.py +0 -0
  130. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/webhook.py +0 -0
  131. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/commands/workspace.py +0 -0
  132. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/context/__init__.py +0 -0
  133. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/context/endpoint.py +0 -0
  134. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/context/profiles.py +0 -0
  135. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/contracts/__init__.py +0 -0
  136. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/contracts/auth.py +0 -0
  137. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/errors/__init__.py +0 -0
  138. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/errors/envelope.py +0 -0
  139. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/manifest/__init__.py +0 -0
  140. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/messages/__init__.py +0 -0
  141. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/output/__init__.py +0 -0
  142. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/output/envelope.py +0 -0
  143. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/output/normalize.py +0 -0
  144. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/output/policy.py +0 -0
  145. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/output/progress.py +0 -0
  146. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/output/render.py +0 -0
  147. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/py.typed +0 -0
  148. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/__init__.py +0 -0
  149. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/confirm.py +0 -0
  150. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/dryrun.py +0 -0
  151. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/options.py +0 -0
  152. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/parents.py +0 -0
  153. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/runlog.py +0 -0
  154. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/session.py +0 -0
  155. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/updates.py +0 -0
  156. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/runtime/validate.py +0 -0
  157. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/__init__.py +0 -0
  158. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/argspec.py +0 -0
  159. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/coerce.py +0 -0
  160. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/command_contract.py +0 -0
  161. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/conditions.py +0 -0
  162. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/dispatch.py +0 -0
  163. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/factory.py +0 -0
  164. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/input_fields.py +0 -0
  165. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/mapping.py +0 -0
  166. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/openapi_types.py +0 -0
  167. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/positionals.py +0 -0
  168. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/protocol.py +0 -0
  169. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/testing.py +0 -0
  170. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/services/type_system.py +0 -0
  171. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/skills/__init__.py +0 -0
  172. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/skills/steering.py +0 -0
  173. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/mammoth_cli/testing.py +0 -0
  174. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/activity.yaml +0 -0
  175. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/addon.yaml +0 -0
  176. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/agent.yaml +0 -0
  177. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/ai.yaml +0 -0
  178. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/annotation.yaml +0 -0
  179. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/auth.yaml +0 -0
  180. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/automation.yaml +0 -0
  181. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/batch.yaml +0 -0
  182. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/billing.yaml +0 -0
  183. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/browse.yaml +0 -0
  184. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/capability.yaml +0 -0
  185. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/client-app.yaml +0 -0
  186. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/completion.yaml +0 -0
  187. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/config.yaml +0 -0
  188. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/connector.yaml +0 -0
  189. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/context.yaml +0 -0
  190. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/dashboard.yaml +0 -0
  191. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/data-app.yaml +0 -0
  192. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/dataset.yaml +0 -0
  193. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/doctor.yaml +0 -0
  194. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/external-key.yaml +0 -0
  195. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/file.yaml +0 -0
  196. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/folder.yaml +0 -0
  197. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/job.yaml +0 -0
  198. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/log.yaml +0 -0
  199. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/notification.yaml +0 -0
  200. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/parameter.yaml +0 -0
  201. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/project.yaml +0 -0
  202. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/report.yaml +0 -0
  203. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/schedule.yaml +0 -0
  204. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/schema.yaml +0 -0
  205. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/skill.yaml +0 -0
  206. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/snippet.yaml +0 -0
  207. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/support.yaml +0 -0
  208. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/template.yaml +0 -0
  209. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/trash.yaml +0 -0
  210. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/upgrade.yaml +0 -0
  211. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/user.yaml +0 -0
  212. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/version.yaml +0 -0
  213. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/view.yaml +0 -0
  214. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/webhook.yaml +0 -0
  215. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/workflow.yaml +0 -0
  216. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/commands/workspace.yaml +0 -0
  217. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/openapi-operations.yaml +0 -0
  218. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/schema-v1.json +0 -0
  219. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/sdk-catalog.source.yaml +0 -0
  220. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/manifests/sdk-methods.yaml +0 -0
  221. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/spec/openapi/metadata.json +0 -0
  222. {mammoth_cli-2.0.30 → mammoth_cli-2.0.32}/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.30
3
+ Version: 2.0.32
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.13
20
+ Requires-Dist: mammoth-io<0.8,>=0.7.14
21
21
  Requires-Dist: platformdirs<5,>=4.10
22
22
  Requires-Dist: pydantic<3,>=2.13
23
23
  Requires-Dist: pyyaml<7,>=6
@@ -30,7 +30,7 @@ Description-Content-Type: text/markdown
30
30
 
31
31
  Use [Mammoth Analytics](https://mammoth.io) from a terminal. The `mammoth`
32
32
  command covers data import and export, transformations, project organization,
33
- automation, and administration. Its interface is designed to be readable at a
33
+ automation, and administration. Its interface is readable at a
34
34
  shell and predictable in scripts and agent runs.
35
35
 
36
36
  [![PyPI](https://img.shields.io/pypi/v/mammoth-cli)](https://pypi.org/project/mammoth-cli/)
@@ -38,14 +38,14 @@ shell and predictable in scripts and agent runs.
38
38
  [![License](https://img.shields.io/pypi/l/mammoth-cli)](https://github.com/EdgeMetric/mammothsdk/blob/main/mammoth-cli/LICENSE)
39
39
 
40
40
  - **Human-friendly by default.** In a terminal, commands print a readable table.
41
- - **Agent-native.** When output is piped, you get a stable JSON envelope with a
41
+ - **Agent-native.** When you pipe the output, you get a stable JSON envelope with a
42
42
  documented schema, exit codes, and error codes — no flags required.
43
43
  - **Guarded mutations.** Commands expose their confirmation policy; promptless
44
44
  destructive operations require an explicit `--yes`.
45
45
  - **Discoverable.** `mammoth capability list` and `mammoth schema get` describe
46
46
  every command, so an agent can learn the surface at runtime.
47
47
 
48
- The CLI is built on the public [`mammoth-io`](https://pypi.org/project/mammoth-io/)
48
+ The CLI uses the public [`mammoth-io`](https://pypi.org/project/mammoth-io/)
49
49
  SDK. It adds no second HTTP client and calls no private SDK members.
50
50
 
51
51
  See the [capability matrix](https://github.com/EdgeMetric/mammothsdk/blob/main/mammoth-cli/docs/release-capability-matrix.md)
@@ -103,8 +103,7 @@ history, or command arguments. On POSIX, put the required JSON credentials in a
103
103
  private owner-only (0600) file outside the repository and pass its path to:
104
104
 
105
105
  ```bash
106
- mammoth auth login --input /private/path/credentials.json --storage file \
107
-
106
+ mammoth auth login --input /private/path/credentials.json --storage file
108
107
  ```
109
108
 
110
109
  On Windows, use the approved OS keyring instead; do not use a file fallback
@@ -136,8 +135,7 @@ To pin it for a whole session, `export MAMMOTH_OUTPUT=json MAMMOTH_NO_INPUT=1`
136
135
  the private, permission-checked file described above:
137
136
 
138
137
  ```bash
139
- mammoth auth login --input /private/path/credentials.json --storage file \
140
-
138
+ mammoth auth login --input /private/path/credentials.json --storage file
141
139
  ```
142
140
 
143
141
  Feed multi-field requests as one document instead of many flags:
@@ -210,9 +208,10 @@ Use Mammoth Analytics only through the `mammoth` CLI in bash; run
210
208
  1. If `mammoth --version` fails, install, then re-check (new shell if needed):
211
209
  curl -fsSL https://raw.githubusercontent.com/EdgeMetric/mammothsdk/main/mammoth-cli/installers/mammoth-install.sh | bash
212
210
  2. Run `mammoth auth status`. If it shows no credentials, print exactly this
213
- and wait until I say done: "In the Mammoth web app open account settings,
214
- create an API key (key + secret) and note your workspace id, then run in
215
- your own terminal: mammoth auth login" — never ask for, read, or pass a key
211
+ and wait until I say done: "In the Mammoth web app open Workspace settings
212
+ → API Tokens → Create token, copy the key and the secret (shown once), and
213
+ note the workspace id (the number after /workspaces/ in the address bar),
214
+ then run in your own terminal: mammoth auth login" — never ask for, read, or pass a key
216
215
  or secret yourself, and never run auth login.
217
216
  3. Require `mammoth doctor` to pass, then run `mammoth skill show` and
218
217
  follow the guide it prints.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Use [Mammoth Analytics](https://mammoth.io) from a terminal. The `mammoth`
4
4
  command covers data import and export, transformations, project organization,
5
- automation, and administration. Its interface is designed to be readable at a
5
+ automation, and administration. Its interface is readable at a
6
6
  shell and predictable in scripts and agent runs.
7
7
 
8
8
  [![PyPI](https://img.shields.io/pypi/v/mammoth-cli)](https://pypi.org/project/mammoth-cli/)
@@ -10,14 +10,14 @@ shell and predictable in scripts and agent runs.
10
10
  [![License](https://img.shields.io/pypi/l/mammoth-cli)](https://github.com/EdgeMetric/mammothsdk/blob/main/mammoth-cli/LICENSE)
11
11
 
12
12
  - **Human-friendly by default.** In a terminal, commands print a readable table.
13
- - **Agent-native.** When output is piped, you get a stable JSON envelope with a
13
+ - **Agent-native.** When you pipe the output, you get a stable JSON envelope with a
14
14
  documented schema, exit codes, and error codes — no flags required.
15
15
  - **Guarded mutations.** Commands expose their confirmation policy; promptless
16
16
  destructive operations require an explicit `--yes`.
17
17
  - **Discoverable.** `mammoth capability list` and `mammoth schema get` describe
18
18
  every command, so an agent can learn the surface at runtime.
19
19
 
20
- The CLI is built on the public [`mammoth-io`](https://pypi.org/project/mammoth-io/)
20
+ The CLI uses the public [`mammoth-io`](https://pypi.org/project/mammoth-io/)
21
21
  SDK. It adds no second HTTP client and calls no private SDK members.
22
22
 
23
23
  See the [capability matrix](https://github.com/EdgeMetric/mammothsdk/blob/main/mammoth-cli/docs/release-capability-matrix.md)
@@ -75,8 +75,7 @@ history, or command arguments. On POSIX, put the required JSON credentials in a
75
75
  private owner-only (0600) file outside the repository and pass its path to:
76
76
 
77
77
  ```bash
78
- mammoth auth login --input /private/path/credentials.json --storage file \
79
-
78
+ mammoth auth login --input /private/path/credentials.json --storage file
80
79
  ```
81
80
 
82
81
  On Windows, use the approved OS keyring instead; do not use a file fallback
@@ -108,8 +107,7 @@ To pin it for a whole session, `export MAMMOTH_OUTPUT=json MAMMOTH_NO_INPUT=1`
108
107
  the private, permission-checked file described above:
109
108
 
110
109
  ```bash
111
- mammoth auth login --input /private/path/credentials.json --storage file \
112
-
110
+ mammoth auth login --input /private/path/credentials.json --storage file
113
111
  ```
114
112
 
115
113
  Feed multi-field requests as one document instead of many flags:
@@ -182,9 +180,10 @@ Use Mammoth Analytics only through the `mammoth` CLI in bash; run
182
180
  1. If `mammoth --version` fails, install, then re-check (new shell if needed):
183
181
  curl -fsSL https://raw.githubusercontent.com/EdgeMetric/mammothsdk/main/mammoth-cli/installers/mammoth-install.sh | bash
184
182
  2. Run `mammoth auth status`. If it shows no credentials, print exactly this
185
- and wait until I say done: "In the Mammoth web app open account settings,
186
- create an API key (key + secret) and note your workspace id, then run in
187
- your own terminal: mammoth auth login" — never ask for, read, or pass a key
183
+ and wait until I say done: "In the Mammoth web app open Workspace settings
184
+ → API Tokens → Create token, copy the key and the secret (shown once), and
185
+ note the workspace id (the number after /workspaces/ in the address bar),
186
+ then run in your own terminal: mammoth auth login" — never ask for, read, or pass a key
188
187
  or secret yourself, and never run auth login.
189
188
  3. Require `mammoth doctor` to pass, then run `mammoth skill show` and
190
189
  follow the guide it prints.
@@ -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.30"
9
+ __version__ = "2.0.32"
10
10
 
11
11
  # The versioned machine output envelope contract.
12
12
  SCHEMA_VERSION = 1
@@ -330,6 +330,13 @@ class _LeafGroup(TyperGroup):
330
330
  class _EnvelopeGroup(TyperGroup):
331
331
  """Root group that renders Click usage errors as the machine error envelope.
332
332
 
333
+ It also materialises top-level command groups lazily (see
334
+ :func:`_load_top_level_group`): ``list_commands`` and ``get_command`` know
335
+ every group by name from the manifest, but a group's Click tree is only
336
+ built when it is invoked, completed or listed in ``--help``. Reading
337
+ ``commands`` directly materialises them all, so tools that walk the tree
338
+ still see the full surface.
339
+
333
340
  Click's standalone error handling prints a human ``Usage: ... Error: ...``
334
341
  message and exits, even under ``--output json``: an agent driving the CLI
335
342
  then receives un-parseable prose (or, for a leaf that also parents
@@ -345,6 +352,28 @@ class _EnvelopeGroup(TyperGroup):
345
352
  on.
346
353
  """
347
354
 
355
+ @property # type: ignore[override]
356
+ def commands(self) -> dict[str, Any]:
357
+ loaded: dict[str, Any] = self.__dict__.setdefault("_eager_commands", {})
358
+ for name in _LAZY_GROUP_NAMES:
359
+ if name not in loaded:
360
+ loaded[name] = _load_top_level_group(name)
361
+ return loaded
362
+
363
+ @commands.setter
364
+ def commands(self, value: Any) -> None:
365
+ self.__dict__["_eager_commands"] = dict(value or {})
366
+
367
+ def list_commands(self, ctx: Any) -> list[str]:
368
+ eager = self.__dict__.get("_eager_commands", {})
369
+ return [*eager, *(name for name in _LAZY_GROUP_NAMES if name not in eager)]
370
+
371
+ def get_command(self, ctx: Any, cmd_name: str) -> Any:
372
+ eager: dict[str, Any] = self.__dict__.setdefault("_eager_commands", {})
373
+ if cmd_name not in eager and cmd_name in _LAZY_GROUP_NAMES:
374
+ eager[cmd_name] = _load_top_level_group(cmd_name)
375
+ return eager.get(cmd_name)
376
+
348
377
  def main(self, *args: Any, **kwargs: Any) -> Any:
349
378
  if not kwargs.get("standalone_mode", True):
350
379
  return super().main(*args, **kwargs)
@@ -888,68 +917,55 @@ def _short_type(type_name: str) -> str:
888
917
  return " | ".join(part.strip().rsplit(".", 1)[-1] for part in text.split("|"))[:40]
889
918
 
890
919
 
891
- def build_app() -> typer.Typer:
892
- """Construct the full Typer command tree from the command manifests."""
893
- root = typer.Typer(
894
- name="mammoth",
895
- help=(
896
- "Command-line interface for the Mammoth Analytics platform.\n\n"
897
- "Start with 'mammoth doctor' to check access, 'mammoth schema find QUERY' "
898
- "to locate a command, and 'mammoth schema get COMMAND_ID' for its full input schema."
899
- ),
920
+ def _command_records() -> list[dict[str, Any]]:
921
+ return [r for r in load_commands() if r.get("disposition") != "alias"]
922
+
923
+
924
+ @cache
925
+ def _command_tree() -> tuple[dict[tuple[str, ...], str], frozenset[tuple[str, ...]]]:
926
+ """Map every command path to its id, and name the container nodes.
927
+
928
+ A "container command" sits at a node that also has deeper subcommands
929
+ (e.g. ``dataset file-settings``, which also has ``... undo`` / ``... update``).
930
+ """
931
+ path_to_command = {
932
+ tuple(r["command_path"].split()): r["command_id"] for r in _command_records()
933
+ }
934
+ prefixes: set[tuple[str, ...]] = set()
935
+ for tokens in path_to_command:
936
+ for depth in range(1, len(tokens)):
937
+ prefixes.add(tokens[:depth])
938
+ return path_to_command, frozenset(prefixes & path_to_command.keys())
939
+
940
+
941
+ def _group_typer(tokens: tuple[str, ...], command_id: str | None) -> typer.Typer:
942
+ if command_id is not None:
943
+ # This node is both a group and an invocable command.
944
+ sub = typer.Typer(
945
+ cls=_LeafGroup,
946
+ no_args_is_help=False,
947
+ invoke_without_command=True,
948
+ context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
949
+ )
950
+ sub.callback()(_build_leaf(command_id, is_group_callback=True))
951
+ return sub
952
+ return typer.Typer(
953
+ help=_GROUP_DESCRIPTIONS.get(tokens[0], f"Commands for {' '.join(tokens)}."),
900
954
  no_args_is_help=True,
901
- add_completion=True,
902
- cls=_EnvelopeGroup,
903
955
  context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
904
956
  )
905
957
 
906
- @root.callback()
907
- def _root(
908
- version: bool = typer.Option(
909
- False, "--version", callback=_version_callback, is_eager=True, help="Show version."
910
- ),
911
- ) -> None:
912
- """Root callback holding eager global options."""
913
958
 
914
- records = [r for r in load_commands() if r.get("disposition") != "alias"]
915
- path_to_command: dict[tuple[str, ...], str] = {
916
- tuple(r["command_path"].split()): r["command_id"] for r in records
917
- }
918
- all_paths = set(path_to_command)
919
- # A "container command" sits at a node that also has deeper subcommands
920
- # (e.g. `dataset file-settings`, which also has `... undo` / `... update`).
921
- containers = {
922
- tokens
923
- for tokens in all_paths
924
- if any(other != tokens and other[: len(tokens)] == tokens for other in all_paths)
925
- }
926
-
927
- groups: dict[tuple[str, ...], typer.Typer] = {(): root}
928
-
929
- def _make_group(tokens: tuple[str, ...]) -> typer.Typer:
930
- command_id = path_to_command.get(tokens)
931
- if command_id is not None:
932
- # This node is both a group and an invocable command.
933
- sub = typer.Typer(
934
- cls=_LeafGroup,
935
- no_args_is_help=False,
936
- invoke_without_command=True,
937
- context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
938
- )
939
- sub.callback()(_build_leaf(command_id, is_group_callback=True))
940
- else:
941
- sub = typer.Typer(
942
- help=_GROUP_DESCRIPTIONS.get(tokens[0], f"Commands for {' '.join(tokens)}."),
943
- no_args_is_help=True,
944
- context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
945
- )
946
- return sub
959
+ def _populate(base: tuple[str, ...], group: typer.Typer) -> None:
960
+ """Register every command below ``base`` (exclusive) on ``group``."""
961
+ path_to_command, containers = _command_tree()
962
+ groups: dict[tuple[str, ...], typer.Typer] = {base: group}
947
963
 
948
964
  def _group_for(tokens: tuple[str, ...]) -> typer.Typer:
949
965
  if tokens in groups:
950
966
  return groups[tokens]
951
967
  parent = _group_for(tokens[:-1])
952
- sub = _make_group(tokens)
968
+ sub = _group_typer(tokens, path_to_command.get(tokens))
953
969
  top_level = tokens[0]
954
970
  parent.add_typer(
955
971
  sub,
@@ -960,15 +976,16 @@ def build_app() -> typer.Typer:
960
976
  groups[tokens] = sub
961
977
  return sub
962
978
 
979
+ below = {t: c for t, c in path_to_command.items() if t[: len(base)] == base and t != base}
963
980
  # Ensure every container group exists (parents before children).
964
- for tokens in sorted(containers, key=len):
981
+ for tokens in sorted((t for t in below if t in containers), key=len):
965
982
  _group_for(tokens)
966
983
 
967
984
  # Register every non-container command as a leaf under its parent group.
968
985
  # A command_id with a bespoke, fully-typed callback overrides the generic
969
986
  # leaf at the same registered name and path; the manifest-driven surface
970
987
  # is otherwise unchanged.
971
- for tokens, command_id in sorted(path_to_command.items()):
988
+ for tokens, command_id in sorted(below.items()):
972
989
  if tokens in containers:
973
990
  continue
974
991
  record = command_by_id(command_id)
@@ -980,11 +997,88 @@ def build_app() -> typer.Typer:
980
997
  context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
981
998
  )(callback)
982
999
 
1000
+
1001
+ @cache
1002
+ def _top_level_typer(name: str) -> typer.Typer:
1003
+ """Build (once) the Typer sub-app for one top-level command group."""
1004
+ path_to_command, _ = _command_tree()
1005
+ sub = _group_typer((name,), path_to_command.get((name,)))
1006
+ _populate((name,), sub)
1007
+ return sub
1008
+
1009
+
1010
+ # Top-level groups are converted to Click on first use. Building the leaf
1011
+ # callbacks and ``--help`` text for all ~550 commands, then letting Typer
1012
+ # convert every one of them, used to cost most of the CLI's start-up time on
1013
+ # every invocation; a run touches one group.
1014
+ _LAZY_GROUP_NAMES: list[str] = []
1015
+ _LAZY_SETTINGS: dict[str, Any] = {}
1016
+
1017
+
1018
+ def _load_top_level_group(name: str) -> Any:
1019
+ from typer.models import TyperInfo
1020
+
1021
+ info = TyperInfo(
1022
+ _top_level_typer(name),
1023
+ name=name,
1024
+ help=_GROUP_DESCRIPTIONS.get(name, f"Commands for {name}."),
1025
+ rich_help_panel=_ROOT_HELP_PANELS.get(name),
1026
+ )
1027
+ return typer.main.get_group_from_info(info, **_LAZY_SETTINGS)
1028
+
1029
+
1030
+ def build_app() -> typer.Typer:
1031
+ """Construct the Typer command tree from the command manifests.
1032
+
1033
+ Top-level leaves (``doctor``, ``version``, ...) are registered here; every
1034
+ top-level group is materialised by :class:`_EnvelopeGroup` on demand.
1035
+ """
1036
+ root = typer.Typer(
1037
+ name="mammoth",
1038
+ help=(
1039
+ "Command-line interface for the Mammoth Analytics platform.\n\n"
1040
+ "Start with 'mammoth doctor' to check access, 'mammoth schema find QUERY' "
1041
+ "to locate a command, and 'mammoth schema get COMMAND_ID' for its full input schema."
1042
+ ),
1043
+ no_args_is_help=True,
1044
+ add_completion=True,
1045
+ cls=_EnvelopeGroup,
1046
+ context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
1047
+ )
1048
+
1049
+ @root.callback()
1050
+ def _root(
1051
+ version: bool = typer.Option(
1052
+ False, "--version", callback=_version_callback, is_eager=True, help="Show version."
1053
+ ),
1054
+ ) -> None:
1055
+ """Root callback holding eager global options."""
1056
+
1057
+ path_to_command, containers = _command_tree()
1058
+ top_names = sorted({tokens[0] for tokens in path_to_command})
1059
+ lazy: list[str] = []
1060
+ for name in top_names:
1061
+ if (name,) in containers or (name,) not in path_to_command:
1062
+ lazy.append(name)
1063
+ continue
1064
+ command_id = path_to_command[(name,)]
1065
+ root.command(
1066
+ name=name,
1067
+ help=_command_help(command_id, command_by_id(command_id)),
1068
+ rich_help_panel=_ROOT_HELP_PANELS.get(name),
1069
+ context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
1070
+ )(BESPOKE.get(command_id) or _build_leaf(command_id))
1071
+ _LAZY_GROUP_NAMES[:] = lazy
1072
+ _LAZY_SETTINGS.update(
1073
+ pretty_exceptions_short=root.pretty_exceptions_short,
1074
+ rich_markup_mode=root.rich_markup_mode,
1075
+ suggest_commands=root.suggest_commands,
1076
+ )
983
1077
  return root
984
1078
 
985
1079
 
986
1080
  def registered_command_paths() -> set[str]:
987
- """Return every registered command path by walking the built Typer tree.
1081
+ """Return every registered command path by walking the built Typer trees.
988
1082
 
989
1083
  Container commands (a node that is both a group and invocable) are counted
990
1084
  by their own path as well as their subcommands.
@@ -998,14 +1092,20 @@ def registered_command_paths() -> set[str]:
998
1092
  paths.add(" ".join((*prefix, name)))
999
1093
  for group in instance.registered_groups:
1000
1094
  sub = group.typer_instance
1001
- if sub is None or not group.name:
1095
+ name = group.name
1096
+ if sub is None or not name:
1002
1097
  continue
1003
- node = (*prefix, group.name)
1004
- if getattr(sub.info, "invoke_without_command", False) and sub.registered_callback:
1098
+ node = (*prefix, name)
1099
+ if sub.registered_callback is not None:
1005
1100
  paths.add(" ".join(node))
1006
1101
  walk(sub, node)
1007
1102
 
1008
- walk(build_app(), ())
1103
+ walk(app, ())
1104
+ for name in _LAZY_GROUP_NAMES:
1105
+ sub = _top_level_typer(name)
1106
+ if sub.registered_callback is not None:
1107
+ paths.add(name)
1108
+ walk(sub, (name,))
1009
1109
  return paths
1010
1110
 
1011
1111
 
@@ -1020,7 +1120,9 @@ def _root_click_command() -> Any:
1020
1120
  the tree is fixed for the process lifetime (:data:`app` is built once at
1021
1121
  import time).
1022
1122
  """
1023
- return typer.main.get_command(app)
1123
+ root: Any = typer.main.get_command(app)
1124
+ root.commands # noqa: B018 -- materialise every lazy top-level group
1125
+ return root
1024
1126
 
1025
1127
 
1026
1128
  def command_option_names(command_path: str) -> set[str]:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: mammoth-cli
3
- version: 2.0.30
3
+ version: 2.0.32
4
4
  description: "Use Mammoth Analytics from a terminal: install or authenticate the CLI, discover its live command contract, and safely manage projects, data, views, pipelines, dashboards, exports, and handoffs."
5
5
  ---
6
6
 
@@ -8,7 +8,7 @@ description: "Use Mammoth Analytics from a terminal: install or authenticate the
8
8
 
9
9
  Use this skill for Mammoth shell work, not for Python SDK integration. The
10
10
  CLI is the contract: it validates every request locally, returns one JSON
11
- envelope, and never needs a flag to do so when its output is piped.
11
+ envelope, and needs no flag for that when you pipe its output.
12
12
 
13
13
  ## Start
14
14
 
@@ -21,8 +21,9 @@ mammoth project ensure 'PROJECT NAME' # get-or-create; becomes the active proj
21
21
  command anyway. Production is the `app` endpoint; use `release` only when the
22
22
  task names it, and check `meta.profile`/`auth status` `endpoint` match the
23
23
  intended environment before doing anything. If no profile has credentials,
24
- tell the operator the exact `mammoth auth login --profile PROFILE` command to
25
- run in their own terminal and wait; never ask for a key or secret in chat,
24
+ tell the operator to run `mammoth auth login` in their own terminal (add
25
+ `--profile NAME` only for a profile other than `default`; [auth](references/auth.md)
26
+ says where the key and secret come from) and wait; never ask for a key or secret in chat,
26
27
  never read one from a file or environment variable, never run `auth login`
27
28
  yourself. If any envelope carries `meta.update_available`, run its `command`
28
29
  before the next step.
@@ -62,7 +63,8 @@ before the next step.
62
63
  returns, never backend aliases.
63
64
  - `--dry-run` on any API-backed command resolves everything and reports the
64
65
  request instead of sending it; use it before a write you are not sure of.
65
- - Destructive commands need `--yes --confirm ID`. Preserve requested
66
+ - Deletes need `--yes`; high-impact ones (`project delete`, access changes)
67
+ also need `--confirm ID`, and `schema get` shows which. Preserve requested
66
68
  deliverables; cleanup is exact-ID authorized and
67
69
  never means delete-all-owned-resources: delete only ids this run created,
68
70
  one per call, and read back that they are gone.
@@ -17,8 +17,12 @@ An agent never receives the key or secret. When `auth status` reports a
17
17
  missing profile or `has_credentials=false`, stop and hand the login to the
18
18
  human operator:
19
19
 
20
- 1. Tell the operator the exact command to run in **their own** terminal. For
21
- production it is just:
20
+ 1. Tell the operator where the credentials come from: in the Mammoth web app,
21
+ **Workspace settings → API Tokens → Create token** gives a key and a secret;
22
+ the web app shows the secret only once (on an existing token, **Generate new
23
+ secret** replaces it). The workspace id is the number after `/workspaces/`
24
+ in the web app's address bar. Then give the exact command to run in
25
+ **their own** terminal. For production it is:
22
26
 
23
27
  ```bash
24
28
  mammoth auth login
@@ -30,6 +34,10 @@ human operator:
30
34
  hidden input, then the workspace id, so no secret enters chat, argv, or
31
35
  history. Credentials are per environment: a release key never
32
36
  authenticates on `app`.
37
+ On macOS the Keychain may show a dialog about `mammoth-cli`; tell the
38
+ operator to choose **Always Allow**. If the keychain cannot be used (for
39
+ example over SSH), login falls back to the owner-only file, or the operator
40
+ runs `mammoth auth login --storage file`.
33
41
  2. Wait for the operator to confirm, then re-run
34
42
  `mammoth auth status --profile PROFILE` and
35
43
  `mammoth doctor --profile PROFILE`.
@@ -33,7 +33,7 @@ Ran once: `automation.create`, `automation.delete`, `automation.list`
33
33
 
34
34
  | Command | State | Note |
35
35
  |---|---|---|
36
- | `automation.get` | observed blocker | backend_error: SUSPECTED DEFECT: automation.get on the id just returned by automation.create (id=1) returns HTTP 500 empty body every time (3 retries, several seconds apart), not e |
36
+ | `automation.get` | observed blocker | backend_error: SUSPECTED DEFECT: automation.get on the id that automation.create returned (id=1) returns HTTP 500 empty body every time (3 retries, several seconds apart), not even |
37
37
  | `automation.update` | observed blocker | cli_error: CLI rejected 'name' field; error message says accepted field is 'patch' (nested patch object), not documented in agent_example |
38
38
 
39
39
  ## `batch`
@@ -30,7 +30,7 @@ Example: `mammoth automation get 123`. Placeholders are illustrative; resolve ID
30
30
 
31
31
  Result: `AutomationGetResult`; mutation `read`, confirmation `none`, wait policy `not_async`.
32
32
 
33
- Status on release: observed blocker — backend_error: SUSPECTED DEFECT: automation.get on the id just returned by automation.create (id=1) returns HTTP 500 empty body every time (3 retries, several seconds apart), not e. Re-check before relying on it.
33
+ Status on release: observed blocker — backend_error: SUSPECTED DEFECT: automation.get on the id that automation.create returned (id=1) returns HTTP 500 empty body every time (3 retries, several seconds apart), not even. Re-check before relying on it.
34
34
 
35
35
  ### `automation.list`
36
36
 
@@ -11,15 +11,18 @@ operator logs in from their own terminal as described in [auth](auth.md).
11
11
 
12
12
  ## Required record
13
13
 
14
- Include `format: "mammoth-agent-handoff"`, `format_version`, producer
15
- `cli_version`, `sdk_version`, `contract_schema_version`, and `skill_version`
16
- (the `version:` field in this skill's `SKILL.md` frontmatter; `mammoth
17
- --version` gives the other two);
18
- the intent and acceptance criteria; authorized `profile` name and exact
19
- workspace/project scope; observed resources with dataset/view parents and
20
- dependencies; last verified state and hashes of bounded secret-free evidence;
21
- pending known jobs and `unknown_outcomes`; completed actions; remaining
22
- objectives; and a cleanup owner plus dependency order.
14
+ Include `format: "mammoth-agent-handoff"`, `format_version`, and the producer
15
+ versions: `cli_version`, `sdk_version`, `contract_schema_version`, and
16
+ `skill_version`. `skill_version` is the `version:` field in this skill's
17
+ `SKILL.md` frontmatter; `mammoth --version` gives the other two. Also include
18
+ the intent and acceptance criteria and the authorized `profile` name and exact
19
+ workspace/project scope. Then add:
20
+
21
+ - observed resources with dataset/view parents and dependencies;
22
+ - the last verified state and hashes of bounded secret-free evidence;
23
+ - pending known jobs and `unknown_outcomes`;
24
+ - completed actions and remaining objectives;
25
+ - a cleanup owner plus dependency order.
23
26
 
24
27
  Never include API keys, API secrets, tokens, headers, credentials files, raw
25
28
  secret-bearing input, or unredacted response bodies. IDs and display names are
@@ -5,7 +5,11 @@ A command's `wait_policy` (visible via `mammoth schema get`) determines what
5
5
  happens with the job, so you do not have to guess:
6
6
 
7
7
  - `always_wait` and `start_or_wait` commands resolve the job for you and return
8
- the final result. You do NOT wait manually.
8
+ the final result. You do NOT wait manually. A `view transform` success
9
+ envelope says `"status": "done"` and `"pipeline_state": "ready"`: the
10
+ pipeline has finished, so do not poll its `future_id`; verify the values
11
+ with `view data get`. (With SDK ≤ 0.7.13 the same envelope said
12
+ `"processing"`; it meant the same thing.)
9
13
  - Only a `returns_job` command normally needs you to wait on the job id
10
14
  explicitly:
11
15
  ```bash