mammoth-cli 2.2.21__tar.gz → 2.2.23__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.21 → mammoth_cli-2.2.23}/PKG-INFO +1 -1
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/__init__.py +1 -1
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +2 -2
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/dataset.py +112 -2
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/project.py +42 -11
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/view.py +18 -5
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/view_ops.py +25 -1
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/errors/envelope.py +2 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/positionals.py +10 -2
- mammoth_cli-2.2.23/mammoth_cli/services/sql_check.py +87 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/pyproject.toml +1 -1
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/ai.yaml +4 -8
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/dataset.yaml +2 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/project.yaml +8 -2
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/sdk-catalog.source.yaml +2 -2
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/sdk-methods.yaml +2 -2
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/.gitignore +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/LICENSE +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/README.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/__main__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/app.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/about-mammoth.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/calc.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-qa.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-style.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-template.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/link.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view-transform.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/database-import.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/scheduling.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/activity.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/addon.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/agent.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/ai.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/annotation.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/auth.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/automation.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/batch.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/billing.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/browse.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/calc.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/capability.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/client_app.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/completion.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/config.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/connector.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/context.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/dashboard.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/data_app.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/doctor.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/external_key.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/file.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/folder.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/job.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/link.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/notification.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/parameter.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/registry.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/report.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/schedule.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/schema.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/skill.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/snippet.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/support.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/template.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/trash.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/upgrade.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/user.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/view_profile.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/webhook.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/workflow.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/commands/workspace.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/context/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/context/credentials.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/context/endpoint.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/context/profiles.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/context/resolver.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/contracts/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/contracts/auth.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/embed.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/errors/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/manifest/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/manifest/loader.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/messages/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/output/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/output/envelope.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/output/normalize.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/output/policy.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/output/progress.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/output/render.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/py.typed +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/confirm.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/dataset_health.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/dryrun.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/dryrun_targets.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/embedded.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/executor.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/input_loader.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/intent_only.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/invocation.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/new_data.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/options.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/parents.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/runlog.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/session.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/state.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/strict.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/updates.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/validate.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/runtime/verify.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/argspec.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/board_values.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/coerce.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/command_contract.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/conditional_format.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/conditions.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/dashboard_filters.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/dashboard_pages.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/dashboard_review.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/data_profile.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/data_quality.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/dispatch.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/factory.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/input_fields.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/listing.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/local_time.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/mapping.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/openapi_types.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/protocol.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/read_queries.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/sdk_service.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/stored_stats.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/testing.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/text_dates.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/type_system.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/services/write_impact.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/skills/__init__.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/skills/installer.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/skills/steering.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/mammoth_cli/testing.py +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/activity.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/addon.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/agent.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/annotation.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/auth.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/automation.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/batch.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/billing.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/browse.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/calc.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/capability.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/client-app.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/completion.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/config.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/connector.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/context.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/dashboard.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/data-app.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/doctor.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/external-key.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/file.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/folder.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/job.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/link.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/log.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/notification.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/parameter.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/report.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/schedule.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/schema.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/skill.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/snippet.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/support.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/template.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/trash.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/upgrade.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/user.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/version.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/view.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/webhook.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/workflow.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/commands/workspace.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/edits-target.source.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/openapi-operations.yaml +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/manifests/schema-v1.json +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/openapi/metadata.json +0 -0
- {mammoth_cli-2.2.21 → mammoth_cli-2.2.23}/spec/openapi/openapi.json +0 -0
|
@@ -8,7 +8,7 @@ Run: `mammoth ai condition generate`. Exact input fields: `mammoth schema get ai
|
|
|
8
8
|
|
|
9
9
|
Example: `mammoth ai condition generate 123 --input '{"intent": "Summarize revenue by region"}'`. Placeholders are illustrative; resolve IDs and input from observed reads.
|
|
10
10
|
|
|
11
|
-
Result: `AiConditionGenerateResult`; mutation `
|
|
11
|
+
Result: `AiConditionGenerateResult`; mutation `read`, confirmation `none`, 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. Generated: lower("region") = 'east' (CD01). First attempt without dataview_id failed with job_failed/CD02 Dataview 4 not found (defaulted to wrong dataview) -- dataview_id must be passed explicitly. S…
|
|
14
14
|
|
|
@@ -18,7 +18,7 @@ Run: `mammoth ai expression generate`. Exact input fields: `mammoth schema get a
|
|
|
18
18
|
|
|
19
19
|
Example: `mammoth ai expression generate 123 --input '{"intent": "Summarize revenue by region", "mode": "sample"}'`. Placeholders are illustrative; resolve IDs and input from observed reads.
|
|
20
20
|
|
|
21
|
-
Result: `AiExpressionGenerateResult`; mutation `
|
|
21
|
+
Result: `AiExpressionGenerateResult`; mutation `read`, confirmation `none`, wait policy `not_async`.
|
|
22
22
|
|
|
23
23
|
Status on release: ran once on CLI 2.0.15 — re-verification 2026-09-18: exit 2 on release with CLI 2.0.15. Fix held: invalid mode surfaced as invalid_arguments with the SDK message before any request was sent: {"error":{"code":"invalid_arguments","message":"`mode` must be 'math' or 'metric', got 'sampl…
|
|
24
24
|
|
|
@@ -10,7 +10,7 @@ seam to the public SDK method named by the command's reviewed manifest
|
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
|
-
from typing import Any
|
|
13
|
+
from typing import Any, Protocol
|
|
14
14
|
|
|
15
15
|
from mammoth_cli.errors.envelope import (
|
|
16
16
|
CODE_INVALID_ARGUMENT,
|
|
@@ -44,6 +44,13 @@ from mammoth_cli.services.listing import (
|
|
|
44
44
|
HandlerResult = tuple[Any, dict[str, Any]]
|
|
45
45
|
|
|
46
46
|
|
|
47
|
+
_DATASET_GET_SYMBOL = "mammoth.api.datasets.DatasetsAPI.get"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class _SdkCaller(Protocol):
|
|
51
|
+
def call(self, sdk_symbol: str, /, **kwargs: object) -> object: ...
|
|
52
|
+
|
|
53
|
+
|
|
47
54
|
def _symbol(invocation: Invocation) -> str:
|
|
48
55
|
"""Return the reviewed backing SDK symbol for this command."""
|
|
49
56
|
record = command_by_id(invocation.command_id)
|
|
@@ -803,12 +810,16 @@ def dataset_create(invocation: Invocation) -> HandlerResult:
|
|
|
803
810
|
assert document is not None
|
|
804
811
|
_forward_optional(document, kwargs, ("folder_resource_id",))
|
|
805
812
|
with open_service(invocation) as (service, auth):
|
|
813
|
+
if invocation.dry_run:
|
|
814
|
+
_predict_final_name(invocation, service, dataset_spec, project_id)
|
|
806
815
|
data = service.call(_symbol(invocation), **kwargs)
|
|
807
816
|
# ``datasets.create`` returns a bare job handle and never waits. Block on
|
|
808
817
|
# it here (honoring ``--job-timeout``) so the command reports a finished
|
|
809
818
|
# dataset id instead of a job id the caller must poll separately.
|
|
810
819
|
settled = service.wait_if_job(data)
|
|
811
|
-
|
|
820
|
+
result = _created_dataset(data, settled)
|
|
821
|
+
_add_final_name(service, result, dataset_spec, project_id)
|
|
822
|
+
return result, _meta(invocation, auth.workspace_id, project_id)
|
|
812
823
|
|
|
813
824
|
|
|
814
825
|
def _created_dataset(handle: Any, settled: Any) -> dict[str, Any]:
|
|
@@ -836,6 +847,105 @@ def _created_dataset(handle: Any, settled: Any) -> dict[str, Any]:
|
|
|
836
847
|
return result
|
|
837
848
|
|
|
838
849
|
|
|
850
|
+
#: Pages (of 100) read to predict a final name; past it the answer is "a suffix may be added".
|
|
851
|
+
_NAME_PROBE_PAGES = 20
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
def _requested_name(dataset_spec: object) -> str | None:
|
|
855
|
+
"""The name the caller asked for: ``ds_name`` (clone, cloud) or ``name`` (sketch)."""
|
|
856
|
+
if not isinstance(dataset_spec, dict):
|
|
857
|
+
return None
|
|
858
|
+
for key in ("ds_name", "name"):
|
|
859
|
+
if isinstance(dataset_spec.get(key), str) and dataset_spec[key]:
|
|
860
|
+
return str(dataset_spec[key])
|
|
861
|
+
return None
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
def _project_dataset_names(service: _SdkCaller, project_id: int) -> tuple[set[str], bool]:
|
|
865
|
+
"""Every dataset name in the project and whether all of them were read."""
|
|
866
|
+
names: set[str] = set()
|
|
867
|
+
for page in range(_NAME_PROBE_PAGES):
|
|
868
|
+
data = service.call(
|
|
869
|
+
"mammoth.api.datasets.DatasetsAPI.list",
|
|
870
|
+
project_id=project_id,
|
|
871
|
+
limit=100,
|
|
872
|
+
offset=page * 100,
|
|
873
|
+
)
|
|
874
|
+
rows = data.get("datasets", []) if isinstance(data, dict) else []
|
|
875
|
+
names.update(r["name"] for r in rows if isinstance(r, dict) and "name" in r)
|
|
876
|
+
if len(rows) < 100:
|
|
877
|
+
return names, True
|
|
878
|
+
return names, False
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
def _name_impact(requested: str, names: set[str], complete: bool) -> dict[str, Any]:
|
|
882
|
+
"""The dry-run prediction for ``requested`` against the project's dataset ``names``."""
|
|
883
|
+
if requested not in names:
|
|
884
|
+
free: dict[str, Any] = {"requested_name": requested, "name_taken": False}
|
|
885
|
+
if complete:
|
|
886
|
+
return {**free, "final_name": requested}
|
|
887
|
+
return {**free, "note": "Not all datasets were read; a numeric suffix is added if taken."}
|
|
888
|
+
impact: dict[str, Any] = {"requested_name": requested, "name_taken": True}
|
|
889
|
+
if not complete:
|
|
890
|
+
impact["note"] = f"'{requested}' is taken; a numeric suffix will be added to the name."
|
|
891
|
+
return impact
|
|
892
|
+
suffix = next(i for i in range(2, len(names) + 3) if f"{requested} {i}" not in names)
|
|
893
|
+
impact["final_name"] = f"{requested} {suffix}"
|
|
894
|
+
impact["note"] = (
|
|
895
|
+
f"'{requested}' is taken; the dataset will be named '{impact['final_name']}'. "
|
|
896
|
+
"Ask the user whether to use a different name."
|
|
897
|
+
)
|
|
898
|
+
return impact
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
def _predict_final_name(
|
|
902
|
+
invocation: Invocation, service: _SdkCaller, dataset_spec: object, project_id: int
|
|
903
|
+
) -> None:
|
|
904
|
+
"""Dry run: say whether the requested name is taken and what the server will name it.
|
|
905
|
+
|
|
906
|
+
The server (``Datasource.get_unique_name``) tries ``name``, ``name 2``, ``name 3``...
|
|
907
|
+
against the project's live dataset names, so the answer is computed the same way.
|
|
908
|
+
"""
|
|
909
|
+
requested = _requested_name(dataset_spec)
|
|
910
|
+
if requested is not None:
|
|
911
|
+
names, complete = _project_dataset_names(service, project_id)
|
|
912
|
+
object.__setattr__(invocation, "predicted_impact", _name_impact(requested, names, complete))
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
def _add_final_name(
|
|
916
|
+
service: _SdkCaller, result: dict[str, Any], dataset_spec: object, project_id: int
|
|
917
|
+
) -> None:
|
|
918
|
+
"""Add the name the server actually gave the new dataset to a create result.
|
|
919
|
+
|
|
920
|
+
The server appends a suffix when the requested name is taken, so the
|
|
921
|
+
requested name is not the dataset's name. The dataset already exists, so a failed
|
|
922
|
+
lookup must not fail (and invite a duplicate) create; it is reported in ``note``.
|
|
923
|
+
"""
|
|
924
|
+
dataset_id = result.get("dataset_id")
|
|
925
|
+
if dataset_id is None:
|
|
926
|
+
return
|
|
927
|
+
try:
|
|
928
|
+
record = service.call(
|
|
929
|
+
_DATASET_GET_SYMBOL, dataset_id=dataset_id, project_id=project_id, fields="id,name"
|
|
930
|
+
)
|
|
931
|
+
except CliError as exc: # the service maps every SDK API/HTTP error to CliError
|
|
932
|
+
result["note"] = (
|
|
933
|
+
f"Created dataset {dataset_id}; its final name could not be read back "
|
|
934
|
+
f"({exc.code}). Run dataset get {dataset_id}."
|
|
935
|
+
)
|
|
936
|
+
return
|
|
937
|
+
if not isinstance(record, dict):
|
|
938
|
+
return
|
|
939
|
+
name = record.get("dataset", record).get("name")
|
|
940
|
+
if not isinstance(name, str):
|
|
941
|
+
return
|
|
942
|
+
result["name"] = name
|
|
943
|
+
requested = _requested_name(dataset_spec)
|
|
944
|
+
if requested is not None and requested != name:
|
|
945
|
+
result["requested_name"] = requested
|
|
946
|
+
result["note"] = f"The name '{requested}' was taken, so the dataset is named '{name}'."
|
|
947
|
+
|
|
948
|
+
|
|
839
949
|
def dataset_create_from_pdf(invocation: Invocation) -> HandlerResult:
|
|
840
950
|
"""Create dataset(s) from tables extracted out of a PDF file."""
|
|
841
951
|
project_id = require_project(invocation)
|
|
@@ -580,9 +580,9 @@ def _report_line(where: str, warning: dict[str, Any]) -> str:
|
|
|
580
580
|
return f"{subject}: {warning.get('issue')}. {warning.get('detail', '')}".strip()
|
|
581
581
|
|
|
582
582
|
|
|
583
|
-
def
|
|
584
|
-
"""The
|
|
585
|
-
raw = invocation.positional(
|
|
583
|
+
def _scoped_id(invocation: Invocation, name: str) -> int | None:
|
|
584
|
+
"""The integer positional ``name`` (``dataset_id``, ``view_id``), or None if omitted."""
|
|
585
|
+
raw = invocation.positional(name)
|
|
586
586
|
if raw is None:
|
|
587
587
|
return None
|
|
588
588
|
try:
|
|
@@ -590,11 +590,28 @@ def _scoped_dataset_id(invocation: Invocation) -> int | None:
|
|
|
590
590
|
except ValueError as exc:
|
|
591
591
|
raise CliError(
|
|
592
592
|
code=CODE_INVALID_ARGUMENT,
|
|
593
|
-
message=f"The
|
|
593
|
+
message=f"The {name.replace('_', ' ')} argument '{raw}' is not an integer.",
|
|
594
594
|
exit_status=EXIT_USAGE,
|
|
595
595
|
) from exc
|
|
596
596
|
|
|
597
597
|
|
|
598
|
+
def _scoped_dataset_id(invocation: Invocation) -> int | None:
|
|
599
|
+
"""The DATASET_ID that narrows ``project check`` to one dataset, or None."""
|
|
600
|
+
return _scoped_id(invocation, "dataset_id")
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
def _scoped_view_id(invocation: Invocation, dataset_id: int | None) -> int | None:
|
|
604
|
+
"""The VIEW_ID that picks which view of DATASET_ID ``project check`` reads, or None."""
|
|
605
|
+
view_id = _scoped_id(invocation, "view_id")
|
|
606
|
+
if view_id is not None and dataset_id is None:
|
|
607
|
+
raise CliError(
|
|
608
|
+
code=CODE_INVALID_ARGUMENT,
|
|
609
|
+
message="A view id needs its dataset: project check PROJECT_ID DATASET_ID VIEW_ID.",
|
|
610
|
+
exit_status=EXIT_USAGE,
|
|
611
|
+
)
|
|
612
|
+
return view_id
|
|
613
|
+
|
|
614
|
+
|
|
598
615
|
def _datasets_to_check(service: Any, project_id: int, scoped: int | None) -> list[Any]:
|
|
599
616
|
"""Every dataset of the project, or only the named one -- never a walk when scoped."""
|
|
600
617
|
if scoped is not None:
|
|
@@ -647,14 +664,16 @@ def _map_checks[T](
|
|
|
647
664
|
)
|
|
648
665
|
|
|
649
666
|
|
|
650
|
-
def _preview_dataset(
|
|
667
|
+
def _preview_dataset(
|
|
668
|
+
service: Any, _auth: Any, args: tuple[Any, int | None, int | None]
|
|
669
|
+
) -> dict[str, Any]:
|
|
651
670
|
from mammoth_cli.commands.view import upload_preview
|
|
652
671
|
|
|
653
|
-
dataset, project_id = args
|
|
672
|
+
dataset, project_id, view_id = args
|
|
654
673
|
dataset_id = dataset.get("id") if isinstance(dataset, dict) else None
|
|
655
674
|
if not isinstance(dataset_id, int):
|
|
656
675
|
return {"preview_error": "dataset entry has no integer id"}
|
|
657
|
-
return upload_preview(service, dataset_id, project_id)
|
|
676
|
+
return upload_preview(service, dataset_id, project_id, view_id)
|
|
658
677
|
|
|
659
678
|
|
|
660
679
|
def _check_dashboard(invocation: Invocation) -> Callable[[Any, Any, Any], dict[str, Any]]:
|
|
@@ -678,6 +697,7 @@ def _dataset_entry(dataset: dict[str, Any], preview: dict[str, Any]) -> dict[str
|
|
|
678
697
|
"dataset_id": dataset.get("id"),
|
|
679
698
|
"dataset_name": dataset.get("name"),
|
|
680
699
|
"view_id": preview["view_id"],
|
|
700
|
+
"view_name": preview.get("view_name"),
|
|
681
701
|
"row_count": preview.get("row_count"),
|
|
682
702
|
"column_warnings": preview.get("column_warnings", []),
|
|
683
703
|
"column_checks": preview["column_checks"],
|
|
@@ -711,6 +731,7 @@ def _dataset_status(dataset: dict[str, Any], preview: dict[str, Any]) -> dict[st
|
|
|
711
731
|
return {
|
|
712
732
|
**row,
|
|
713
733
|
"view_id": preview["view_id"],
|
|
734
|
+
"view_name": preview.get("view_name"),
|
|
714
735
|
"freshness": preview.get("freshness", {"state": "unknown"}),
|
|
715
736
|
"data_quality": {
|
|
716
737
|
"warnings": len(preview.get("column_warnings", [])),
|
|
@@ -745,7 +766,9 @@ def project_check(invocation: Invocation) -> HandlerResult:
|
|
|
745
766
|
one line per finding; ``resources`` has one status row per dataset and
|
|
746
767
|
dashboard (freshness apart from data quality, or the error that stopped
|
|
747
768
|
its check). Resources are checked several at once. Given a DATASET_ID it
|
|
748
|
-
reads only that dataset's first view (no dataset list, no dashboards)
|
|
769
|
+
reads only that dataset's first view (no dataset list, no dashboards);
|
|
770
|
+
given VIEW_ID as well it reads that view instead. Every status row names
|
|
771
|
+
the ``view_id`` and ``view_name`` it checked.
|
|
749
772
|
Cold-agent evals (2.0.41) left one column's blanks undecided in every
|
|
750
773
|
run, because the warning sat in an earlier result.
|
|
751
774
|
"""
|
|
@@ -758,6 +781,7 @@ def project_check(invocation: Invocation) -> HandlerResult:
|
|
|
758
781
|
skipped: list[dict[str, Any]] = []
|
|
759
782
|
statuses: list[dict[str, Any]] = []
|
|
760
783
|
scoped_dataset = _scoped_dataset_id(invocation)
|
|
784
|
+
scoped_view = _scoped_view_id(invocation, scoped_dataset)
|
|
761
785
|
with open_service(invocation) as (service, auth):
|
|
762
786
|
every_dataset = _datasets_to_check(service, project_id, scoped_dataset)
|
|
763
787
|
datasets = every_dataset[:_CHECK_MAX_DATASETS]
|
|
@@ -773,7 +797,7 @@ def project_check(invocation: Invocation) -> HandlerResult:
|
|
|
773
797
|
invocation,
|
|
774
798
|
service,
|
|
775
799
|
auth,
|
|
776
|
-
[(dataset, project_id) for dataset in datasets],
|
|
800
|
+
[(dataset, project_id, scoped_view) for dataset in datasets],
|
|
777
801
|
_preview_dataset,
|
|
778
802
|
)
|
|
779
803
|
for dataset, preview in zip(datasets, previews, strict=True):
|
|
@@ -788,13 +812,14 @@ def project_check(invocation: Invocation) -> HandlerResult:
|
|
|
788
812
|
)
|
|
789
813
|
continue
|
|
790
814
|
entry = _dataset_entry(dataset, preview)
|
|
791
|
-
if "other_views" in preview:
|
|
815
|
+
if "other_views" in preview and scoped_view is None:
|
|
792
816
|
to_report.append(_other_views_line(dataset, preview))
|
|
793
817
|
views.append(entry)
|
|
794
818
|
checked.append(
|
|
795
819
|
{
|
|
796
820
|
"dataset_id": dataset["id"],
|
|
797
821
|
"view_id": preview["view_id"],
|
|
822
|
+
"view_name": preview.get("view_name"),
|
|
798
823
|
"rows_checked": preview["column_checks"]["rows_checked"],
|
|
799
824
|
}
|
|
800
825
|
)
|
|
@@ -834,7 +859,13 @@ def project_check(invocation: Invocation) -> HandlerResult:
|
|
|
834
859
|
"checked": checked,
|
|
835
860
|
"skipped": skipped,
|
|
836
861
|
**(
|
|
837
|
-
{
|
|
862
|
+
{
|
|
863
|
+
"scope": {
|
|
864
|
+
"dataset_id": scoped_dataset,
|
|
865
|
+
**({"view_id": scoped_view} if scoped_view else {}),
|
|
866
|
+
"dashboards": "not checked",
|
|
867
|
+
}
|
|
868
|
+
}
|
|
838
869
|
if scoped_dataset
|
|
839
870
|
else {}
|
|
840
871
|
),
|
|
@@ -4096,8 +4096,17 @@ _DATAVIEW_LIST_SYMBOL = "mammoth.api.dataviews.DataviewsAPI.list"
|
|
|
4096
4096
|
_UPLOAD_SAMPLE_ROWS = 3
|
|
4097
4097
|
|
|
4098
4098
|
|
|
4099
|
-
def
|
|
4100
|
-
"""The
|
|
4099
|
+
def _select_view(views: list[Any], view_id: int | None) -> dict[str, Any] | None:
|
|
4100
|
+
"""The view with ``view_id``, or the first (most recent) one when none is named."""
|
|
4101
|
+
if view_id is None:
|
|
4102
|
+
return views[0]
|
|
4103
|
+
return next((v for v in views if isinstance(v, dict) and v.get("id") == view_id), None)
|
|
4104
|
+
|
|
4105
|
+
|
|
4106
|
+
def upload_preview(
|
|
4107
|
+
service: Any, dataset_id: int, project_id: int | None, view_id: int | None = None
|
|
4108
|
+
) -> dict[str, Any]:
|
|
4109
|
+
"""A view of a dataset (the first unless ``view_id``): columns, types, sample rows, warnings.
|
|
4101
4110
|
|
|
4102
4111
|
``before_dashboard`` names the columns to add before any dashboard is
|
|
4103
4112
|
made (revenue from a unit price and a quantity), since a dashboard does
|
|
@@ -4116,16 +4125,19 @@ def upload_preview(service: Any, dataset_id: int, project_id: int | None) -> dic
|
|
|
4116
4125
|
views = listing.get("dataviews") if isinstance(listing, dict) else None
|
|
4117
4126
|
if not isinstance(views, list) or not views or not isinstance(views[0], dict):
|
|
4118
4127
|
return {"preview_error": f"dataset {dataset_id} has no view to preview"}
|
|
4128
|
+
chosen = _select_view(views, view_id)
|
|
4129
|
+
if chosen is None:
|
|
4130
|
+
return {"preview_error": f"dataset {dataset_id} has no view {view_id}"}
|
|
4119
4131
|
# A dataset with more than one live view has one previewed here; the
|
|
4120
4132
|
# rest are named (id + name) so a caller (``project.check``) can say
|
|
4121
4133
|
# a view besides the one checked exists, rather than silently acting
|
|
4122
4134
|
# on the single view this function happens to preview.
|
|
4123
4135
|
other_views = [
|
|
4124
4136
|
{"id": other.get("id"), "name": other.get("name")}
|
|
4125
|
-
for other in views
|
|
4126
|
-
if isinstance(other, dict) and isinstance(other.get("id"), int)
|
|
4137
|
+
for other in views
|
|
4138
|
+
if other is not chosen and isinstance(other, dict) and isinstance(other.get("id"), int)
|
|
4127
4139
|
]
|
|
4128
|
-
record = apply_column_renames(
|
|
4140
|
+
record = apply_column_renames(chosen)
|
|
4129
4141
|
view_id = record.get("id")
|
|
4130
4142
|
if not isinstance(view_id, int):
|
|
4131
4143
|
return {"preview_error": f"dataset {dataset_id}'s first view has no id"}
|
|
@@ -4150,6 +4162,7 @@ def upload_preview(service: Any, dataset_id: int, project_id: int | None) -> dic
|
|
|
4150
4162
|
checks, warnings = _check_columns(rows, types, view_id, dataset_id)
|
|
4151
4163
|
preview: dict[str, Any] = {
|
|
4152
4164
|
"view_id": view_id,
|
|
4165
|
+
"view_name": record.get("name"),
|
|
4153
4166
|
"row_count": record.get("row_count"),
|
|
4154
4167
|
"columns": types,
|
|
4155
4168
|
"sample_rows": rows[:_UPLOAD_SAMPLE_ROWS],
|
|
@@ -61,6 +61,7 @@ from mammoth_cli.runtime.session import open_service, resolved_project
|
|
|
61
61
|
from mammoth_cli.services.command_contract import bind_command_inputs
|
|
62
62
|
from mammoth_cli.services.conditions import CONDITION_KWARG
|
|
63
63
|
from mammoth_cli.services.input_fields import TASK_COUNT_FIELD
|
|
64
|
+
from mammoth_cli.services.sql_check import check_sql_binds
|
|
64
65
|
from mammoth_cli.services.write_impact import (
|
|
65
66
|
ImpactRead,
|
|
66
67
|
Measure,
|
|
@@ -923,7 +924,30 @@ def view_transform_add_sql(invocation: Invocation) -> HandlerResult:
|
|
|
923
924
|
_require_field(document, "query")
|
|
924
925
|
assert document is not None
|
|
925
926
|
kwargs = _bind_transform_inputs(invocation, document)
|
|
926
|
-
return _dispatch_view(
|
|
927
|
+
return _dispatch_view(
|
|
928
|
+
invocation, view_id, "add_sql", prepare=_sql_binding_check(invocation, view_id), **kwargs
|
|
929
|
+
)
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
def _sql_binding_check(
|
|
933
|
+
invocation: Invocation, view_id: int
|
|
934
|
+
) -> Callable[[Any, int, dict[str, Any]], Any]:
|
|
935
|
+
"""A ``prepare`` hook: a dry run fails with ``would_fail`` when the SQL names a column
|
|
936
|
+
the step cannot bind (see :mod:`mammoth_cli.services.sql_check`). A real run is unchanged."""
|
|
937
|
+
|
|
938
|
+
def check(service: Any, dataset_id: int, kwargs: dict[str, Any]) -> Any:
|
|
939
|
+
if invocation.dry_run:
|
|
940
|
+
view = service.call(
|
|
941
|
+
_DATAVIEW_GET_SYMBOL,
|
|
942
|
+
dataset_id=dataset_id,
|
|
943
|
+
dataview_id=view_id,
|
|
944
|
+
project_id=resolved_project(invocation),
|
|
945
|
+
)
|
|
946
|
+
if isinstance(view, dict):
|
|
947
|
+
check_sql_binds(str(kwargs.get("query", "")), view)
|
|
948
|
+
return None
|
|
949
|
+
|
|
950
|
+
return check
|
|
927
951
|
|
|
928
952
|
|
|
929
953
|
def view_transform_ai(invocation: Invocation) -> HandlerResult:
|
|
@@ -56,6 +56,7 @@ CODE_JOB_FAILED = "job_failed"
|
|
|
56
56
|
CODE_INTERRUPTED = "interrupted"
|
|
57
57
|
CODE_UNSUPPORTED_CONTRACT = "unsupported_contract"
|
|
58
58
|
CODE_NO_OP = "no_op"
|
|
59
|
+
CODE_WOULD_FAIL = "would_fail"
|
|
59
60
|
|
|
60
61
|
# User-safe, one-line summaries shown to the customer instead of the model-facing
|
|
61
62
|
# ``message``/``hint``. Plain language only: no command names, ids, field names
|
|
@@ -173,6 +174,7 @@ ERROR_SUMMARIES: dict[str, str] = {
|
|
|
173
174
|
"upgrade_failed": "The update didn't complete.",
|
|
174
175
|
"usage_error": _S_BAD_REQUEST,
|
|
175
176
|
"view_in_draft": "This view is still a draft and can't be used yet.",
|
|
177
|
+
"would_fail": "This step would fail when it runs, so it was not added.",
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
#: Shown for a code with no entry (a runtime backstop only; the exhaustiveness
|
|
@@ -395,14 +395,22 @@ POSITIONAL_OVERRIDES: dict[str, tuple[PositionalSpec, ...]] = {
|
|
|
395
395
|
# active project). The SDK signature marks it required or omits it, so the
|
|
396
396
|
# dual-sourced optional locator is authored here.
|
|
397
397
|
"project.get": _optional_project_id(),
|
|
398
|
-
# ``project check PROJECT_ID DATASET_ID`` narrows the check to one dataset
|
|
398
|
+
# ``project check PROJECT_ID DATASET_ID [VIEW_ID]`` narrows the check to one dataset,
|
|
399
|
+
# and to one of its views (its first, most recent one when VIEW_ID is omitted).
|
|
399
400
|
"project.check": (
|
|
400
401
|
*_optional_project_id(),
|
|
401
402
|
PositionalSpec(
|
|
402
403
|
name="dataset_id",
|
|
403
404
|
type=int,
|
|
404
405
|
required=False,
|
|
405
|
-
help="Check only this dataset
|
|
406
|
+
help="Check only this dataset (its first view unless VIEW_ID is given); "
|
|
407
|
+
"no other dataset or dashboard is read.",
|
|
408
|
+
),
|
|
409
|
+
PositionalSpec(
|
|
410
|
+
name="view_id",
|
|
411
|
+
type=int,
|
|
412
|
+
required=False,
|
|
413
|
+
help="Check this view of DATASET_ID instead of its first (most recent) one.",
|
|
406
414
|
),
|
|
407
415
|
),
|
|
408
416
|
"project.needs-attention": _optional_project_id(),
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Check a SQL step's column names against what it will bind to, before it is added.
|
|
2
|
+
|
|
3
|
+
``FROM "view:<id>"`` binds to the names the pipeline produced (the ``metadata`` of the
|
|
4
|
+
view's latest data), not to a display-only rename (``display_properties.COLUMN_NAMES``),
|
|
5
|
+
which ``view get`` shows. A query naming the renamed column is accepted by the CLI and
|
|
6
|
+
fails in the backend's DuckDB with a Binder Error, so a dry run says so first.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import re
|
|
12
|
+
from collections.abc import Mapping
|
|
13
|
+
|
|
14
|
+
from mammoth_cli.errors.envelope import CODE_WOULD_FAIL, EXIT_USAGE, CliError
|
|
15
|
+
|
|
16
|
+
_STRING = re.compile(r"'(?:[^']|'')*'")
|
|
17
|
+
_QUOTED = re.compile(r'"((?:[^"]|"")+)"')
|
|
18
|
+
_ALIAS = re.compile(r'\bAS\s+("(?:[^"]|"")+"|\w+)|("(?:[^"]|"")+"|\w+)\s+AS\s*\(', re.IGNORECASE)
|
|
19
|
+
_TABLE = re.compile(r'\b(?:FROM|JOIN)\s+("(?:[^"]|"")+")', re.IGNORECASE)
|
|
20
|
+
_VIEW_REF = re.compile(r"view:\d+")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _unquote(name: str) -> str:
|
|
24
|
+
return name[1:-1].replace('""', '"') if name.startswith('"') else name
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _declared(query: str) -> set[str]:
|
|
28
|
+
"""Names the query itself introduces (aliases, CTEs) or reads as a table."""
|
|
29
|
+
aliases = {_unquote(a or b) for a, b in _ALIAS.findall(query)}
|
|
30
|
+
tables = {_unquote(t) for t in _TABLE.findall(query)}
|
|
31
|
+
return {name.casefold() for name in aliases | tables}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _identifiers(query: str, renamed: Mapping[str, str]) -> list[str]:
|
|
35
|
+
"""Quoted identifiers, plus any bare word that is a renamed column's new name."""
|
|
36
|
+
found = [m for m in _QUOTED.findall(query) if not _VIEW_REF.fullmatch(m)]
|
|
37
|
+
words = {w.casefold() for w in re.findall(r"\w+", _QUOTED.sub(" ", query))}
|
|
38
|
+
found += [new for new in renamed if new.casefold() in words]
|
|
39
|
+
return list(dict.fromkeys(name.replace('""', '"') for name in found))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _renames(view: Mapping[str, object]) -> dict[str, str]:
|
|
43
|
+
"""``{new name: pipeline name}`` for each display-only rename of the view."""
|
|
44
|
+
display = view.get("display_properties")
|
|
45
|
+
names = display.get("COLUMN_NAMES") if isinstance(display, dict) else None
|
|
46
|
+
metadata = view.get("metadata")
|
|
47
|
+
if not isinstance(names, dict) or not isinstance(metadata, list):
|
|
48
|
+
return {}
|
|
49
|
+
by_internal = {c.get("internal_name"): c.get("display_name") for c in metadata}
|
|
50
|
+
return {new: by_internal[i] for i, new in names.items() if by_internal.get(i)}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def check_sql_binds(query: str, view: Mapping[str, object]) -> None:
|
|
54
|
+
"""Raise ``would_fail`` when ``query`` names a column the step cannot bind.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
query: The step's SQL.
|
|
58
|
+
view: The raw ``dataview get`` record (its ``metadata`` is the bindable schema).
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
CliError: ``would_fail``, with the unknown name and the candidate columns.
|
|
62
|
+
"""
|
|
63
|
+
metadata = view.get("metadata")
|
|
64
|
+
rows = metadata if isinstance(metadata, list) else []
|
|
65
|
+
columns = [
|
|
66
|
+
str(c["display_name"]) for c in rows if isinstance(c, dict) and c.get("display_name")
|
|
67
|
+
]
|
|
68
|
+
if not columns:
|
|
69
|
+
return
|
|
70
|
+
renamed = _renames(view)
|
|
71
|
+
text = _STRING.sub("''", query)
|
|
72
|
+
known = {c.casefold() for c in columns} | _declared(text)
|
|
73
|
+
for name in _identifiers(text, renamed):
|
|
74
|
+
if name.casefold() not in known:
|
|
75
|
+
raise _unbound(name, columns, renamed.get(name))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _unbound(name: str, columns: list[str], was: str | None) -> CliError:
|
|
79
|
+
hint = f'Use "{was}": "{name}" is only a display name for it.' if was else None
|
|
80
|
+
return CliError(
|
|
81
|
+
code=CODE_WOULD_FAIL,
|
|
82
|
+
message=f'Referenced column "{name}" not found. Candidate bindings: '
|
|
83
|
+
+ ", ".join(f'"{c}"' for c in columns),
|
|
84
|
+
exit_status=EXIT_USAGE,
|
|
85
|
+
hint=hint or "Use one of the candidate columns; nothing was added.",
|
|
86
|
+
details={"unknown_column": name, "candidate_columns": columns},
|
|
87
|
+
)
|
|
@@ -18,12 +18,11 @@ commands:
|
|
|
18
18
|
sdk_conversion: Call mammoth.api.ai.AIAPI.condition_generate with validated request fields.
|
|
19
19
|
request_model: AiConditionGenerateRequest
|
|
20
20
|
result_model: AiConditionGenerateResult
|
|
21
|
-
mutation_class:
|
|
22
|
-
edits_target: false
|
|
21
|
+
mutation_class: read
|
|
23
22
|
confirmation: none
|
|
24
23
|
wait_policy: not_async
|
|
25
24
|
pagination_policy: none
|
|
26
|
-
acceptance_evidence:
|
|
25
|
+
acceptance_evidence: live_read_only
|
|
27
26
|
live_test: LT-AI-CONDITION-GENERATE
|
|
28
27
|
live_exemption_reason: null
|
|
29
28
|
contract_fixture: null
|
|
@@ -41,7 +40,6 @@ commands:
|
|
|
41
40
|
undo_test: null
|
|
42
41
|
known_restrictions: null
|
|
43
42
|
reviewed_by: primary
|
|
44
|
-
no_readback: "generates a condition preview; nothing is persisted to read back"
|
|
45
43
|
- command_id: ai.expression.generate
|
|
46
44
|
command_path: ai expression generate
|
|
47
45
|
disposition: command
|
|
@@ -60,12 +58,11 @@ commands:
|
|
|
60
58
|
sdk_conversion: Call mammoth.api.ai.AIAPI.expression_generate with validated request fields.
|
|
61
59
|
request_model: AiExpressionGenerateRequest
|
|
62
60
|
result_model: AiExpressionGenerateResult
|
|
63
|
-
mutation_class:
|
|
64
|
-
edits_target: false
|
|
61
|
+
mutation_class: read
|
|
65
62
|
confirmation: none
|
|
66
63
|
wait_policy: not_async
|
|
67
64
|
pagination_policy: none
|
|
68
|
-
acceptance_evidence:
|
|
65
|
+
acceptance_evidence: live_read_only
|
|
69
66
|
live_test: LT-AI-EXPRESSION-GENERATE
|
|
70
67
|
live_exemption_reason: null
|
|
71
68
|
contract_fixture: null
|
|
@@ -84,7 +81,6 @@ commands:
|
|
|
84
81
|
undo_test: null
|
|
85
82
|
known_restrictions: null
|
|
86
83
|
reviewed_by: primary
|
|
87
|
-
no_readback: "generates an expression preview; nothing is persisted to read back"
|
|
88
84
|
- command_id: ai.retention.condition
|
|
89
85
|
command_path: ai retention condition
|
|
90
86
|
disposition: command
|
|
@@ -252,6 +252,8 @@ commands:
|
|
|
252
252
|
dataset/view IDs and delete only IDs created by this task. A weburl dataset is a one-time copy that
|
|
253
253
|
keeps no source details to refresh from, so automation's run_data_retrieval task cannot refresh it
|
|
254
254
|
(only a cloud-connected dataset can be refreshed); say so rather than scheduling a refresh for it.
|
|
255
|
+
The result's name is the dataset's real name; when the requested name was taken the server adds a suffix,
|
|
256
|
+
and requested_name and note say so. Use name, not the name you asked for.
|
|
255
257
|
reviewed_by: primary
|
|
256
258
|
- command_id: dataset.create-from-pdf
|
|
257
259
|
command_path: dataset create-from-pdf
|
|
@@ -98,7 +98,13 @@ commands:
|
|
|
98
98
|
required: false
|
|
99
99
|
metavar: DATASET_ID
|
|
100
100
|
falls_back_to_field: null
|
|
101
|
-
help: Check only this dataset
|
|
101
|
+
help: Check only this dataset (its first view unless VIEW_ID is given); no other dataset or dashboard is read.
|
|
102
|
+
- name: view_id
|
|
103
|
+
type: int
|
|
104
|
+
required: false
|
|
105
|
+
metavar: VIEW_ID
|
|
106
|
+
falls_back_to_field: null
|
|
107
|
+
help: Check this view of DATASET_ID instead of its first (most recent) one.
|
|
102
108
|
options: []
|
|
103
109
|
sdk_symbol: mammoth_cli.commands.project.project_check
|
|
104
110
|
sdk_conversion: Call mammoth_cli.commands.project.project_check with validated request fields.
|
|
@@ -124,7 +130,7 @@ commands:
|
|
|
124
130
|
- CT-PROJECT-CHECK-ERROR
|
|
125
131
|
draft_test: null
|
|
126
132
|
undo_test: null
|
|
127
|
-
known_restrictions: Reads the first view of each dataset (the one uploads and the playbooks use) and one data page per view, six resources at a time. `resources` has one status row per dataset and dashboard with its freshness (in_sync, out_of_sync or running, with data_updated_at) kept apart from its data quality (warning count), or the error that stopped its check. Given DATASET_ID it reads only that dataset's first view and skips the dashboards.
|
|
133
|
+
known_restrictions: Reads the first view of each dataset (the one uploads and the playbooks use) and one data page per view, six resources at a time. `resources` has one status row per dataset and dashboard with its freshness (in_sync, out_of_sync or running, with data_updated_at) kept apart from its data quality (warning count), or the error that stopped its check. Given DATASET_ID it reads only that dataset's first view and skips the dashboards; also given VIEW_ID it reads that view instead. Every status row names the view_id and view_name it checked, so compare it with the view the work was on.
|
|
128
134
|
reviewed_by: primary
|
|
129
135
|
- command_id: project.checkpoint.list
|
|
130
136
|
command_path: project checkpoint list
|
|
@@ -421,14 +421,14 @@ sdk_methods:
|
|
|
421
421
|
- sdk_symbol: mammoth.api.ai.AIAPI.condition_generate
|
|
422
422
|
canonical_command: ai.condition.generate
|
|
423
423
|
alias_of: null
|
|
424
|
-
mutation_class:
|
|
424
|
+
mutation_class: read
|
|
425
425
|
wait_policy: null
|
|
426
426
|
pagination_policy: null
|
|
427
427
|
openapi_operation_ids: []
|
|
428
428
|
- sdk_symbol: mammoth.api.ai.AIAPI.expression_generate
|
|
429
429
|
canonical_command: ai.expression.generate
|
|
430
430
|
alias_of: null
|
|
431
|
-
mutation_class:
|
|
431
|
+
mutation_class: read
|
|
432
432
|
wait_policy: null
|
|
433
433
|
pagination_policy: null
|
|
434
434
|
openapi_operation_ids: []
|