mammoth-cli 2.2.8__tar.gz → 2.2.10__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.
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/PKG-INFO +2 -2
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/__init__.py +1 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/app.py +6 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +9 -10
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +1 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +1 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +2 -2
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +2 -2
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +4 -4
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +2 -2
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/activity.py +8 -3
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/calc.py +37 -10
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/client_app.py +3 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/dashboard.py +13 -7
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/dataset.py +108 -15
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/doctor.py +2 -3
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/file.py +12 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/folder.py +22 -32
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/project.py +36 -11
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/schema.py +3 -2
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/view.py +124 -22
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/view_ops.py +16 -3
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/view_profile.py +19 -8
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/workflow.py +16 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/workspace.py +7 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/embed.py +56 -25
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/errors/envelope.py +1 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/output/normalize.py +51 -31
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/dryrun.py +33 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/dryrun_targets.py +46 -5
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/embedded.py +15 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/executor.py +26 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/input_loader.py +16 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/intent_only.py +2 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/parents.py +24 -3
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/runlog.py +5 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/dashboard_review.py +4 -3
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/data_profile.py +2 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/data_quality.py +12 -6
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/input_fields.py +8 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/listing.py +5 -3
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/mapping.py +2 -2
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/sdk_service.py +61 -20
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/text_dates.py +4 -4
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/pyproject.toml +2 -2
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/dashboard.yaml +1 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/dataset.yaml +1 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/project.yaml +1 -1
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/workflow.yaml +3 -3
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/workspace.yaml +3 -3
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/sdk-catalog.source.yaml +66 -64
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/sdk-methods.yaml +14 -2
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/.gitignore +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/LICENSE +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/README.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/__main__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/about-mammoth.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/calc.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-qa.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-template.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/link.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view-transform.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/database-import.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/scheduling.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/addon.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/agent.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/ai.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/annotation.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/auth.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/automation.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/batch.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/billing.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/browse.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/capability.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/completion.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/config.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/connector.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/context.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/data_app.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/external_key.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/job.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/link.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/notification.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/parameter.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/registry.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/report.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/schedule.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/skill.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/snippet.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/support.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/template.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/trash.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/upgrade.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/user.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/commands/webhook.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/context/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/context/credentials.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/context/endpoint.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/context/profiles.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/context/resolver.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/contracts/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/contracts/auth.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/errors/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/manifest/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/manifest/loader.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/messages/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/output/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/output/envelope.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/output/policy.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/output/progress.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/output/render.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/py.typed +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/confirm.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/dataset_health.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/invocation.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/new_data.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/options.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/session.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/state.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/strict.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/updates.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/validate.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/runtime/verify.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/argspec.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/board_values.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/coerce.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/command_contract.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/conditions.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/dashboard_filters.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/dashboard_pages.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/dispatch.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/factory.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/openapi_types.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/positionals.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/protocol.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/read_queries.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/stored_stats.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/testing.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/type_system.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/services/write_impact.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/skills/__init__.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/skills/installer.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/skills/steering.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/mammoth_cli/testing.py +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/activity.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/addon.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/agent.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/ai.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/annotation.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/auth.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/automation.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/batch.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/billing.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/browse.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/calc.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/capability.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/client-app.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/completion.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/config.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/connector.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/context.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/data-app.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/doctor.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/external-key.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/file.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/folder.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/job.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/link.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/log.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/notification.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/parameter.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/report.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/schedule.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/schema.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/skill.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/snippet.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/support.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/template.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/trash.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/upgrade.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/user.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/version.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/view.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/commands/webhook.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/edits-target.source.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/openapi-operations.yaml +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/manifests/schema-v1.json +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/openapi/metadata.json +0 -0
- {mammoth_cli-2.2.8 → mammoth_cli-2.2.10}/spec/openapi/openapi.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mammoth-cli
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.10
|
|
4
4
|
Summary: Command-line interface for the Mammoth Analytics platform
|
|
5
5
|
Project-URL: homepage, https://mammoth.io
|
|
6
6
|
Project-URL: repository, https://github.com/EdgeMetric/mammothsdk
|
|
@@ -17,7 +17,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
17
17
|
Requires-Python: <3.15,>=3.12
|
|
18
18
|
Requires-Dist: jsonschema>=4.20
|
|
19
19
|
Requires-Dist: keyring<26,>=25.7
|
|
20
|
-
Requires-Dist: mammoth-io<0.9,>=0.8.
|
|
20
|
+
Requires-Dist: mammoth-io<0.9,>=0.8.11
|
|
21
21
|
Requires-Dist: platformdirs<5,>=4.10
|
|
22
22
|
Requires-Dist: pydantic<3,>=2.12.5
|
|
23
23
|
Requires-Dist: pyyaml<7,>=6
|
|
@@ -457,6 +457,12 @@ class _EnvelopeGroup(TyperGroup):
|
|
|
457
457
|
# classify an argv flag that is not a known global option;
|
|
458
458
|
# a known option's malformed value remains usage_error.
|
|
459
459
|
known, _valued = _global_option_flags()
|
|
460
|
+
command = getattr(getattr(error, "ctx", None), "command", None)
|
|
461
|
+
known = known | {
|
|
462
|
+
flag
|
|
463
|
+
for param in getattr(command, "params", [])
|
|
464
|
+
for flag in (*param.opts, *param.secondary_opts)
|
|
465
|
+
}
|
|
460
466
|
option = next(
|
|
461
467
|
(
|
|
462
468
|
token.split("=", 1)[0]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# What is proven on release
|
|
2
2
|
|
|
3
3
|
Generated from `docs/release-capability-matrix.json`; do not edit by hand.
|
|
4
|
-
The CLI publishes 633 commands.
|
|
4
|
+
The CLI publishes 633 commands. 504 of them bind one of the 545 API operations in the matrix; the remainder are local commands (`schema`, `auth`, `doctor`, `log`, ...) or typed variants that share an operation (`view transform *` commands submit through `view.task.add`, except `rename-columns` and `sort`, which set view display properties through `view.update`). 262 bound commands ran once successfully on release, 1 are not supported there, and the rest are untried. Untried is not broken: discover the contract with `mammoth schema get COMMAND_ID`, run it, and treat the structured error envelope as the answer. Use an untried command normally: confirm a write with the user first, check its result with a read afterwards, and never refuse a command only because it is untried.
|
|
5
5
|
|
|
6
6
|
Status meanings:
|
|
7
7
|
|
|
@@ -17,20 +17,21 @@ The typed `view transform *` commands all submit through `view.task.add` (`renam
|
|
|
17
17
|
|
|
18
18
|
| Family | Commands | Ran once | Not supported | Untried |
|
|
19
19
|
|---|---|---|---|---|
|
|
20
|
-
| `dashboard` |
|
|
20
|
+
| `dashboard` | 122 | 81 | 1 | 40 |
|
|
21
|
+
| `support` | 66 | 9 | 0 | 57 |
|
|
21
22
|
| `view` | 62 | 58 | 0 | 4 |
|
|
22
|
-
| `
|
|
23
|
+
| `billing` | 24 | 4 | 0 | 20 |
|
|
23
24
|
| `connector` | 22 | 3 | 0 | 19 |
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
| `dataset` | 17 | 12 | 0 | 5 |
|
|
25
|
+
| `workspace` | 20 | 7 | 0 | 13 |
|
|
26
|
+
| `dataset` | 18 | 12 | 0 | 6 |
|
|
27
27
|
| `project` | 17 | 15 | 0 | 2 |
|
|
28
28
|
| `workflow` | 16 | 9 | 0 | 7 |
|
|
29
29
|
| `parameter` | 14 | 7 | 0 | 7 |
|
|
30
30
|
| `data-app` | 12 | 1 | 0 | 11 |
|
|
31
|
+
| `automation` | 8 | 3 | 0 | 5 |
|
|
32
|
+
| `browse` | 8 | 1 | 0 | 7 |
|
|
31
33
|
| `folder` | 8 | 8 | 0 | 0 |
|
|
32
34
|
| `snippet` | 8 | 6 | 0 | 2 |
|
|
33
|
-
| `automation` | 7 | 3 | 0 | 4 |
|
|
34
35
|
| `user` | 7 | 3 | 0 | 4 |
|
|
35
36
|
| `webhook` | 7 | 5 | 0 | 2 |
|
|
36
37
|
| `addon` | 6 | 0 | 0 | 6 |
|
|
@@ -43,7 +44,6 @@ The typed `view transform *` commands all submit through `view.task.add` (`renam
|
|
|
43
44
|
| `notification` | 5 | 1 | 0 | 4 |
|
|
44
45
|
| `schedule` | 5 | 0 | 0 | 5 |
|
|
45
46
|
| `template` | 5 | 5 | 0 | 0 |
|
|
46
|
-
| `browse` | 4 | 1 | 0 | 3 |
|
|
47
47
|
| `external-key` | 4 | 1 | 0 | 3 |
|
|
48
48
|
| `trash` | 3 | 3 | 0 | 0 |
|
|
49
49
|
| `activity` | 2 | 1 | 0 | 1 |
|
|
@@ -58,7 +58,6 @@ Ran once: `dashboard.action`, `dashboard.analytics`, `dashboard.archive`, `dashb
|
|
|
58
58
|
|
|
59
59
|
| Command | State | Note |
|
|
60
60
|
|---|---|---|
|
|
61
|
-
| `dashboard.create` | not supported | Not supported on release: backend returns HTTP 409 4DASH012 DASHBOARD_LEGACY_CREATION_RETIRED (legacy dashboard creation retired). Use dashboard.create-blank or dashboard.v3.generate. Dashboard sweep 2026-09-18, CLI 2.0.12. |
|
|
62
61
|
| `dashboard.pdf.export` | not supported | Not supported from the CLI on release: backend HTTP 400 4GENR001 requires params.data to be the browser-hydrated DashboardData map and states it cannot rebuild it from stored descriptors (dashboard sweep and Haiku e2e, 2026-09-18). The route works only with a client render pass. |
|
|
63
62
|
| `dashboard.data.draft` | observed blocker | blocked_missing_fixture: Dashboard 56 (create-blank/v3 engine) has no widgets in its canvas and getDraftData rejects with backend_code 4DASH004 DASHBOARD_WRONG_ENGINE: "This dashbo |
|
|
64
63
|
| `dashboard.data.published` | observed blocker | blocked_missing_fixture: Same as dashboard.data.draft: backend_code 4DASH004 DASHBOARD_WRONG_ENGINE on /dashboards/56/getPublishData |
|
|
@@ -110,7 +109,7 @@ Ran once: `project.bulk-delete`, `project.bulk-update`, `project.checkpoint.list
|
|
|
110
109
|
|
|
111
110
|
## `view`
|
|
112
111
|
|
|
113
|
-
Ran once: `view.active-user.list`, `view.active-user.mark`, `view.ai.generate-data`, `view.ai.profile`, `view.bulk-delete`, `view.checkpoint.create`, `view.checkpoint.delete`, `view.checkpoint.get`, `view.checkpoint.list`, `view.checkpoint.update`, `view.conditional-format.create`, `view.conditional-format.delete-all`, `view.conditional-format.list`, `view.conditional-format.update`, `view.create`, `view.data-check.create`, `view.data-check.delete`, `view.data-check.get`, `view.data-check.list`, `view.data.get`, `view.data.query`, `view.delete`, `view.derivative.create`, `view.derivative.data`, `view.derivative.delete`, `view.derivative.list`, `view.derivative.update`, `view.draft.command`, `view.export.create`, `view.export.delete`, `view.export.get`, `view.export.list`, `view.export.publish-db`, `view.export.update`, `view.exportable-config.apply`, `view.exportable-config.get`, `view.get`, `view.list`, `view.parameter-context`, `view.pipeline.edit`, `view.pipeline.get`, `view.pipeline.items`, `view.pipeline.rerun`, `view.preview`, `view.restore`, `view.task.add`, `view.task.delete`, `view.task.get`, `view.task.list`, `view.task.preview`, `view.task.update`, `view.trash`, `view.version.apply`, `view.version.delete`, `view.version.get`, `view.version.list`, `view.version.update`
|
|
112
|
+
Ran once: `view.active-user.list`, `view.active-user.mark`, `view.ai.generate-data`, `view.ai.profile`, `view.bulk-delete`, `view.checkpoint.create`, `view.checkpoint.delete`, `view.checkpoint.get`, `view.checkpoint.list`, `view.checkpoint.update`, `view.conditional-format.create`, `view.conditional-format.delete-all`, `view.conditional-format.list`, `view.conditional-format.update`, `view.create`, `view.data-check.create`, `view.data-check.delete`, `view.data-check.get`, `view.data-check.list`, `view.data.aggregate`, `view.data.get`, `view.data.query`, `view.delete`, `view.derivative.create`, `view.derivative.data`, `view.derivative.delete`, `view.derivative.list`, `view.derivative.update`, `view.draft.command`, `view.export.create`, `view.export.delete`, `view.export.get`, `view.export.list`, `view.export.publish-db`, `view.export.update`, `view.exportable-config.apply`, `view.exportable-config.get`, `view.get`, `view.list`, `view.parameter-context`, `view.pipeline.edit`, `view.pipeline.get`, `view.pipeline.items`, `view.pipeline.rerun`, `view.preview`, `view.restore`, `view.task.add`, `view.task.delete`, `view.task.get`, `view.task.list`, `view.task.preview`, `view.task.update`, `view.trash`, `view.version.apply`, `view.version.delete`, `view.version.get`, `view.version.list`, `view.version.update`
|
|
114
113
|
|
|
115
114
|
| Command | State | Note |
|
|
116
115
|
|---|---|---|
|
|
@@ -386,7 +386,7 @@ Status on release: untried; no live run recorded.
|
|
|
386
386
|
|
|
387
387
|
Run: `mammoth dashboard format-preview`. Exact input fields: `mammoth schema get dashboard.format-preview`.
|
|
388
388
|
|
|
389
|
-
Example: `mammoth dashboard format-preview 123 --input '{"style": "
|
|
389
|
+
Example: `mammoth dashboard format-preview 123 --input '{"style": "presentation"}'`. Placeholders are illustrative; resolve IDs and input from observed reads.
|
|
390
390
|
|
|
391
391
|
Result: `DashboardFormatPreviewResult`; mutation `read`, confirmation `none`, wait policy `not_async`.
|
|
392
392
|
|
|
@@ -26,7 +26,7 @@ Status on release: untried; no live run recorded.
|
|
|
26
26
|
|
|
27
27
|
Run: `mammoth dataset broken-rows resolve`. Exact input fields: `mammoth schema get dataset.broken-rows.resolve`.
|
|
28
28
|
|
|
29
|
-
Example: `mammoth dataset broken-rows resolve 123 --input '{"op": "add", "batch_id": 1, "rows": [{"
|
|
29
|
+
Example: `mammoth dataset broken-rows resolve 123 --input '{"op": "add", "batch_id": 1, "rows": [{"line_num": 2, "line": "corrected,line,here"}]}'`. Illustrative only: append `--yes` after observing an owned target.
|
|
30
30
|
|
|
31
31
|
Result: `DatasetBrokenRowsResolveResult`; mutation `destructive`, confirmation `prompt_or_yes`, wait policy `not_async`.
|
|
32
32
|
|
|
@@ -6,9 +6,9 @@ Every command returns the standard JSON envelope. On nonzero exit, read the erro
|
|
|
6
6
|
|
|
7
7
|
Run: `mammoth project bulk-delete`. Exact input fields: `mammoth schema get project.bulk-delete`.
|
|
8
8
|
|
|
9
|
-
Example: `mammoth project bulk-delete --input '{"project_ids": [1]}'`. Illustrative only: append `--yes
|
|
9
|
+
Example: `mammoth project bulk-delete --input '{"project_ids": [1]}'`. Illustrative only: append `--yes --confirm <EXACT_TARGET>` after observing the target.
|
|
10
10
|
|
|
11
|
-
Result: `ProjectBulkDeleteResult`; mutation `destructive`, confirmation `
|
|
11
|
+
Result: `ProjectBulkDeleteResult`; mutation `destructive`, confirmation `confirm_target`, wait policy `not_async`.
|
|
12
12
|
|
|
13
13
|
Status on release: ran once on CLI 2.0.14 — write sweep 2026-09-18: exit 0 on release with CLI 2.0.14. Created throwaway project 22 (cli-write-sweep-throwaway-20260918), then bulk-deleted it. Without --yes: confirmation_required. With --yes: data:{}. Verified via project list: only project 3 (protected…
|
|
14
14
|
|
|
@@ -220,7 +220,7 @@ Example: `mammoth view data aggregate 123 --input '{"group_by": ["Channel"], "ag
|
|
|
220
220
|
|
|
221
221
|
Result: `ViewDataAggregateResult`; mutation `read`, confirmation `none`, wait policy `always_wait`.
|
|
222
222
|
|
|
223
|
-
Status on release:
|
|
223
|
+
Status on release: ran once on CLI 2.0.18 — golden-data check 2026-09-19 (CLI 2.0.18): condition on the pivoted view compiled to the backend clause shape and answered (exit 0); EQ with a column select and an AND of CONTAINS/NE also verified read-only on a pre-existing view. Before 2.0.18 the spec was f…
|
|
224
224
|
|
|
225
225
|
### `view.data.compare`
|
|
226
226
|
|
|
@@ -270,7 +270,7 @@ Example: `mammoth view data query 123 123`. Placeholders are illustrative; resol
|
|
|
270
270
|
|
|
271
271
|
Result: `ViewDataQueryResult`; mutation `read`, confirmation `none`, wait policy `always_wait`.
|
|
272
272
|
|
|
273
|
-
Status on release: ran once on CLI 2.0.
|
|
273
|
+
Status on release: ran once on CLI 2.0.28 — ILG simulation 2026-09-19: exit 0 on release with CLI 2.0.28. Paged reads (limit up to 500) used for every value check; envelope data.data rows keyed by display name. Single invocation only.
|
|
274
274
|
|
|
275
275
|
### `view.delete`
|
|
276
276
|
|
|
@@ -16,9 +16,9 @@ Status on release: untried; no live run recorded.
|
|
|
16
16
|
|
|
17
17
|
Run: `mammoth workflow block auth`. Exact input fields: `mammoth schema get workflow.block.auth`.
|
|
18
18
|
|
|
19
|
-
Example: `mammoth workflow block auth 123 123 --input '{"auth_data": {"sample_key": "Status"}}'`.
|
|
19
|
+
Example: `mammoth workflow block auth 123 123 --input '{"auth_data": {"sample_key": "Status"}}'`. Illustrative only: append `--yes --confirm <EXACT_TARGET>` after observing the target.
|
|
20
20
|
|
|
21
|
-
Result: `WorkflowBlockAuthResult`; mutation `benign_mutation`, confirmation `
|
|
21
|
+
Result: `WorkflowBlockAuthResult`; mutation `benign_mutation`, confirmation `confirm_target`, wait policy `not_async`.
|
|
22
22
|
|
|
23
23
|
Status on release: untried; no live run recorded.
|
|
24
24
|
|
|
@@ -56,9 +56,9 @@ Status on release: untried; no live run recorded.
|
|
|
56
56
|
|
|
57
57
|
Run: `mammoth workflow cleanup`. Exact input fields: `mammoth schema get workflow.cleanup`.
|
|
58
58
|
|
|
59
|
-
Example: `mammoth workflow cleanup`.
|
|
59
|
+
Example: `mammoth workflow cleanup`. Illustrative only: append `--yes` after observing an owned target.
|
|
60
60
|
|
|
61
|
-
Result: `WorkflowCleanupResult`; mutation `
|
|
61
|
+
Result: `WorkflowCleanupResult`; mutation `destructive`, confirmation `prompt_or_yes`, wait policy `not_async`.
|
|
62
62
|
|
|
63
63
|
Status on release: untried; no live run recorded.
|
|
64
64
|
|
|
@@ -258,8 +258,8 @@ Status on release: untried; no live run recorded.
|
|
|
258
258
|
|
|
259
259
|
Run: `mammoth workspace user update-batch`. Exact input fields: `mammoth schema get workspace.user.update-batch`.
|
|
260
260
|
|
|
261
|
-
Example: `mammoth workspace user update-batch --input '{"patches": [{"sample_key": "Status"}]}'`.
|
|
261
|
+
Example: `mammoth workspace user update-batch --input '{"patches": [{"sample_key": "Status"}]}'`. Illustrative only: append `--yes --confirm <EXACT_TARGET>` after observing the target.
|
|
262
262
|
|
|
263
|
-
Result: `WorkspaceUserUpdateBatchResult`; mutation `
|
|
263
|
+
Result: `WorkspaceUserUpdateBatchResult`; mutation `high_impact`, confirmation `confirm_target`, wait policy `not_async`.
|
|
264
264
|
|
|
265
265
|
Status on release: untried; no live run recorded.
|
|
@@ -12,6 +12,7 @@ public SDK method named by the command's reviewed manifest ``sdk_symbol``.
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
14
|
import json
|
|
15
|
+
import shlex
|
|
15
16
|
from datetime import UTC, datetime
|
|
16
17
|
from typing import Any
|
|
17
18
|
|
|
@@ -136,7 +137,9 @@ def _refuse_bare_resource_id(document: dict[str, Any]) -> None:
|
|
|
136
137
|
f" keys each resource by its type — {forms}."
|
|
137
138
|
),
|
|
138
139
|
exit_status=EXIT_USAGE,
|
|
139
|
-
recovery_commands=[
|
|
140
|
+
recovery_commands=[
|
|
141
|
+
f"mammoth activity list --input {shlex.quote(retry)}" for retry in retries
|
|
142
|
+
],
|
|
140
143
|
)
|
|
141
144
|
|
|
142
145
|
|
|
@@ -205,8 +208,10 @@ def _user_emails(service: Any) -> dict[Any, str]:
|
|
|
205
208
|
|
|
206
209
|
def _change(entry: dict[str, Any], emails: dict[Any, str]) -> dict[str, Any]:
|
|
207
210
|
"""One log entry as a line of a change list: when, who, what, on which object."""
|
|
208
|
-
|
|
209
|
-
|
|
211
|
+
raw_details = entry.get("details")
|
|
212
|
+
details: dict[str, Any] = raw_details if isinstance(raw_details, dict) else {}
|
|
213
|
+
raw_primary = entry.get("primary_object")
|
|
214
|
+
primary: dict[str, Any] = raw_primary if isinstance(raw_primary, dict) else {}
|
|
210
215
|
user_id = entry.get("user_id")
|
|
211
216
|
change = {
|
|
212
217
|
"when": _local_time(entry.get("created_at")),
|
|
@@ -18,7 +18,13 @@ from __future__ import annotations
|
|
|
18
18
|
import ast
|
|
19
19
|
import re
|
|
20
20
|
from collections.abc import Callable
|
|
21
|
-
from decimal import
|
|
21
|
+
from decimal import (
|
|
22
|
+
ROUND_HALF_UP,
|
|
23
|
+
Decimal,
|
|
24
|
+
DivisionByZero,
|
|
25
|
+
InvalidOperation,
|
|
26
|
+
localcontext,
|
|
27
|
+
)
|
|
22
28
|
from typing import Any
|
|
23
29
|
|
|
24
30
|
from mammoth_cli.errors.envelope import CODE_INVALID_ARGUMENT, EXIT_USAGE, CliError
|
|
@@ -30,6 +36,9 @@ HandlerResult = tuple[Any, dict[str, Any]]
|
|
|
30
36
|
#: valid Python expression syntax on its own.
|
|
31
37
|
_PERCENT_RE = re.compile(r"(\d+(?:\.\d+)?)\s*%")
|
|
32
38
|
|
|
39
|
+
#: Significant digits kept in a result (Python's default is 28).
|
|
40
|
+
_PRECISION = 60
|
|
41
|
+
|
|
33
42
|
_BINOPS: dict[type, Callable[[Decimal, Decimal], Decimal]] = {
|
|
34
43
|
ast.Add: lambda a, b: a + b,
|
|
35
44
|
ast.Sub: lambda a, b: a - b,
|
|
@@ -48,18 +57,26 @@ def _unsupported(expression: str) -> CliError:
|
|
|
48
57
|
)
|
|
49
58
|
|
|
50
59
|
|
|
51
|
-
def
|
|
60
|
+
def _literal(node: ast.Constant, source: str) -> Decimal:
|
|
61
|
+
"""The number as written: going through a float would round away digits past 17."""
|
|
62
|
+
try:
|
|
63
|
+
return Decimal(ast.get_source_segment(source, node) or "")
|
|
64
|
+
except InvalidOperation:
|
|
65
|
+
return Decimal(str(node.value))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _evaluate(node: ast.AST, expression: str, source: str) -> Decimal:
|
|
52
69
|
if isinstance(node, ast.Expression):
|
|
53
|
-
return _evaluate(node.body, expression)
|
|
70
|
+
return _evaluate(node.body, expression, source)
|
|
54
71
|
if (
|
|
55
72
|
isinstance(node, ast.Constant)
|
|
56
73
|
and isinstance(node.value, (int, float))
|
|
57
74
|
and not isinstance(node.value, bool)
|
|
58
75
|
):
|
|
59
|
-
return
|
|
76
|
+
return _literal(node, source)
|
|
60
77
|
if isinstance(node, ast.BinOp) and type(node.op) in _BINOPS:
|
|
61
|
-
left = _evaluate(node.left, expression)
|
|
62
|
-
right = _evaluate(node.right, expression)
|
|
78
|
+
left = _evaluate(node.left, expression, source)
|
|
79
|
+
right = _evaluate(node.right, expression, source)
|
|
63
80
|
try:
|
|
64
81
|
return _BINOPS[type(node.op)](left, right)
|
|
65
82
|
except (InvalidOperation, DivisionByZero, ZeroDivisionError) as exc:
|
|
@@ -69,7 +86,7 @@ def _evaluate(node: ast.AST, expression: str) -> Decimal:
|
|
|
69
86
|
exit_status=EXIT_USAGE,
|
|
70
87
|
) from exc
|
|
71
88
|
if isinstance(node, ast.UnaryOp) and isinstance(node.op, (ast.UAdd, ast.USub)):
|
|
72
|
-
value = _evaluate(node.operand, expression)
|
|
89
|
+
value = _evaluate(node.operand, expression, source)
|
|
73
90
|
return value if isinstance(node.op, ast.UAdd) else -value
|
|
74
91
|
if (
|
|
75
92
|
isinstance(node, ast.Call)
|
|
@@ -78,7 +95,7 @@ def _evaluate(node: ast.AST, expression: str) -> Decimal:
|
|
|
78
95
|
and not node.keywords
|
|
79
96
|
and 1 <= len(node.args) <= 2
|
|
80
97
|
):
|
|
81
|
-
value = _evaluate(node.args[0], expression)
|
|
98
|
+
value = _evaluate(node.args[0], expression, source)
|
|
82
99
|
ndigits = 0
|
|
83
100
|
if len(node.args) == 2:
|
|
84
101
|
digits_node = node.args[1]
|
|
@@ -90,7 +107,14 @@ def _evaluate(node: ast.AST, expression: str) -> Decimal:
|
|
|
90
107
|
raise _unsupported(expression)
|
|
91
108
|
ndigits = digits_node.value
|
|
92
109
|
quantum = Decimal(1).scaleb(-ndigits)
|
|
93
|
-
|
|
110
|
+
try:
|
|
111
|
+
return value.quantize(quantum, rounding=ROUND_HALF_UP)
|
|
112
|
+
except InvalidOperation as exc:
|
|
113
|
+
raise CliError(
|
|
114
|
+
code=CODE_INVALID_ARGUMENT,
|
|
115
|
+
message=f"round() digits out of range in {expression!r}.",
|
|
116
|
+
exit_status=EXIT_USAGE,
|
|
117
|
+
) from exc
|
|
94
118
|
raise _unsupported(expression)
|
|
95
119
|
|
|
96
120
|
|
|
@@ -120,5 +144,8 @@ def calc(invocation: Invocation) -> HandlerResult:
|
|
|
120
144
|
hint="calc supports + - * / and parentheses, unary +/-, a trailing "
|
|
121
145
|
"'%' (divides by 100), and round(x[, ndigits]).",
|
|
122
146
|
) from exc
|
|
123
|
-
|
|
147
|
+
source = normalized
|
|
148
|
+
with localcontext() as context:
|
|
149
|
+
context.prec = _PRECISION
|
|
150
|
+
result = _evaluate(tree, expression, source)
|
|
124
151
|
return {"expression": expression, "result": str(result)}, {}
|
|
@@ -27,6 +27,7 @@ from mammoth_cli.errors.envelope import (
|
|
|
27
27
|
CliError,
|
|
28
28
|
)
|
|
29
29
|
from mammoth_cli.manifest.loader import command_by_id
|
|
30
|
+
from mammoth_cli.output.normalize import Revealed, normalize
|
|
30
31
|
from mammoth_cli.runtime.confirm import (
|
|
31
32
|
POLICY_CONFIRM_TARGET,
|
|
32
33
|
POLICY_PROMPT_OR_YES,
|
|
@@ -210,6 +211,8 @@ def client_app_create(invocation: Invocation) -> HandlerResult:
|
|
|
210
211
|
_forward_optional(document, kwargs, ("description",))
|
|
211
212
|
with open_service(invocation) as (service, auth):
|
|
212
213
|
data = service.call(_symbol(invocation), **kwargs)
|
|
214
|
+
# The API shows the new app's token once; masking it would lose it for good.
|
|
215
|
+
data = Revealed(normalize(data, redact_secrets=False))
|
|
213
216
|
return data, _meta(invocation, auth.workspace_id, resolved_project(invocation))
|
|
214
217
|
|
|
215
218
|
|
|
@@ -396,6 +396,10 @@ def dashboard_get(invocation: Invocation) -> HandlerResult:
|
|
|
396
396
|
return data, _meta(invocation, auth.workspace_id)
|
|
397
397
|
|
|
398
398
|
|
|
399
|
+
#: Sources whose owning dataset one ``dashboard get`` looks up (one request each).
|
|
400
|
+
_MAX_SOURCE_LOOKUPS = 20
|
|
401
|
+
|
|
402
|
+
|
|
399
403
|
def _source_dataset(service: Any, invocation: Invocation, workspace_id: Any, view_id: int) -> Any:
|
|
400
404
|
"""The dataset that owns ``view_id``: remembered, else looked up; never raises."""
|
|
401
405
|
profile_name = invocation.profile or profiles.get_selected()
|
|
@@ -422,16 +426,18 @@ def _with_source_datasets(
|
|
|
422
426
|
sources = data.get("sources") if isinstance(data, dict) else None
|
|
423
427
|
if not isinstance(sources, list) or not sources:
|
|
424
428
|
return data
|
|
429
|
+
view_ids = [view_id for view_id in sources if isinstance(view_id, int)]
|
|
425
430
|
views = [
|
|
426
431
|
_source_dataset(service, invocation, workspace_id, view_id)
|
|
427
|
-
for view_id in
|
|
428
|
-
if isinstance(view_id, int)
|
|
432
|
+
for view_id in view_ids[:_MAX_SOURCE_LOOKUPS]
|
|
429
433
|
]
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
434
|
+
note = "sources are view ids; use a source's dataset_id for dataset commands."
|
|
435
|
+
if len(view_ids) > _MAX_SOURCE_LOOKUPS:
|
|
436
|
+
note += (
|
|
437
|
+
f" Only the first {_MAX_SOURCE_LOOKUPS} of {len(view_ids)} sources were labelled;"
|
|
438
|
+
" read the others with 'view get VIEW_ID'."
|
|
439
|
+
)
|
|
440
|
+
return {**data, "source_views": views, "sources_note": note}
|
|
435
441
|
|
|
436
442
|
|
|
437
443
|
def _with_board_project(data: Any) -> Any:
|
|
@@ -149,19 +149,38 @@ def _visible_projects(service: Any) -> list[dict[str, Any]]:
|
|
|
149
149
|
|
|
150
150
|
|
|
151
151
|
def _find_in_projects(
|
|
152
|
-
service: Any,
|
|
152
|
+
service: Any,
|
|
153
|
+
needle: str,
|
|
154
|
+
projects: list[dict[str, Any]],
|
|
155
|
+
skipped: list[dict[str, Any]] | None = None,
|
|
153
156
|
) -> list[dict[str, Any]]:
|
|
154
|
-
"""Datasets whose name contains ``needle`` (case-insensitive), in each of ``projects``.
|
|
157
|
+
"""Datasets whose name contains ``needle`` (case-insensitive), in each of ``projects``.
|
|
158
|
+
|
|
159
|
+
A project that cannot be read does not end the search: with ``skipped`` it is
|
|
160
|
+
recorded there (id, name, why) and the rest are still searched.
|
|
161
|
+
"""
|
|
155
162
|
matches: list[dict[str, Any]] = []
|
|
156
163
|
for project in projects:
|
|
157
164
|
project_id = project.get("id")
|
|
158
165
|
if project_id is None:
|
|
159
166
|
continue
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
167
|
+
try:
|
|
168
|
+
response = service.call(
|
|
169
|
+
"mammoth.api.datasets.DatasetsAPI.list_all",
|
|
170
|
+
project_id=project_id,
|
|
171
|
+
fields=DATASET_ROW_FIELDS,
|
|
172
|
+
)
|
|
173
|
+
except CliError as error:
|
|
174
|
+
if skipped is None:
|
|
175
|
+
raise
|
|
176
|
+
skipped.append(
|
|
177
|
+
{
|
|
178
|
+
"project_id": project_id,
|
|
179
|
+
"project_name": project.get("name"),
|
|
180
|
+
"error": error.message,
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
continue
|
|
165
184
|
datasets = response.get("datasets", []) if isinstance(response, dict) else []
|
|
166
185
|
for dataset in datasets:
|
|
167
186
|
name = dataset.get("name") if isinstance(dataset, dict) else None
|
|
@@ -177,6 +196,63 @@ def _find_in_projects(
|
|
|
177
196
|
return matches
|
|
178
197
|
|
|
179
198
|
|
|
199
|
+
#: Pages of resource search read for one name (100 hits each); past it the result says so.
|
|
200
|
+
_SEARCH_PAGES = 5
|
|
201
|
+
_SEARCH_PAGE_SIZE = 100
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def search_hits(
|
|
205
|
+
service: Any, resource_type: str, needle: str, project_id: int | None = None
|
|
206
|
+
) -> tuple[list[dict[str, Any]], bool]:
|
|
207
|
+
"""Resources of ``resource_type`` whose name contains ``needle``, from the search route.
|
|
208
|
+
|
|
209
|
+
One request (one more per 100 hits) replaces a listing per project: the
|
|
210
|
+
workspace search, or the project's own resource list when ``project_id`` is
|
|
211
|
+
given. Returns the minimal rows and whether the read stopped at
|
|
212
|
+
``_SEARCH_PAGES`` pages with more hits unread.
|
|
213
|
+
"""
|
|
214
|
+
symbol = (
|
|
215
|
+
"mammoth.api.browse.BrowseAPI.resources_search"
|
|
216
|
+
if project_id is None
|
|
217
|
+
else "mammoth.api.browse.BrowseAPI.resources_list"
|
|
218
|
+
)
|
|
219
|
+
scope: dict[str, Any] = {} if project_id is None else {"project_id": project_id}
|
|
220
|
+
rows: list[dict[str, Any]] = []
|
|
221
|
+
cursor: str | None = None
|
|
222
|
+
for _ in range(_SEARCH_PAGES):
|
|
223
|
+
page = service.call(
|
|
224
|
+
symbol,
|
|
225
|
+
search=needle,
|
|
226
|
+
resource_type=resource_type,
|
|
227
|
+
limit=_SEARCH_PAGE_SIZE,
|
|
228
|
+
cursor=cursor,
|
|
229
|
+
fields="minimal",
|
|
230
|
+
**scope,
|
|
231
|
+
)
|
|
232
|
+
rows += [r for r in page.get("resources", []) if isinstance(r, dict)]
|
|
233
|
+
cursor = page.get("next_cursor")
|
|
234
|
+
if not (page.get("has_more") and cursor):
|
|
235
|
+
return rows, False
|
|
236
|
+
return rows, True
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def search_cut_note(kind: str) -> str:
|
|
240
|
+
"""Said when a name search stopped early, with how to narrow it."""
|
|
241
|
+
return (
|
|
242
|
+
f"The name matched more than {_SEARCH_PAGES * _SEARCH_PAGE_SIZE} {kind}, so only the "
|
|
243
|
+
"first of them were read. Use a longer name, or --project, to narrow it."
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _projects_holding(
|
|
248
|
+
service: Any, needle: str, visible: list[dict[str, Any]]
|
|
249
|
+
) -> tuple[list[dict[str, Any]], bool]:
|
|
250
|
+
"""The visible projects that hold a dataset whose name contains ``needle``."""
|
|
251
|
+
rows, cut = search_hits(service, "datasource", needle)
|
|
252
|
+
holding = {r.get("project_id") for r in rows}
|
|
253
|
+
return [p for p in visible if p.get("id") in holding], cut
|
|
254
|
+
|
|
255
|
+
|
|
180
256
|
def _other_projects(visible: list[dict[str, Any]], project_id: int) -> list[dict[str, Any]]:
|
|
181
257
|
"""Every visible project except ``project_id``."""
|
|
182
258
|
return [p for p in visible if p.get("id") != project_id]
|
|
@@ -210,18 +286,23 @@ def dataset_find(invocation: Invocation) -> HandlerResult:
|
|
|
210
286
|
"""
|
|
211
287
|
name_substring = _require_string_positional(invocation, "name substring")
|
|
212
288
|
needle = name_substring.lower()
|
|
289
|
+
skipped: list[dict[str, Any]] = []
|
|
213
290
|
with open_service(invocation) as (service, auth):
|
|
214
291
|
visible = _visible_projects(service)
|
|
292
|
+
cut = False
|
|
215
293
|
if invocation.project is not None:
|
|
216
294
|
projects: list[dict[str, Any]] = [named_project(service, invocation.project, visible)]
|
|
217
|
-
matches = _find_in_projects(service, needle, projects)
|
|
295
|
+
matches = _find_in_projects(service, needle, projects, skipped)
|
|
218
296
|
if not matches:
|
|
219
|
-
|
|
220
|
-
matches = _find_in_projects(
|
|
221
|
-
|
|
297
|
+
holding, cut = _projects_holding(service, needle, visible)
|
|
298
|
+
matches = _find_in_projects(
|
|
299
|
+
service, needle, _other_projects(holding, invocation.project), skipped
|
|
300
|
+
)
|
|
301
|
+
projects += _other_projects(visible, invocation.project)
|
|
222
302
|
else:
|
|
223
303
|
projects = visible
|
|
224
|
-
|
|
304
|
+
holding, cut = _projects_holding(service, needle, visible)
|
|
305
|
+
matches = _find_in_projects(service, needle, holding, skipped)
|
|
225
306
|
meta = {
|
|
226
307
|
"profile": invocation.profile,
|
|
227
308
|
"workspace_id": auth.workspace_id,
|
|
@@ -229,9 +310,15 @@ def dataset_find(invocation: Invocation) -> HandlerResult:
|
|
|
229
310
|
}
|
|
230
311
|
result: dict[str, Any] = {
|
|
231
312
|
"matches": matches,
|
|
232
|
-
"projects_searched": len(projects),
|
|
313
|
+
"projects_searched": len(projects) - len(skipped),
|
|
233
314
|
}
|
|
234
|
-
if
|
|
315
|
+
if skipped:
|
|
316
|
+
result["projects_skipped"] = skipped
|
|
317
|
+
notes = [ambiguity_note(len(matches), name_substring)]
|
|
318
|
+
if cut:
|
|
319
|
+
result["truncated"] = True
|
|
320
|
+
notes.append(search_cut_note("datasets"))
|
|
321
|
+
if note := " ".join(n for n in notes if n):
|
|
235
322
|
result["note"] = note
|
|
236
323
|
return result, meta
|
|
237
324
|
|
|
@@ -282,8 +369,9 @@ def _dataset_name_search(
|
|
|
282
369
|
records = data.get("datasets", []) if isinstance(data, dict) else []
|
|
283
370
|
page = search_page(records, name, int(document.get("offset", 0)), document.get("limit"))
|
|
284
371
|
if page["matched"] == 0:
|
|
372
|
+
holding, cut = _projects_holding(service, name.lower(), _visible_projects(service))
|
|
285
373
|
elsewhere = _find_in_projects(
|
|
286
|
-
service, name.lower(), _other_projects(
|
|
374
|
+
service, name.lower(), _other_projects(holding, project_id)
|
|
287
375
|
)
|
|
288
376
|
if elsewhere:
|
|
289
377
|
page["in_other_projects"] = elsewhere
|
|
@@ -291,6 +379,11 @@ def _dataset_name_search(
|
|
|
291
379
|
f"No dataset in project {project_id} matches; the ones listed in "
|
|
292
380
|
"in_other_projects do. Run the next call with --project <its project_id>."
|
|
293
381
|
)
|
|
382
|
+
if cut:
|
|
383
|
+
page["truncated"] = True
|
|
384
|
+
page["note"] = " ".join(
|
|
385
|
+
filter(None, (page.get("note"), search_cut_note("datasets")))
|
|
386
|
+
)
|
|
294
387
|
page["name"] = name
|
|
295
388
|
return page, _meta(invocation, auth.workspace_id, project_id)
|
|
296
389
|
|
|
@@ -133,9 +133,8 @@ _PROJECT_LIMIT = 20
|
|
|
133
133
|
|
|
134
134
|
def _visible_projects(service: Any) -> list[dict[str, Any]]:
|
|
135
135
|
"""Return the projects this credential can list, or an empty list."""
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return [p for p in projects if isinstance(p, dict)]
|
|
136
|
+
# Every page: "is the selected project visible" must not stop at the first few.
|
|
137
|
+
return [p for p in service.list_all_projects() if isinstance(p, dict)]
|
|
139
138
|
|
|
140
139
|
|
|
141
140
|
def _nearest_existing(path: Path) -> Path:
|
|
@@ -237,9 +237,17 @@ def file_upload(invocation: Invocation) -> HandlerResult:
|
|
|
237
237
|
# the status the platform holds for each dataset, not an assumed one.
|
|
238
238
|
result = _upload_result(data, lambda dataset_id: _dataset_status(service, dataset_id))
|
|
239
239
|
project_id = resolved_project(invocation)
|
|
240
|
+
previewed = 0
|
|
240
241
|
for entry in result["datasets"]:
|
|
241
242
|
if entry.get("status") != "ready":
|
|
242
243
|
continue
|
|
244
|
+
if previewed >= _UPLOAD_PREVIEW_LIMIT:
|
|
245
|
+
entry["preview_skipped"] = (
|
|
246
|
+
f"Only the first {_UPLOAD_PREVIEW_LIMIT} datasets are previewed; "
|
|
247
|
+
f"run 'view list {entry['id']}' to see this one."
|
|
248
|
+
)
|
|
249
|
+
continue
|
|
250
|
+
previewed += 1
|
|
243
251
|
preview = upload_preview(service, int(entry["id"]), project_id)
|
|
244
252
|
if "preview_error" in preview:
|
|
245
253
|
entry["preview_error"] = preview["preview_error"]
|
|
@@ -253,6 +261,10 @@ def file_upload(invocation: Invocation) -> HandlerResult:
|
|
|
253
261
|
return result, _meta(invocation, auth.workspace_id, resolved_project(invocation))
|
|
254
262
|
|
|
255
263
|
|
|
264
|
+
#: Uploaded datasets one ``file upload`` previews (several requests each).
|
|
265
|
+
_UPLOAD_PREVIEW_LIMIT = 5
|
|
266
|
+
|
|
267
|
+
|
|
256
268
|
def _require_local_files(files: Any) -> None:
|
|
257
269
|
"""Fail as a usage error, naming the path, when a local file is missing.
|
|
258
270
|
|