mammoth-cli 2.0.72__tar.gz → 2.0.73__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.0.72 → mammoth_cli-2.0.73}/PKG-INFO +2 -2
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/__init__.py +1 -1
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +55 -58
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +4 -1
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/scheduling.md +4 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/registry.py +48 -4
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/schema.py +113 -9
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/view.py +96 -10
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/view_ops.py +7 -1
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/verify.py +93 -15
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/pyproject.toml +2 -2
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/dataset.yaml +3 -1
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/.gitignore +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/LICENSE +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/README.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/__main__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/app.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/about-mammoth.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-qa.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view-transform.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/activity.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/addon.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/agent.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/ai.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/annotation.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/auth.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/automation.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/batch.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/billing.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/browse.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/capability.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/client_app.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/completion.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/config.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/connector.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/context.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/dashboard.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/data_app.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/dataset.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/doctor.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/external_key.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/file.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/folder.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/job.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/notification.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/parameter.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/project.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/report.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/schedule.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/skill.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/snippet.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/support.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/template.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/trash.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/upgrade.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/user.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/webhook.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/workflow.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/commands/workspace.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/context/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/context/credentials.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/context/endpoint.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/context/profiles.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/context/resolver.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/contracts/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/contracts/auth.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/embed.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/errors/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/errors/envelope.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/manifest/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/manifest/loader.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/messages/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/output/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/output/envelope.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/output/normalize.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/output/policy.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/output/progress.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/output/render.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/py.typed +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/confirm.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/dryrun.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/embedded.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/executor.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/input_loader.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/invocation.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/options.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/parents.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/runlog.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/session.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/strict.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/updates.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/runtime/validate.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/argspec.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/coerce.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/command_contract.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/conditions.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/dashboard_pages.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/dashboard_review.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/data_quality.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/dispatch.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/factory.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/input_fields.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/mapping.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/openapi_types.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/positionals.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/protocol.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/sdk_service.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/testing.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/services/type_system.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/skills/__init__.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/skills/installer.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/skills/steering.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/mammoth_cli/testing.py +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/activity.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/addon.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/agent.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/ai.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/annotation.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/auth.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/automation.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/batch.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/billing.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/browse.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/capability.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/client-app.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/completion.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/config.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/connector.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/context.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/dashboard.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/data-app.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/doctor.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/external-key.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/file.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/folder.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/job.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/log.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/notification.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/parameter.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/project.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/report.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/schedule.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/schema.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/skill.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/snippet.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/support.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/template.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/trash.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/upgrade.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/user.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/version.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/view.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/webhook.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/workflow.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/commands/workspace.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/openapi-operations.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/schema-v1.json +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/sdk-catalog.source.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/manifests/sdk-methods.yaml +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/openapi/metadata.json +0 -0
- {mammoth_cli-2.0.72 → mammoth_cli-2.0.73}/spec/openapi/openapi.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mammoth-cli
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.73
|
|
4
4
|
Summary: Command-line interface for the Mammoth Analytics platform
|
|
5
5
|
Project-URL: homepage, https://mammoth.io
|
|
6
6
|
Project-URL: repository, https://github.com/EdgeMetric/mammothsdk
|
|
@@ -17,7 +17,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
17
17
|
Requires-Python: <3.15,>=3.12
|
|
18
18
|
Requires-Dist: jsonschema>=4.20
|
|
19
19
|
Requires-Dist: keyring<26,>=25.7
|
|
20
|
-
Requires-Dist: mammoth-io<0.8,>=0.7.
|
|
20
|
+
Requires-Dist: mammoth-io<0.8,>=0.7.33
|
|
21
21
|
Requires-Dist: platformdirs<5,>=4.10
|
|
22
22
|
Requires-Dist: pydantic<3,>=2.12.5
|
|
23
23
|
Requires-Dist: pyyaml<7,>=6
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mammoth-cli
|
|
3
|
-
version: 2.0.
|
|
3
|
+
version: 2.0.73
|
|
4
4
|
description: "Use Mammoth Analytics from a terminal: install or authenticate the CLI, discover its live command contract, and safely manage projects, data, views, pipelines (join, merge, pivot, filter, clean), dashboards, exports, and handoffs."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Mammoth CLI
|
|
8
8
|
|
|
9
|
-
Use this skill for Mammoth shell work, not
|
|
10
|
-
|
|
11
|
-
envelope,
|
|
9
|
+
Use this skill for Mammoth shell work, not Python SDK integration. The CLI
|
|
10
|
+
is the contract: it validates requests locally and returns one JSON
|
|
11
|
+
envelope, with no flag needed for that when piped.
|
|
12
12
|
|
|
13
13
|
## What Mammoth is
|
|
14
14
|
|
|
@@ -18,9 +18,8 @@ calculated in a **pipeline** of tasks on a **view**, and the result is
|
|
|
18
18
|
published as a dashboard or delivered as a CSV, a database table, a BI feed
|
|
19
19
|
or another dataset. The pipeline re-runs when new data arrives, so build the
|
|
20
20
|
steps in Mammoth rather than computing a result locally. The web app and
|
|
21
|
-
this CLI call the same API: every
|
|
22
|
-
|
|
23
|
-
capabilities and the full web-to-CLI map are in
|
|
21
|
+
this CLI call the same API: every Transform-menu task is a `mammoth view
|
|
22
|
+
transform` command. The data model, capabilities and full web-to-CLI map:
|
|
24
23
|
[about Mammoth](references/about-mammoth.md).
|
|
25
24
|
|
|
26
25
|
## Start
|
|
@@ -30,13 +29,13 @@ mammoth doctor # auth, endpoint, connectivity, version;
|
|
|
30
29
|
mammoth project ensure 'PROJECT NAME' # get-or-create; becomes the active project
|
|
31
30
|
```
|
|
32
31
|
|
|
33
|
-
`doctor` failing is a precondition failure, not a reason to
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
`doctor` failing is a precondition failure, not a reason to proceed anyway.
|
|
33
|
+
When the connection check fails with a 502, 504 or timeout, `mammoth doctor
|
|
34
|
+
--input '{"wait": 300}'` probes again for up to that many seconds; continue
|
|
35
|
+
only once it passes. Production is the `app` endpoint; use `release` only
|
|
36
|
+
when named, and check `meta.profile`/`auth status` `endpoint` match before
|
|
37
|
+
continuing. If no profile has credentials, tell the operator to run
|
|
38
|
+
`mammoth auth login` in their own terminal (add
|
|
40
39
|
`--profile NAME` only for a profile other than `default`; [auth](references/auth.md)
|
|
41
40
|
says where the token comes from) and wait; never ask for the token in chat,
|
|
42
41
|
never read one from a file or environment variable, never run `auth login`
|
|
@@ -65,12 +64,13 @@ State the goal in plain words; the search knows common phrasing, and
|
|
|
65
64
|
```bash
|
|
66
65
|
mammoth schema find "merge two datasets" # -> view.transform.join
|
|
67
66
|
mammoth view transform --help # every data transformation
|
|
67
|
+
mammoth schema find "join two datasets; remove duplicates; build a dashboard" # 1 call, 1 result per goal
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
| Goal | Command |
|
|
71
71
|
|---|---|
|
|
72
72
|
| Combine two datasets on a key (merge, VLOOKUP) | `view transform join`; one value per key: `view transform lookup` |
|
|
73
|
-
| Add rows to an existing dataset, or combine
|
|
73
|
+
| Add rows to an existing dataset, or combine sources | Local file: `file upload FILE --input '{"append_to_ds_id": DATASET_ID}'`. Already in Mammoth: `view export dataset VIEW_ID --input '{"dataset_name": "NAME"}'`, then per further source `view export dataset VIEW_ID --input '{"dataset_name": "NAME", "target_ds_id": DATASET_ID, "save_as_mode": "APPEND_TO_DS"}'` — combine first, clean once; then `discard-duplicates` and diff `row_count` before/after ([about Mammoth](references/about-mammoth.md#view-settings-and-what-has-no-command)) |
|
|
74
74
|
| Keep or remove rows | `view transform filter` |
|
|
75
75
|
| Remove duplicate rows | `view transform discard-duplicates` |
|
|
76
76
|
| Totals, counts, averages per group — just to read the number | `view data aggregate` (read-only: `--input '{"group_by": [...], "aggregations": [{"column": ..., "function": "SUM"}]}'` or `{"metric": {...}}`); never add a `pivot` task just to answer a question |
|
|
@@ -83,38 +83,36 @@ mammoth view transform --help # every data transformation
|
|
|
83
83
|
| Rank, running total, previous row | `view transform window` |
|
|
84
84
|
| A dashboard | `dashboard v3 generate`, then `chat edit` ([dashboards](references/recipes/dashboards.md)) |
|
|
85
85
|
| Deliver the rows | `view export csv`, `view export postgres` (and other destinations), `view export dataset` |
|
|
86
|
-
| Run something on a schedule or on new data (refresh, append, alert) | `automation create`: a condition (`at_specific_time`, new file in a folder, ...) and tasks (`run_data_retrieval`, `append_data`, `send_an_alert`, `pull_cloud_files`). `schedule create` only pulls a connector's data. A dataset
|
|
86
|
+
| Run something on a schedule or on new data (refresh, append, alert) | `automation create`: a condition (`at_specific_time`, new file in a folder, ...) and tasks (`run_data_retrieval`, `append_data`, `send_an_alert`, `pull_cloud_files`). `schedule create` only pulls a connector's data. A dataset from an uploaded file or URL is a one-time copy with no source to refresh; say so. Full recipe, including a known `automation get` backend caveat: [recurring work](references/recipes/scheduling.md) |
|
|
87
87
|
|
|
88
88
|
Call a find result (or `suggestions` entry) from its `accepted_fields` and
|
|
89
|
-
`agent_example`. Before
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
report a real gap with the command you tried.
|
|
89
|
+
`agent_example`. Before concluding the CLI cannot do something the web app
|
|
90
|
+
does, check `view transform --help` and "View settings, and what has no
|
|
91
|
+
command" in [about Mammoth](references/about-mammoth.md). Do not switch to
|
|
92
|
+
the browser, or compute locally, for work the CLI covers; report a real gap
|
|
93
|
+
with the command tried.
|
|
95
94
|
|
|
96
95
|
## Several files, one deliverable
|
|
97
96
|
|
|
98
97
|
Users often upload related files without saying how they relate ("make a
|
|
99
|
-
dashboard from t_a and t_b"). Work it out from the data before
|
|
100
|
-
|
|
101
|
-
1. Upload every file. Each
|
|
102
|
-
|
|
103
|
-
`
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
text, and blanks, each with the fix.
|
|
98
|
+
dashboard from t_a and t_b"). Work it out from the data before building:
|
|
99
|
+
|
|
100
|
+
1. Upload every file. Each result carries a `view` preview of what Mammoth
|
|
101
|
+
made of it (`view_id`, column types, sample rows, `column_warnings`,
|
|
102
|
+
`before_dashboard`). Do not open the local files (`cat`, `head`) — what
|
|
103
|
+
Mammoth made of them is what counts. Run `view data get VIEW_ID` per view;
|
|
104
|
+
warnings list numbers/dates stored as text, and blanks, each with its fix.
|
|
107
105
|
2. Find the keys. A column in one view whose values appear in a column of
|
|
108
106
|
the other (`customer_id` and `id`, `order_ref` and `order_no`) is a
|
|
109
107
|
foreign key; the view with many rows per key is the main one.
|
|
110
108
|
3. Make the keys match before the join: same type (`convert-type`), same
|
|
111
109
|
case and padding (`text`), no blanks (`set-values`, `filter`).
|
|
112
110
|
4. Act on every `column_warnings` entry for a column the deliverable uses:
|
|
113
|
-
run its `fix` (`convert-type` to `NUMERIC
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
line
|
|
117
|
-
|
|
111
|
+
run its `fix` (`convert-type` to `NUMERIC`/`DATE`; non-numeric values
|
|
112
|
+
become empty) — a text `price` cannot be summed on a dashboard. Then
|
|
113
|
+
decide each `blank_values` entry: fill, filter, or keep, and report one
|
|
114
|
+
line per entry (column, count, what and why). A blank seen but unmentioned
|
|
115
|
+
is a miss.
|
|
118
116
|
5. `view transform join` the lookup view into the main view (`LEFT`). The
|
|
119
117
|
result's `join_check` gives `match_rate`, `unmatched_rows` and
|
|
120
118
|
`unmatched_keys`; put them in your report, and stop to compare the keys
|
|
@@ -123,9 +121,9 @@ dashboard from t_a and t_b"). Work it out from the data before you build:
|
|
|
123
121
|
(`math`, `qty * price`, `new_column`), the `fix` in `before_dashboard`.
|
|
124
122
|
A dashboard sees only the columns the view had when it was made.
|
|
125
123
|
7. Build the dashboard from the joined view with one sentence
|
|
126
|
-
([dashboards](references/recipes/dashboards.md))
|
|
127
|
-
revenue
|
|
128
|
-
|
|
124
|
+
([dashboards](references/recipes/dashboards.md)) charting the sum of
|
|
125
|
+
revenue, not a unit price. Fix each `deliverable_check` warning, or say
|
|
126
|
+
why not.
|
|
129
127
|
|
|
130
128
|
For the defaults that most pipelines use (new column or overwrite, `LEFT`
|
|
131
129
|
joins, date steps), see
|
|
@@ -136,7 +134,7 @@ your report. If no column links the files, ask before you combine them.
|
|
|
136
134
|
## Calling a command
|
|
137
135
|
|
|
138
136
|
- Ids are positionals; request fields are one `--input '{...}'` document;
|
|
139
|
-
|
|
137
|
+
no per-field flags (`project create NAME`, not `--name`).
|
|
140
138
|
- `mammoth skill show --input '{"file": "references/recipes/transforms.md"}'`
|
|
141
139
|
prints any file of this skill; `mammoth skill agents-md install` writes a
|
|
142
140
|
steering block into a repository's AGENTS.md so later sessions start here.
|
|
@@ -150,10 +148,10 @@ your report. If no column links the files, ask before you combine them.
|
|
|
150
148
|
status, row_count, `metadata` columns and types, pipeline state);
|
|
151
149
|
`view get ... --input '{"fields": "__full"}'` or `view list ... --input
|
|
152
150
|
'{"full": true}'` returns the dependency and display trees too.
|
|
153
|
-
- Column inputs
|
|
151
|
+
- Column inputs/expressions use the exact **display names** the view
|
|
154
152
|
returns, never backend aliases.
|
|
155
|
-
- `--dry-run` on any API-backed command resolves
|
|
156
|
-
|
|
153
|
+
- `--dry-run` on any API-backed command resolves and reports the request
|
|
154
|
+
instead of sending it; use before a write you are unsure of.
|
|
157
155
|
- Deletes need `--yes`; high-impact ones (`project delete`, access changes)
|
|
158
156
|
also need `--confirm ID`, and `schema get` shows which. Preserve requested
|
|
159
157
|
deliverables; cleanup is exact-ID authorized and
|
|
@@ -167,14 +165,13 @@ your report. If no column links the files, ask before you combine them.
|
|
|
167
165
|
- A success envelope proves the call, not the outcome. After a row-scoped
|
|
168
166
|
change (set-values, filter, replace, join, fill) run `view data get
|
|
169
167
|
VIEW_ID` (50 rows by default, `limit` to change) and check rows the
|
|
170
|
-
condition should
|
|
171
|
-
|
|
168
|
+
condition should and should not have touched. Sample the target column
|
|
169
|
+
*before* the change for comparison.
|
|
172
170
|
- A uniform result (every amount 0, every region "Unknown", most join rows
|
|
173
171
|
unmatched) means the previous step went wrong; stop and re-inspect it.
|
|
174
172
|
- `column_warnings` on a data read and `join_check` on a join are findings,
|
|
175
|
-
not decoration: fix each
|
|
176
|
-
|
|
177
|
-
"limit": 50}`.
|
|
173
|
+
not decoration: fix each the deliverable depends on, or say why kept.
|
|
174
|
+
`view data get` pages with `{"offset": 51, "limit": 50}`.
|
|
178
175
|
- A timeout, exit 7 or interruption does not prove failure; reconcile an
|
|
179
176
|
`outcome_unknown` (`job get`, `view task list`) before replaying.
|
|
180
177
|
- Check an answer with no write against the question (a trend: time
|
|
@@ -182,9 +179,9 @@ your report. If no column links the files, ask before you combine them.
|
|
|
182
179
|
- After a write, run `mammoth project check PROJECT_ID` and fix each
|
|
183
180
|
`to_report` line, or give it one line in the report.
|
|
184
181
|
- Run the [report checklist](references/report-checklist.md) before stating
|
|
185
|
-
a number or calling a step done. When files
|
|
186
|
-
[capabilities](references/capabilities.md) wins over a recipe,
|
|
187
|
-
over the generated
|
|
182
|
+
a number or calling a step done. When files disagree,
|
|
183
|
+
[capabilities](references/capabilities.md) wins over a recipe, which wins
|
|
184
|
+
over the generated catalog.
|
|
188
185
|
|
|
189
186
|
## Route only what the task needs
|
|
190
187
|
|
|
@@ -204,9 +201,9 @@ your report. If no column links the files, ask before you combine them.
|
|
|
204
201
|
[recovery](references/recovery.md) — failure modes by message and the
|
|
205
202
|
stop-condition list
|
|
206
203
|
- **A known command family or exact command:** [command catalog](references/command-index.md)
|
|
207
|
-
— a lookup for
|
|
208
|
-
|
|
209
|
-
|
|
204
|
+
— a lookup for one command, not upfront reading; each entry carries its
|
|
205
|
+
release status line, and a `not supported`/`observed blocker` entry names
|
|
206
|
+
the route to use instead
|
|
210
207
|
- **Whether a route is proven, known-blocked, or untried on release:**
|
|
211
208
|
[capabilities](references/capabilities.md) — read it before promising a
|
|
212
209
|
deliverable or reporting a failure as a backend fault
|
|
@@ -214,9 +211,9 @@ your report. If no column links the files, ask before you combine them.
|
|
|
214
211
|
|
|
215
212
|
## Handoff checklist
|
|
216
213
|
|
|
217
|
-
Before yielding work, write a nonsecret checkpoint
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
objectives;
|
|
221
|
-
record and re-reads remote state before deciding what to do next
|
|
214
|
+
Before yielding work, write a nonsecret checkpoint: intent and acceptance
|
|
215
|
+
criteria; authorized profile/workspace/project; observed resource parents;
|
|
216
|
+
verified evidence hashes; known jobs and unknown outcomes; remaining
|
|
217
|
+
objectives; exact cleanup ownership. The receiving agent validates that
|
|
218
|
+
record and re-reads remote state before deciding what to do next — a handoff
|
|
222
219
|
is not a resume command or a grant of authority.
|
|
@@ -122,4 +122,7 @@ not sufficient. `dataset.create` waits for its asynchronous work; only the
|
|
|
122
122
|
`weburl` creation type is proven, other freeform variants remain unqualified.
|
|
123
123
|
If the schema does not accept a URL,
|
|
124
124
|
report URL import unsupported; do not silently substitute local processing. A
|
|
125
|
-
4/5/7 envelope is a failed or uncertain operation, not a usable dataset.
|
|
125
|
+
4/5/7 envelope is a failed or uncertain operation, not a usable dataset. A
|
|
126
|
+
`weburl` dataset is a one-time copy: it keeps no source details, so it cannot be
|
|
127
|
+
scheduled to refresh (see [recurring work](scheduling.md)); say so rather than
|
|
128
|
+
promising a refreshable source.
|
|
@@ -43,6 +43,10 @@ mammoth automation create 'Nightly refresh' --yes --input '{
|
|
|
43
43
|
}'
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
`run_data_retrieval` only refreshes a cloud-connected dataset; a dataset made
|
|
47
|
+
from an uploaded file or a URL (`weburl`) is a one-time copy with no source
|
|
48
|
+
details to refresh from — say so rather than scheduling one.
|
|
49
|
+
|
|
46
50
|
The other three task types take the shapes documented in `schema get
|
|
47
51
|
automation.create` under `tasks[].details`:
|
|
48
52
|
|
|
@@ -152,16 +152,60 @@ def _schema_get(invocation: Invocation) -> HandlerResult:
|
|
|
152
152
|
return schema_cmd.brief_schema(entry), {}
|
|
153
153
|
|
|
154
154
|
|
|
155
|
+
#: Above this many ';'-separated goals in one 'schema find' call, an agent is
|
|
156
|
+
#: almost certainly pasting something else (a whole plan, a sentence with
|
|
157
|
+
#: semicolons) rather than a real goal list; reject with a clear message
|
|
158
|
+
#: instead of silently running dozens of searches.
|
|
159
|
+
_MAX_FIND_GOALS = 12
|
|
160
|
+
|
|
161
|
+
_EMPTY_QUERY_ERROR = CliError(
|
|
162
|
+
code="empty_search_query",
|
|
163
|
+
message="The schema search query must contain at least one word.",
|
|
164
|
+
exit_status=EXIT_USAGE,
|
|
165
|
+
hint="For the complete inventory, use 'mammoth schema list'.",
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _cap_inline_detail(result: dict[str, Any], keep: int) -> None:
|
|
170
|
+
"""Strip inline ``accepted_fields``/``agent_example`` past the top `keep`."""
|
|
171
|
+
for key in ("matches", "suggestions"):
|
|
172
|
+
for entry in (result.get(key) or [])[keep:]:
|
|
173
|
+
entry.pop("accepted_fields", None)
|
|
174
|
+
entry.pop("agent_example", None)
|
|
175
|
+
|
|
176
|
+
|
|
155
177
|
def _schema_find(invocation: Invocation) -> HandlerResult:
|
|
156
178
|
query = _require_arg(invocation, "search query")
|
|
157
179
|
if not query.strip():
|
|
180
|
+
raise _EMPTY_QUERY_ERROR
|
|
181
|
+
if ";" not in query:
|
|
182
|
+
return schema_cmd.find_schemas(query), {}
|
|
183
|
+
# Several goals in one call ("join customers onto orders; remove
|
|
184
|
+
# duplicate rows; build a dashboard"): run the existing single-goal
|
|
185
|
+
# search per goal instead of round-tripping once per goal.
|
|
186
|
+
goals = [goal.strip() for goal in query.split(";") if goal.strip()]
|
|
187
|
+
if not goals:
|
|
188
|
+
raise _EMPTY_QUERY_ERROR
|
|
189
|
+
if len(goals) > _MAX_FIND_GOALS:
|
|
158
190
|
raise CliError(
|
|
159
|
-
code="
|
|
160
|
-
message=
|
|
191
|
+
code="too_many_goals",
|
|
192
|
+
message=(
|
|
193
|
+
f"schema find accepts at most {_MAX_FIND_GOALS} ';'-separated goals per "
|
|
194
|
+
f"call; got {len(goals)}."
|
|
195
|
+
),
|
|
161
196
|
exit_status=EXIT_USAGE,
|
|
162
|
-
hint="
|
|
197
|
+
hint="Split the goals across more than one 'schema find' call.",
|
|
163
198
|
)
|
|
164
|
-
|
|
199
|
+
results = [schema_cmd.find_schemas(goal) for goal in goals]
|
|
200
|
+
if len(results) > 1:
|
|
201
|
+
# Cap inline accepted_fields/agent_example to the top match per goal
|
|
202
|
+
# so a multi-goal envelope stays small even when every goal has
|
|
203
|
+
# several candidates.
|
|
204
|
+
for result in results:
|
|
205
|
+
_cap_inline_detail(result, 1)
|
|
206
|
+
return {
|
|
207
|
+
"goals": [{"goal": goal, **result} for goal, result in zip(goals, results, strict=True)]
|
|
208
|
+
}, {}
|
|
165
209
|
|
|
166
210
|
|
|
167
211
|
def _log_path(_: Invocation) -> HandlerResult:
|
|
@@ -68,7 +68,8 @@ _COMMAND_DISCOVERY_PURPOSES = {
|
|
|
68
68
|
"file.upload-folder": "upload source-data directory folder",
|
|
69
69
|
"view.export.csv": "export download local CSV file artifact",
|
|
70
70
|
"view.export.dataset": (
|
|
71
|
-
"send copy branch out rows into a
|
|
71
|
+
"send copy branch out create save the result rows into a new project from an "
|
|
72
|
+
"existing append appending union stack monthly rows across datasets views"
|
|
72
73
|
),
|
|
73
74
|
# One entry per typed export destination, in the way users name the
|
|
74
75
|
# destination rather than Mammoth's route spelling (which a two-word
|
|
@@ -195,7 +196,14 @@ _COMMAND_DISCOVERY_PURPOSES = {
|
|
|
195
196
|
"view.transform.date-diff": "date dates difference days between two date columns age duration",
|
|
196
197
|
"view.transform.delete-columns": "delete drop remove columns",
|
|
197
198
|
"view.transform.discard-duplicates": (
|
|
198
|
-
"duplicate duplicates dedup dedupe deduplicate remove repeated rows unique distinct"
|
|
199
|
+
"duplicate duplicates dedup dedupe deduplicate remove repeated rows unique distinct "
|
|
200
|
+
# "order"/"number" are kept as generic identifying-column vocabulary
|
|
201
|
+
# ("dedupe by an order/number/key"), not the specific business noun
|
|
202
|
+
# "order id" -- "order" also can't be dropped as a data word since
|
|
203
|
+
# view.transform.sort's own purpose text already uses it (sort
|
|
204
|
+
# order), so any query pairing "order" with dedupe words needs it
|
|
205
|
+
# covered here to reach a full match.
|
|
206
|
+
"by order number key column"
|
|
199
207
|
),
|
|
200
208
|
"view.transform.extract-date": (
|
|
201
209
|
"extract date part year month day hour minute second week quarter weekday "
|
|
@@ -211,8 +219,8 @@ _COMMAND_DISCOVERY_PURPOSES = {
|
|
|
211
219
|
"view.transform.generate-sql": "generate write sql query from natural language intent question",
|
|
212
220
|
"view.transform.increment-date": "add subtract days months years to a date column shift",
|
|
213
221
|
"view.transform.join": (
|
|
214
|
-
"join blend merge combine enrich match matching keys rows add columns from
|
|
215
|
-
"second view views dataset datasets table tables vlookup"
|
|
222
|
+
"join blend merge combine enrich match matching key keys rows add columns from "
|
|
223
|
+
"another second view views dataset datasets table tables vlookup"
|
|
216
224
|
),
|
|
217
225
|
"view.transform.json-extract": "json extract parse nested fields keys into columns",
|
|
218
226
|
"view.transform.limit-rows": "limit top bottom first last n rows head",
|
|
@@ -223,7 +231,7 @@ _COMMAND_DISCOVERY_PURPOSES = {
|
|
|
223
231
|
"view.transform.math": (
|
|
224
232
|
"math arithmetic multiply multiplication divide add subtract formula "
|
|
225
233
|
"expression amount calculate compute ratio percentage round new column "
|
|
226
|
-
"conditional threshold greater than if text"
|
|
234
|
+
"conditional threshold greater than if text times"
|
|
227
235
|
),
|
|
228
236
|
"view.transform.pivot": (
|
|
229
237
|
"pivot group by aggregate aggregation sum count average summary summarize "
|
|
@@ -235,7 +243,7 @@ _COMMAND_DISCOVERY_PURPOSES = {
|
|
|
235
243
|
"view.transform.replace": "find replace substitute text value in columns",
|
|
236
244
|
"view.transform.set-values": (
|
|
237
245
|
"set values assign overwrite blank empty default where condition label "
|
|
238
|
-
"category bucket flag if then conditional value"
|
|
246
|
+
"category bucket flag if then conditional add a column with a constant value"
|
|
239
247
|
),
|
|
240
248
|
"view.transform.small-large": "nth smallest largest value across columns",
|
|
241
249
|
"view.transform.sort": (
|
|
@@ -261,6 +269,14 @@ _COMMAND_DISCOVERY_PURPOSES = {
|
|
|
261
269
|
"distribution spread histogram top most common frequent values breakdown share "
|
|
262
270
|
"percentage profile"
|
|
263
271
|
),
|
|
272
|
+
"view.create": "start a new one from an existing dataset, duplicate",
|
|
273
|
+
"dataset.list": "list every dataset in a project workspace",
|
|
274
|
+
# "month"/"week" are kept as generic calendar-grouping vocabulary (a
|
|
275
|
+
# group-by dimension any dataset can have), not a specific business
|
|
276
|
+
# value -- and neither can be dropped as a data word anyway, since
|
|
277
|
+
# view.data.explore's own purpose text already uses both for its trend
|
|
278
|
+
# feature.
|
|
279
|
+
"view.data.aggregate": "group and sum totals by month week without changing the pipeline",
|
|
264
280
|
# Goals users state in their own words, one entry per command the agent's
|
|
265
281
|
# system prompt used to spell out by hand.
|
|
266
282
|
"dashboard.suggestion.list": "ideas suggest suggestions what to show put on a board chart",
|
|
@@ -349,6 +365,22 @@ _SCOPE_REQUIREMENTS: dict[str, dict[str, Any]] = {
|
|
|
349
365
|
_MAX_FIND_RESULTS = 20
|
|
350
366
|
# Outranks any word-overlap score: a command named by its full path comes first.
|
|
351
367
|
_NAMED_COMMAND_BOOST = 10_000
|
|
368
|
+
# Bag-of-words scoring cannot tell "create a NEW VIEW from an existing
|
|
369
|
+
# DATASET" (view.create) apart from "create a DATASET from an existing
|
|
370
|
+
# VIEW" (view.export.dataset): the two goals share the exact same word set,
|
|
371
|
+
# and only word order says which resource is being made and which already
|
|
372
|
+
# exists. No purpose text or synonym can encode that; this pair of small
|
|
373
|
+
# adjacency checks is the intentionally scoped exception. Extend the two
|
|
374
|
+
# dicts, never the regex, if another goal collides the same way.
|
|
375
|
+
_NEW_OBJECT_HINTS: dict[str, str] = {
|
|
376
|
+
"view.create": "view",
|
|
377
|
+
"view.export.dataset": "dataset",
|
|
378
|
+
}
|
|
379
|
+
_EXISTING_OBJECT_HINTS: dict[str, str] = {
|
|
380
|
+
"view.create": "dataset",
|
|
381
|
+
"view.export.dataset": "view",
|
|
382
|
+
}
|
|
383
|
+
_OBJECT_ADJACENCY_BOOST = 150
|
|
352
384
|
_MAX_FIND_LIMIT = 100
|
|
353
385
|
# How many of a find's top matches carry inline accepted_fields/agent_example.
|
|
354
386
|
# 35% of all eval tool calls were command discovery (schema find -> schema
|
|
@@ -372,6 +404,12 @@ _DISCOVERY_SYNONYMS: dict[str, tuple[str, ...]] = {
|
|
|
372
404
|
"csv": ("spreadsheet", "file", "upload"),
|
|
373
405
|
"local": ("file", "download", "csv", "artifact"),
|
|
374
406
|
"download": ("export", "file", "csv", "artifact", "local"),
|
|
407
|
+
# "combine" alone is ambiguous between joining on a key and appending
|
|
408
|
+
# rows; kept a weak alias match (not a literal word) here so a bare
|
|
409
|
+
# "combine datasets" still favors join's own literal "combine" purpose
|
|
410
|
+
# text, while "combine ... by appending rows" still resolves to the
|
|
411
|
+
# export -- its own literal "append"/"union"/"stack" carry that case.
|
|
412
|
+
"combine": ("append", "union", "stack", "merge"),
|
|
375
413
|
# "publish" a dataset almost always means one of the typed exports
|
|
376
414
|
# (Power BI, a live DB connection, a webhook, ...); every export
|
|
377
415
|
# command's path literally contains "export", so this one alias covers
|
|
@@ -454,6 +492,12 @@ _DISCOVERY_STOPWORDS = frozenset(
|
|
|
454
492
|
"using",
|
|
455
493
|
"than",
|
|
456
494
|
"via",
|
|
495
|
+
# Filler prepositions in goal phrasing ("datasets as rows", "datasets
|
|
496
|
+
# in a project", "join two datasets on a key"); no command turns on
|
|
497
|
+
# any of these.
|
|
498
|
+
"as",
|
|
499
|
+
"in",
|
|
500
|
+
"on",
|
|
457
501
|
}
|
|
458
502
|
)
|
|
459
503
|
# How many near misses a search with no full match returns.
|
|
@@ -669,6 +713,42 @@ def _adjacent_compound_forms(terms: tuple[str, ...]) -> dict[str, frozenset[str]
|
|
|
669
713
|
return {term: frozenset(compounds) for term, compounds in forms.items()}
|
|
670
714
|
|
|
671
715
|
|
|
716
|
+
@cache
|
|
717
|
+
def _command_vocabulary_tokens() -> frozenset[str]:
|
|
718
|
+
"""Every token that names a command or appears in its curated purpose text.
|
|
719
|
+
|
|
720
|
+
Distinguishes genuine CLI vocabulary from a data word -- a column,
|
|
721
|
+
table, or other business noun from the caller's own data (``orders``,
|
|
722
|
+
``revenue``, ``store``) -- riding along in a goal. Counts a command's own
|
|
723
|
+
id/path (``user``, ``workspace``, ``invoice`` are real resource nouns a
|
|
724
|
+
command is named after) plus ``_COMMAND_DISCOVERY_PURPOSES``/
|
|
725
|
+
``_GROUP_DISCOVERY_PURPOSES`` -- text hand-curated specifically to
|
|
726
|
+
describe what a command is for. Deliberately excludes ``human_example``/
|
|
727
|
+
``agent_example`` and OpenAPI-derived operation hints: those are
|
|
728
|
+
illustrative sample values (a placeholder project name like "Revenue
|
|
729
|
+
report", a sample filename like "sales.csv") reused verbatim across
|
|
730
|
+
dozens of unrelated commands, so counting them would make almost any
|
|
731
|
+
plausible business noun look like real vocabulary and defeat this
|
|
732
|
+
check. A term absent from this set is not something any command is
|
|
733
|
+
named after or actually about, so :func:`find_schemas` drops it from a
|
|
734
|
+
goal's required terms rather than letting it sink an otherwise complete
|
|
735
|
+
match.
|
|
736
|
+
"""
|
|
737
|
+
vocabulary: set[str] = set()
|
|
738
|
+
for record in load_commands():
|
|
739
|
+
if record.get("disposition") == "alias":
|
|
740
|
+
continue
|
|
741
|
+
command_id = str(record["command_id"])
|
|
742
|
+
command_path = str(record["command_path"])
|
|
743
|
+
text = (
|
|
744
|
+
f"{command_id} {command_path} "
|
|
745
|
+
f"{_COMMAND_DISCOVERY_PURPOSES.get(command_id, '')} "
|
|
746
|
+
f"{_GROUP_DISCOVERY_PURPOSES.get(command_path.split()[0], '')}"
|
|
747
|
+
)
|
|
748
|
+
vocabulary.update(_tokens(text))
|
|
749
|
+
return frozenset(vocabulary)
|
|
750
|
+
|
|
751
|
+
|
|
672
752
|
def _compact_contract(record: dict[str, Any]) -> dict[str, Any]:
|
|
673
753
|
"""Return the bounded, honest contract used by discovery clients.
|
|
674
754
|
|
|
@@ -1405,8 +1485,26 @@ def find_schemas(
|
|
|
1405
1485
|
"""
|
|
1406
1486
|
# A query made only of filler words keeps them, rather than matching
|
|
1407
1487
|
# every command.
|
|
1408
|
-
|
|
1409
|
-
compound_forms = _adjacent_compound_forms(
|
|
1488
|
+
raw_terms = _query_tokens(query) or tuple(_tokens(query))
|
|
1489
|
+
compound_forms = _adjacent_compound_forms(raw_terms)
|
|
1490
|
+
# A term no command's discovery-purpose text would ever say is a data
|
|
1491
|
+
# word (a column/table/business noun from the caller's own data, not CLI
|
|
1492
|
+
# vocabulary) riding along in the goal; drop it before the all-terms
|
|
1493
|
+
# rule and scoring so it can't sink an otherwise complete match. If
|
|
1494
|
+
# every term would be dropped, keep them all -- a query that is nothing
|
|
1495
|
+
# but data words still deserves its ordinary near-miss treatment rather
|
|
1496
|
+
# than becoming a match-everything wildcard. A literal full-path lookup
|
|
1497
|
+
# (the ``named`` check below) always uses the un-dropped ``raw_terms``,
|
|
1498
|
+
# so naming a command by its exact path never depends on this filter.
|
|
1499
|
+
vocabulary = _command_vocabulary_tokens()
|
|
1500
|
+
cli_terms = tuple(
|
|
1501
|
+
term
|
|
1502
|
+
for term in raw_terms
|
|
1503
|
+
if (_token_aliases(term) & vocabulary)
|
|
1504
|
+
or (compound_forms.get(term, frozenset()) & vocabulary)
|
|
1505
|
+
)
|
|
1506
|
+
terms = cli_terms or raw_terms
|
|
1507
|
+
query_cf = query.casefold()
|
|
1410
1508
|
# Clamp caller-provided bounds instead of allowing an accidental unbounded
|
|
1411
1509
|
# discovery response. A negative cursor is a usage mistake, not a request
|
|
1412
1510
|
# to wrap around the catalog.
|
|
@@ -1464,6 +1562,12 @@ def find_schemas(
|
|
|
1464
1562
|
action = command_path.split()[1] if len(command_path.split()) > 1 else ""
|
|
1465
1563
|
if "show" in matched_terms and action in {"list", "get", "browse"}:
|
|
1466
1564
|
score += 80
|
|
1565
|
+
new_object = _NEW_OBJECT_HINTS.get(command_id)
|
|
1566
|
+
if new_object and re.search(rf"\bnew\s+{new_object}s?\b", query_cf):
|
|
1567
|
+
score += _OBJECT_ADJACENCY_BOOST
|
|
1568
|
+
existing_object = _EXISTING_OBJECT_HINTS.get(command_id)
|
|
1569
|
+
if existing_object and re.search(rf"\bexisting\s+{existing_object}s?\b", query_cf):
|
|
1570
|
+
score += _OBJECT_ADJACENCY_BOOST
|
|
1467
1571
|
is_support = command_id.startswith("support.")
|
|
1468
1572
|
entry = {
|
|
1469
1573
|
"command_id": command_id,
|
|
@@ -1484,7 +1588,7 @@ def find_schemas(
|
|
|
1484
1588
|
# A query that spells out this command's whole path (``aggregate view
|
|
1485
1589
|
# data ...``) asks for it by name, whatever goal words ride along.
|
|
1486
1590
|
path_tokens = set(_tokens(command_path))
|
|
1487
|
-
named = len(path_tokens) >= 3 and path_tokens <= set(
|
|
1591
|
+
named = len(path_tokens) >= 3 and path_tokens <= set(raw_terms)
|
|
1488
1592
|
if named:
|
|
1489
1593
|
score += _NAMED_COMMAND_BOOST
|
|
1490
1594
|
if named or len(matched_terms) == len(terms):
|