mammoth-cli 2.0.30__tar.gz → 2.0.31__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.30 → mammoth_cli-2.0.31}/PKG-INFO +1 -1
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/__init__.py +1 -1
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/app.py +162 -60
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +1 -1
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +4 -1
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +7 -3
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +7 -0
- mammoth_cli-2.0.31/mammoth_cli/manifest/loader.py +164 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/pyproject.toml +1 -1
- mammoth_cli-2.0.30/mammoth_cli/manifest/loader.py +0 -96
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/.gitignore +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/LICENSE +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/README.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/__main__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/activity.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/addon.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/agent.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/ai.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/annotation.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/auth.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/automation.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/batch.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/billing.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/browse.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/capability.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/client_app.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/completion.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/config.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/connector.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/context.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/dashboard.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/data_app.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/dataset.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/doctor.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/external_key.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/file.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/folder.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/job.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/notification.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/parameter.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/project.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/registry.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/report.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/schedule.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/schema.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/skill.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/snippet.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/support.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/template.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/trash.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/upgrade.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/user.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/view.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/view_ops.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/webhook.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/workflow.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/commands/workspace.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/context/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/context/credentials.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/context/endpoint.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/context/profiles.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/context/resolver.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/contracts/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/contracts/auth.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/errors/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/errors/envelope.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/manifest/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/messages/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/output/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/output/envelope.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/output/normalize.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/output/policy.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/output/progress.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/output/render.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/py.typed +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/confirm.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/dryrun.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/executor.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/input_loader.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/invocation.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/options.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/parents.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/runlog.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/session.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/strict.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/updates.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/runtime/validate.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/argspec.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/coerce.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/command_contract.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/conditions.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/dispatch.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/factory.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/input_fields.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/mapping.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/openapi_types.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/positionals.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/protocol.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/sdk_service.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/testing.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/services/type_system.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/skills/__init__.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/skills/installer.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/skills/steering.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/testing.py +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/activity.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/addon.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/agent.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/ai.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/annotation.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/auth.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/automation.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/batch.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/billing.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/browse.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/capability.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/client-app.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/completion.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/config.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/connector.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/context.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/dashboard.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/data-app.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/dataset.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/doctor.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/external-key.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/file.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/folder.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/job.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/log.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/notification.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/parameter.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/project.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/report.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/schedule.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/schema.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/skill.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/snippet.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/support.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/template.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/trash.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/upgrade.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/user.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/version.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/view.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/webhook.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/workflow.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/commands/workspace.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/openapi-operations.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/schema-v1.json +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/sdk-catalog.source.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/manifests/sdk-methods.yaml +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/openapi/metadata.json +0 -0
- {mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/spec/openapi/openapi.json +0 -0
|
@@ -330,6 +330,13 @@ class _LeafGroup(TyperGroup):
|
|
|
330
330
|
class _EnvelopeGroup(TyperGroup):
|
|
331
331
|
"""Root group that renders Click usage errors as the machine error envelope.
|
|
332
332
|
|
|
333
|
+
It also materialises top-level command groups lazily (see
|
|
334
|
+
:func:`_load_top_level_group`): ``list_commands`` and ``get_command`` know
|
|
335
|
+
every group by name from the manifest, but a group's Click tree is only
|
|
336
|
+
built when it is invoked, completed or listed in ``--help``. Reading
|
|
337
|
+
``commands`` directly materialises them all, so tools that walk the tree
|
|
338
|
+
still see the full surface.
|
|
339
|
+
|
|
333
340
|
Click's standalone error handling prints a human ``Usage: ... Error: ...``
|
|
334
341
|
message and exits, even under ``--output json``: an agent driving the CLI
|
|
335
342
|
then receives un-parseable prose (or, for a leaf that also parents
|
|
@@ -345,6 +352,28 @@ class _EnvelopeGroup(TyperGroup):
|
|
|
345
352
|
on.
|
|
346
353
|
"""
|
|
347
354
|
|
|
355
|
+
@property # type: ignore[override]
|
|
356
|
+
def commands(self) -> dict[str, Any]:
|
|
357
|
+
loaded: dict[str, Any] = self.__dict__.setdefault("_eager_commands", {})
|
|
358
|
+
for name in _LAZY_GROUP_NAMES:
|
|
359
|
+
if name not in loaded:
|
|
360
|
+
loaded[name] = _load_top_level_group(name)
|
|
361
|
+
return loaded
|
|
362
|
+
|
|
363
|
+
@commands.setter
|
|
364
|
+
def commands(self, value: Any) -> None:
|
|
365
|
+
self.__dict__["_eager_commands"] = dict(value or {})
|
|
366
|
+
|
|
367
|
+
def list_commands(self, ctx: Any) -> list[str]:
|
|
368
|
+
eager = self.__dict__.get("_eager_commands", {})
|
|
369
|
+
return [*eager, *(name for name in _LAZY_GROUP_NAMES if name not in eager)]
|
|
370
|
+
|
|
371
|
+
def get_command(self, ctx: Any, cmd_name: str) -> Any:
|
|
372
|
+
eager: dict[str, Any] = self.__dict__.setdefault("_eager_commands", {})
|
|
373
|
+
if cmd_name not in eager and cmd_name in _LAZY_GROUP_NAMES:
|
|
374
|
+
eager[cmd_name] = _load_top_level_group(cmd_name)
|
|
375
|
+
return eager.get(cmd_name)
|
|
376
|
+
|
|
348
377
|
def main(self, *args: Any, **kwargs: Any) -> Any:
|
|
349
378
|
if not kwargs.get("standalone_mode", True):
|
|
350
379
|
return super().main(*args, **kwargs)
|
|
@@ -888,68 +917,55 @@ def _short_type(type_name: str) -> str:
|
|
|
888
917
|
return " | ".join(part.strip().rsplit(".", 1)[-1] for part in text.split("|"))[:40]
|
|
889
918
|
|
|
890
919
|
|
|
891
|
-
def
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
920
|
+
def _command_records() -> list[dict[str, Any]]:
|
|
921
|
+
return [r for r in load_commands() if r.get("disposition") != "alias"]
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
@cache
|
|
925
|
+
def _command_tree() -> tuple[dict[tuple[str, ...], str], frozenset[tuple[str, ...]]]:
|
|
926
|
+
"""Map every command path to its id, and name the container nodes.
|
|
927
|
+
|
|
928
|
+
A "container command" sits at a node that also has deeper subcommands
|
|
929
|
+
(e.g. ``dataset file-settings``, which also has ``... undo`` / ``... update``).
|
|
930
|
+
"""
|
|
931
|
+
path_to_command = {
|
|
932
|
+
tuple(r["command_path"].split()): r["command_id"] for r in _command_records()
|
|
933
|
+
}
|
|
934
|
+
prefixes: set[tuple[str, ...]] = set()
|
|
935
|
+
for tokens in path_to_command:
|
|
936
|
+
for depth in range(1, len(tokens)):
|
|
937
|
+
prefixes.add(tokens[:depth])
|
|
938
|
+
return path_to_command, frozenset(prefixes & path_to_command.keys())
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
def _group_typer(tokens: tuple[str, ...], command_id: str | None) -> typer.Typer:
|
|
942
|
+
if command_id is not None:
|
|
943
|
+
# This node is both a group and an invocable command.
|
|
944
|
+
sub = typer.Typer(
|
|
945
|
+
cls=_LeafGroup,
|
|
946
|
+
no_args_is_help=False,
|
|
947
|
+
invoke_without_command=True,
|
|
948
|
+
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
|
|
949
|
+
)
|
|
950
|
+
sub.callback()(_build_leaf(command_id, is_group_callback=True))
|
|
951
|
+
return sub
|
|
952
|
+
return typer.Typer(
|
|
953
|
+
help=_GROUP_DESCRIPTIONS.get(tokens[0], f"Commands for {' '.join(tokens)}."),
|
|
900
954
|
no_args_is_help=True,
|
|
901
|
-
add_completion=True,
|
|
902
|
-
cls=_EnvelopeGroup,
|
|
903
955
|
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
|
|
904
956
|
)
|
|
905
957
|
|
|
906
|
-
@root.callback()
|
|
907
|
-
def _root(
|
|
908
|
-
version: bool = typer.Option(
|
|
909
|
-
False, "--version", callback=_version_callback, is_eager=True, help="Show version."
|
|
910
|
-
),
|
|
911
|
-
) -> None:
|
|
912
|
-
"""Root callback holding eager global options."""
|
|
913
958
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
}
|
|
918
|
-
all_paths = set(path_to_command)
|
|
919
|
-
# A "container command" sits at a node that also has deeper subcommands
|
|
920
|
-
# (e.g. `dataset file-settings`, which also has `... undo` / `... update`).
|
|
921
|
-
containers = {
|
|
922
|
-
tokens
|
|
923
|
-
for tokens in all_paths
|
|
924
|
-
if any(other != tokens and other[: len(tokens)] == tokens for other in all_paths)
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
groups: dict[tuple[str, ...], typer.Typer] = {(): root}
|
|
928
|
-
|
|
929
|
-
def _make_group(tokens: tuple[str, ...]) -> typer.Typer:
|
|
930
|
-
command_id = path_to_command.get(tokens)
|
|
931
|
-
if command_id is not None:
|
|
932
|
-
# This node is both a group and an invocable command.
|
|
933
|
-
sub = typer.Typer(
|
|
934
|
-
cls=_LeafGroup,
|
|
935
|
-
no_args_is_help=False,
|
|
936
|
-
invoke_without_command=True,
|
|
937
|
-
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
|
|
938
|
-
)
|
|
939
|
-
sub.callback()(_build_leaf(command_id, is_group_callback=True))
|
|
940
|
-
else:
|
|
941
|
-
sub = typer.Typer(
|
|
942
|
-
help=_GROUP_DESCRIPTIONS.get(tokens[0], f"Commands for {' '.join(tokens)}."),
|
|
943
|
-
no_args_is_help=True,
|
|
944
|
-
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
|
|
945
|
-
)
|
|
946
|
-
return sub
|
|
959
|
+
def _populate(base: tuple[str, ...], group: typer.Typer) -> None:
|
|
960
|
+
"""Register every command below ``base`` (exclusive) on ``group``."""
|
|
961
|
+
path_to_command, containers = _command_tree()
|
|
962
|
+
groups: dict[tuple[str, ...], typer.Typer] = {base: group}
|
|
947
963
|
|
|
948
964
|
def _group_for(tokens: tuple[str, ...]) -> typer.Typer:
|
|
949
965
|
if tokens in groups:
|
|
950
966
|
return groups[tokens]
|
|
951
967
|
parent = _group_for(tokens[:-1])
|
|
952
|
-
sub =
|
|
968
|
+
sub = _group_typer(tokens, path_to_command.get(tokens))
|
|
953
969
|
top_level = tokens[0]
|
|
954
970
|
parent.add_typer(
|
|
955
971
|
sub,
|
|
@@ -960,15 +976,16 @@ def build_app() -> typer.Typer:
|
|
|
960
976
|
groups[tokens] = sub
|
|
961
977
|
return sub
|
|
962
978
|
|
|
979
|
+
below = {t: c for t, c in path_to_command.items() if t[: len(base)] == base and t != base}
|
|
963
980
|
# Ensure every container group exists (parents before children).
|
|
964
|
-
for tokens in sorted(containers, key=len):
|
|
981
|
+
for tokens in sorted((t for t in below if t in containers), key=len):
|
|
965
982
|
_group_for(tokens)
|
|
966
983
|
|
|
967
984
|
# Register every non-container command as a leaf under its parent group.
|
|
968
985
|
# A command_id with a bespoke, fully-typed callback overrides the generic
|
|
969
986
|
# leaf at the same registered name and path; the manifest-driven surface
|
|
970
987
|
# is otherwise unchanged.
|
|
971
|
-
for tokens, command_id in sorted(
|
|
988
|
+
for tokens, command_id in sorted(below.items()):
|
|
972
989
|
if tokens in containers:
|
|
973
990
|
continue
|
|
974
991
|
record = command_by_id(command_id)
|
|
@@ -980,11 +997,88 @@ def build_app() -> typer.Typer:
|
|
|
980
997
|
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
|
|
981
998
|
)(callback)
|
|
982
999
|
|
|
1000
|
+
|
|
1001
|
+
@cache
|
|
1002
|
+
def _top_level_typer(name: str) -> typer.Typer:
|
|
1003
|
+
"""Build (once) the Typer sub-app for one top-level command group."""
|
|
1004
|
+
path_to_command, _ = _command_tree()
|
|
1005
|
+
sub = _group_typer((name,), path_to_command.get((name,)))
|
|
1006
|
+
_populate((name,), sub)
|
|
1007
|
+
return sub
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
# Top-level groups are converted to Click on first use. Building the leaf
|
|
1011
|
+
# callbacks and ``--help`` text for all ~550 commands, then letting Typer
|
|
1012
|
+
# convert every one of them, used to cost most of the CLI's start-up time on
|
|
1013
|
+
# every invocation; a run touches one group.
|
|
1014
|
+
_LAZY_GROUP_NAMES: list[str] = []
|
|
1015
|
+
_LAZY_SETTINGS: dict[str, Any] = {}
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
def _load_top_level_group(name: str) -> Any:
|
|
1019
|
+
from typer.models import TyperInfo
|
|
1020
|
+
|
|
1021
|
+
info = TyperInfo(
|
|
1022
|
+
_top_level_typer(name),
|
|
1023
|
+
name=name,
|
|
1024
|
+
help=_GROUP_DESCRIPTIONS.get(name, f"Commands for {name}."),
|
|
1025
|
+
rich_help_panel=_ROOT_HELP_PANELS.get(name),
|
|
1026
|
+
)
|
|
1027
|
+
return typer.main.get_group_from_info(info, **_LAZY_SETTINGS)
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
def build_app() -> typer.Typer:
|
|
1031
|
+
"""Construct the Typer command tree from the command manifests.
|
|
1032
|
+
|
|
1033
|
+
Top-level leaves (``doctor``, ``version``, ...) are registered here; every
|
|
1034
|
+
top-level group is materialised by :class:`_EnvelopeGroup` on demand.
|
|
1035
|
+
"""
|
|
1036
|
+
root = typer.Typer(
|
|
1037
|
+
name="mammoth",
|
|
1038
|
+
help=(
|
|
1039
|
+
"Command-line interface for the Mammoth Analytics platform.\n\n"
|
|
1040
|
+
"Start with 'mammoth doctor' to check access, 'mammoth schema find QUERY' "
|
|
1041
|
+
"to locate a command, and 'mammoth schema get COMMAND_ID' for its full input schema."
|
|
1042
|
+
),
|
|
1043
|
+
no_args_is_help=True,
|
|
1044
|
+
add_completion=True,
|
|
1045
|
+
cls=_EnvelopeGroup,
|
|
1046
|
+
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
|
|
1047
|
+
)
|
|
1048
|
+
|
|
1049
|
+
@root.callback()
|
|
1050
|
+
def _root(
|
|
1051
|
+
version: bool = typer.Option(
|
|
1052
|
+
False, "--version", callback=_version_callback, is_eager=True, help="Show version."
|
|
1053
|
+
),
|
|
1054
|
+
) -> None:
|
|
1055
|
+
"""Root callback holding eager global options."""
|
|
1056
|
+
|
|
1057
|
+
path_to_command, containers = _command_tree()
|
|
1058
|
+
top_names = sorted({tokens[0] for tokens in path_to_command})
|
|
1059
|
+
lazy: list[str] = []
|
|
1060
|
+
for name in top_names:
|
|
1061
|
+
if (name,) in containers or (name,) not in path_to_command:
|
|
1062
|
+
lazy.append(name)
|
|
1063
|
+
continue
|
|
1064
|
+
command_id = path_to_command[(name,)]
|
|
1065
|
+
root.command(
|
|
1066
|
+
name=name,
|
|
1067
|
+
help=_command_help(command_id, command_by_id(command_id)),
|
|
1068
|
+
rich_help_panel=_ROOT_HELP_PANELS.get(name),
|
|
1069
|
+
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
|
|
1070
|
+
)(BESPOKE.get(command_id) or _build_leaf(command_id))
|
|
1071
|
+
_LAZY_GROUP_NAMES[:] = lazy
|
|
1072
|
+
_LAZY_SETTINGS.update(
|
|
1073
|
+
pretty_exceptions_short=root.pretty_exceptions_short,
|
|
1074
|
+
rich_markup_mode=root.rich_markup_mode,
|
|
1075
|
+
suggest_commands=root.suggest_commands,
|
|
1076
|
+
)
|
|
983
1077
|
return root
|
|
984
1078
|
|
|
985
1079
|
|
|
986
1080
|
def registered_command_paths() -> set[str]:
|
|
987
|
-
"""Return every registered command path by walking the built Typer
|
|
1081
|
+
"""Return every registered command path by walking the built Typer trees.
|
|
988
1082
|
|
|
989
1083
|
Container commands (a node that is both a group and invocable) are counted
|
|
990
1084
|
by their own path as well as their subcommands.
|
|
@@ -998,14 +1092,20 @@ def registered_command_paths() -> set[str]:
|
|
|
998
1092
|
paths.add(" ".join((*prefix, name)))
|
|
999
1093
|
for group in instance.registered_groups:
|
|
1000
1094
|
sub = group.typer_instance
|
|
1001
|
-
|
|
1095
|
+
name = group.name
|
|
1096
|
+
if sub is None or not name:
|
|
1002
1097
|
continue
|
|
1003
|
-
node = (*prefix,
|
|
1004
|
-
if
|
|
1098
|
+
node = (*prefix, name)
|
|
1099
|
+
if sub.registered_callback is not None:
|
|
1005
1100
|
paths.add(" ".join(node))
|
|
1006
1101
|
walk(sub, node)
|
|
1007
1102
|
|
|
1008
|
-
walk(
|
|
1103
|
+
walk(app, ())
|
|
1104
|
+
for name in _LAZY_GROUP_NAMES:
|
|
1105
|
+
sub = _top_level_typer(name)
|
|
1106
|
+
if sub.registered_callback is not None:
|
|
1107
|
+
paths.add(name)
|
|
1108
|
+
walk(sub, (name,))
|
|
1009
1109
|
return paths
|
|
1010
1110
|
|
|
1011
1111
|
|
|
@@ -1020,7 +1120,9 @@ def _root_click_command() -> Any:
|
|
|
1020
1120
|
the tree is fixed for the process lifetime (:data:`app` is built once at
|
|
1021
1121
|
import time).
|
|
1022
1122
|
"""
|
|
1023
|
-
|
|
1123
|
+
root: Any = typer.main.get_command(app)
|
|
1124
|
+
root.commands # noqa: B018 -- materialise every lazy top-level group
|
|
1125
|
+
return root
|
|
1024
1126
|
|
|
1025
1127
|
|
|
1026
1128
|
def command_option_names(command_path: str) -> set[str]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mammoth-cli
|
|
3
|
-
version: 2.0.
|
|
3
|
+
version: 2.0.31
|
|
4
4
|
description: "Use Mammoth Analytics from a terminal: install or authenticate the CLI, discover its live command contract, and safely manage projects, data, views, pipelines, dashboards, exports, and handoffs."
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
```bash
|
|
4
4
|
mammoth schema find "view export"
|
|
5
5
|
mammoth schema get view.export.csv
|
|
6
|
-
mammoth view export csv VIEW_ID --project PROJECT_ID
|
|
6
|
+
mammoth view export csv VIEW_ID --project PROJECT_ID --input '{"dataset_id": DATASET_ID, "output_path": "out.csv"}'
|
|
7
7
|
mammoth view export list VIEW_ID DATASET_ID --project PROJECT_ID
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
+
`view export csv` takes one positional (the view); `dataset_id` and
|
|
11
|
+
`output_path` go in `--input`. It is a download, not a pipeline step.
|
|
12
|
+
|
|
10
13
|
If the export or its source dataset/view is requested as a deliverable, mark
|
|
11
14
|
both as retained before starting. Wait/reconcile returned jobs. Verify local
|
|
12
15
|
artifact headers, rows and hash;
|
|
@@ -30,9 +30,13 @@ mammoth dataset file-settings update DATASET_ID --project PROJECT_ID \
|
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
The response is a job (`operation: "understand_csv"`). Poll `dataset get`
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
(the record is under `data.dataset`, so read `data.dataset.status`) until
|
|
34
|
+
the status leaves `need_action`. It usually reaches `ready` within seconds;
|
|
35
|
+
on prague an ISO `YYYY-MM-DD` column was flagged ambiguous and took about
|
|
36
|
+
three minutes, so poll for up to five minutes before treating it as stuck.
|
|
37
|
+
Then `view list` returns the generated view and typed transforms can
|
|
38
|
+
proceed. Which environments ask differs: release processed the same file
|
|
39
|
+
straight to `ready`. If the status becomes `error`, read `status_info`
|
|
36
40
|
and stop; do not retry with guessed settings.
|
|
37
41
|
|
|
38
42
|
## All-text CSV: `ready` without a view
|
{mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md
RENAMED
|
@@ -44,6 +44,13 @@ mammoth view transform filter 144 --dry-run \
|
|
|
44
44
|
# data.would_call.sdk_symbol = ...FilterOpsMixin.filter_rows, view_id 144, dataset_id 122
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
A dry run is a full process with the same reads as the real run. On a
|
|
48
|
+
hosted environment budget roughly 2 s per request (about 0.7 s of it TLS
|
|
49
|
+
setup from a cold process, the rest server time), so `view task list` →
|
|
50
|
+
`--dry-run` → write costs about 30–40 s per pipeline step. That is the
|
|
51
|
+
price of the procedure, not a hang; do not shorten `--timeout` below the
|
|
52
|
+
default to speed it up.
|
|
53
|
+
|
|
47
54
|
## Add-only edits to a pipeline someone else may touch
|
|
48
55
|
|
|
49
56
|
Every `view transform *` and `view task add` accepts `expected_task_count`:
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""Load and validate the reviewed parity and command manifests.
|
|
2
|
+
|
|
3
|
+
These manifests are the single source of truth for capability discovery, schema
|
|
4
|
+
discovery, help generation, the agent skill, and the parity report. Runtime code
|
|
5
|
+
loads them read-only; the build scripts generate them.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import functools
|
|
11
|
+
import hashlib
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import tempfile
|
|
15
|
+
from dataclasses import dataclass
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
import platformdirs
|
|
20
|
+
import yaml
|
|
21
|
+
|
|
22
|
+
SPEC_ROOT = Path(__file__).resolve().parent.parent.parent / "spec"
|
|
23
|
+
MANIFEST_DIR = SPEC_ROOT / "manifests"
|
|
24
|
+
COMMANDS_DIR = MANIFEST_DIR / "commands"
|
|
25
|
+
SCHEMA_PATH = MANIFEST_DIR / "schema-v1.json"
|
|
26
|
+
OPENAPI_OPERATIONS_PATH = MANIFEST_DIR / "openapi-operations.yaml"
|
|
27
|
+
SDK_METHODS_PATH = MANIFEST_DIR / "sdk-methods.yaml"
|
|
28
|
+
|
|
29
|
+
MANIFEST_SCHEMA_VERSION = 1
|
|
30
|
+
CACHE_ENV = "MAMMOTH_CLI_MANIFEST_CACHE"
|
|
31
|
+
|
|
32
|
+
# libyaml parses the 800 KiB of command manifests in ~0.2 s; the pure-Python
|
|
33
|
+
# loader takes ~2 s, which used to be most of the CLI's start-up time.
|
|
34
|
+
_YAML_LOADER = getattr(yaml, "CSafeLoader", yaml.SafeLoader)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _read_yaml(path: Path) -> Any:
|
|
38
|
+
if not path.exists():
|
|
39
|
+
return None
|
|
40
|
+
return yaml.load(path.read_text(encoding="utf-8"), Loader=_YAML_LOADER) # noqa: S506
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def cache_dir() -> Path:
|
|
44
|
+
"""Return the directory the parsed-manifest cache lives in (not created)."""
|
|
45
|
+
return Path(platformdirs.user_cache_dir("mammoth-cli", "Mammoth"))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _cache_enabled() -> bool:
|
|
49
|
+
return os.environ.get(CACHE_ENV, "1").strip().lower() not in {"0", "false", "no", "off"}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _commands_fingerprint(paths: list[Path]) -> str:
|
|
53
|
+
"""Identify the exact set of manifest files by name, size and mtime."""
|
|
54
|
+
digest = hashlib.sha256()
|
|
55
|
+
digest.update(str(MANIFEST_SCHEMA_VERSION).encode())
|
|
56
|
+
for path in paths:
|
|
57
|
+
stat = path.stat()
|
|
58
|
+
digest.update(f"{path.name}\0{stat.st_size}\0{stat.st_mtime_ns}\n".encode())
|
|
59
|
+
return digest.hexdigest()[:24]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _read_commands_cache(path: Path) -> list[dict[str, Any]] | None:
|
|
63
|
+
try:
|
|
64
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
65
|
+
except (OSError, ValueError):
|
|
66
|
+
return None
|
|
67
|
+
if not isinstance(data, list) or not all(isinstance(item, dict) for item in data):
|
|
68
|
+
return None
|
|
69
|
+
return data
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _write_commands_cache(path: Path, records: list[dict[str, Any]]) -> None:
|
|
73
|
+
"""Write the cache atomically; a cache that cannot be written is simply skipped."""
|
|
74
|
+
try:
|
|
75
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
76
|
+
fd, tmp = tempfile.mkstemp(dir=path.parent, prefix=path.name, suffix=".tmp")
|
|
77
|
+
with os.fdopen(fd, "w", encoding="utf-8") as handle:
|
|
78
|
+
json.dump(records, handle, separators=(",", ":"))
|
|
79
|
+
os.replace(tmp, path)
|
|
80
|
+
except OSError:
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@functools.lru_cache(maxsize=1)
|
|
85
|
+
def load_schema() -> dict[str, Any]:
|
|
86
|
+
schema: dict[str, Any] = json.loads(SCHEMA_PATH.read_text(encoding="utf-8"))
|
|
87
|
+
return schema
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@functools.lru_cache(maxsize=1)
|
|
91
|
+
def load_operations() -> list[dict[str, Any]]:
|
|
92
|
+
data = _read_yaml(OPENAPI_OPERATIONS_PATH)
|
|
93
|
+
if not data:
|
|
94
|
+
return []
|
|
95
|
+
return list(data.get("operations", []))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@functools.lru_cache(maxsize=1)
|
|
99
|
+
def load_sdk_methods() -> list[dict[str, Any]]:
|
|
100
|
+
data = _read_yaml(SDK_METHODS_PATH)
|
|
101
|
+
if not data:
|
|
102
|
+
return []
|
|
103
|
+
return list(data.get("methods", []))
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@functools.lru_cache(maxsize=1)
|
|
107
|
+
def load_commands() -> list[dict[str, Any]]:
|
|
108
|
+
"""Load every command record across all command group files, sorted by id.
|
|
109
|
+
|
|
110
|
+
The parsed records are cached as JSON under :func:`cache_dir`, keyed by the
|
|
111
|
+
manifest files' names, sizes and mtimes, so a normal invocation skips YAML
|
|
112
|
+
parsing entirely. Set ``MAMMOTH_CLI_MANIFEST_CACHE=0`` to bypass the cache.
|
|
113
|
+
"""
|
|
114
|
+
if not COMMANDS_DIR.exists():
|
|
115
|
+
return []
|
|
116
|
+
paths = sorted(COMMANDS_DIR.glob("*.yaml"))
|
|
117
|
+
cache_path: Path | None = None
|
|
118
|
+
if _cache_enabled():
|
|
119
|
+
try:
|
|
120
|
+
cache_path = cache_dir() / f"commands-{_commands_fingerprint(paths)}.json"
|
|
121
|
+
except OSError:
|
|
122
|
+
cache_path = None
|
|
123
|
+
if cache_path is not None:
|
|
124
|
+
cached = _read_commands_cache(cache_path)
|
|
125
|
+
if cached is not None:
|
|
126
|
+
return cached
|
|
127
|
+
records: list[dict[str, Any]] = []
|
|
128
|
+
for path in paths:
|
|
129
|
+
data = _read_yaml(path)
|
|
130
|
+
if not data:
|
|
131
|
+
continue
|
|
132
|
+
records.extend(data.get("commands", []))
|
|
133
|
+
records.sort(key=lambda record: record["command_id"])
|
|
134
|
+
if cache_path is not None:
|
|
135
|
+
_write_commands_cache(cache_path, records)
|
|
136
|
+
return records
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@dataclass(frozen=True)
|
|
140
|
+
class ManifestSet:
|
|
141
|
+
operations: list[dict[str, Any]]
|
|
142
|
+
sdk_methods: list[dict[str, Any]]
|
|
143
|
+
commands: list[dict[str, Any]]
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def load_all() -> ManifestSet:
|
|
147
|
+
return ManifestSet(
|
|
148
|
+
operations=load_operations(),
|
|
149
|
+
sdk_methods=load_sdk_methods(),
|
|
150
|
+
commands=load_commands(),
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def command_by_id(command_id: str) -> dict[str, Any] | None:
|
|
155
|
+
for record in load_commands():
|
|
156
|
+
if record["command_id"] == command_id:
|
|
157
|
+
return record
|
|
158
|
+
return None
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def clear_cache() -> None:
|
|
162
|
+
"""Reset cached manifests (used in tests that rewrite manifest files)."""
|
|
163
|
+
for func in (load_schema, load_operations, load_sdk_methods, load_commands):
|
|
164
|
+
func.cache_clear()
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
"""Load and validate the reviewed parity and command manifests.
|
|
2
|
-
|
|
3
|
-
These manifests are the single source of truth for capability discovery, schema
|
|
4
|
-
discovery, help generation, the agent skill, and the parity report. Runtime code
|
|
5
|
-
loads them read-only; the build scripts generate them.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import functools
|
|
11
|
-
import json
|
|
12
|
-
from dataclasses import dataclass
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
from typing import Any
|
|
15
|
-
|
|
16
|
-
import yaml
|
|
17
|
-
|
|
18
|
-
SPEC_ROOT = Path(__file__).resolve().parent.parent.parent / "spec"
|
|
19
|
-
MANIFEST_DIR = SPEC_ROOT / "manifests"
|
|
20
|
-
COMMANDS_DIR = MANIFEST_DIR / "commands"
|
|
21
|
-
SCHEMA_PATH = MANIFEST_DIR / "schema-v1.json"
|
|
22
|
-
OPENAPI_OPERATIONS_PATH = MANIFEST_DIR / "openapi-operations.yaml"
|
|
23
|
-
SDK_METHODS_PATH = MANIFEST_DIR / "sdk-methods.yaml"
|
|
24
|
-
|
|
25
|
-
MANIFEST_SCHEMA_VERSION = 1
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def _read_yaml(path: Path) -> Any:
|
|
29
|
-
if not path.exists():
|
|
30
|
-
return None
|
|
31
|
-
return yaml.safe_load(path.read_text(encoding="utf-8"))
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@functools.lru_cache(maxsize=1)
|
|
35
|
-
def load_schema() -> dict[str, Any]:
|
|
36
|
-
schema: dict[str, Any] = json.loads(SCHEMA_PATH.read_text(encoding="utf-8"))
|
|
37
|
-
return schema
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@functools.lru_cache(maxsize=1)
|
|
41
|
-
def load_operations() -> list[dict[str, Any]]:
|
|
42
|
-
data = _read_yaml(OPENAPI_OPERATIONS_PATH)
|
|
43
|
-
if not data:
|
|
44
|
-
return []
|
|
45
|
-
return list(data.get("operations", []))
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@functools.lru_cache(maxsize=1)
|
|
49
|
-
def load_sdk_methods() -> list[dict[str, Any]]:
|
|
50
|
-
data = _read_yaml(SDK_METHODS_PATH)
|
|
51
|
-
if not data:
|
|
52
|
-
return []
|
|
53
|
-
return list(data.get("methods", []))
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
@functools.lru_cache(maxsize=1)
|
|
57
|
-
def load_commands() -> list[dict[str, Any]]:
|
|
58
|
-
"""Load every command record across all command group files, sorted by id."""
|
|
59
|
-
records: list[dict[str, Any]] = []
|
|
60
|
-
if not COMMANDS_DIR.exists():
|
|
61
|
-
return []
|
|
62
|
-
for path in sorted(COMMANDS_DIR.glob("*.yaml")):
|
|
63
|
-
data = _read_yaml(path)
|
|
64
|
-
if not data:
|
|
65
|
-
continue
|
|
66
|
-
records.extend(data.get("commands", []))
|
|
67
|
-
records.sort(key=lambda record: record["command_id"])
|
|
68
|
-
return records
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
@dataclass(frozen=True)
|
|
72
|
-
class ManifestSet:
|
|
73
|
-
operations: list[dict[str, Any]]
|
|
74
|
-
sdk_methods: list[dict[str, Any]]
|
|
75
|
-
commands: list[dict[str, Any]]
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def load_all() -> ManifestSet:
|
|
79
|
-
return ManifestSet(
|
|
80
|
-
operations=load_operations(),
|
|
81
|
-
sdk_methods=load_sdk_methods(),
|
|
82
|
-
commands=load_commands(),
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def command_by_id(command_id: str) -> dict[str, Any] | None:
|
|
87
|
-
for record in load_commands():
|
|
88
|
-
if record["command_id"] == command_id:
|
|
89
|
-
return record
|
|
90
|
-
return None
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def clear_cache() -> None:
|
|
94
|
-
"""Reset cached manifests (used in tests that rewrite manifest files)."""
|
|
95
|
-
for func in (load_schema, load_operations, load_sdk_methods, load_commands):
|
|
96
|
-
func.cache_clear()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mammoth_cli-2.0.30 → mammoth_cli-2.0.31}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|