mammoth-cli 2.2.54__tar.gz → 2.2.56__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/PKG-INFO +2 -2
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/__init__.py +1 -1
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/__main__.py +2 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/app.py +213 -36
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +3 -3
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view-transform.md +20 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +11 -1
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +14 -0
- mammoth_cli-2.2.56/mammoth_cli/commands/__init__.py +31 -0
- mammoth_cli-2.2.56/mammoth_cli/commands/_lazy.py +38 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/auth.py +12 -11
- mammoth_cli-2.2.56/mammoth_cli/commands/help_summaries.json +659 -0
- mammoth_cli-2.2.56/mammoth_cli/commands/registry.py +911 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/schema.py +19 -4
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/upgrade.py +12 -8
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/view.py +21 -1
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/view_ops.py +207 -8
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/context/credentials.py +6 -1
- mammoth_cli-2.2.56/mammoth_cli/context/keyring_backend.py +86 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/errors/envelope.py +11 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/manifest/loader.py +49 -11
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/executor.py +12 -1
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/command_contract.py +19 -1
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/conditions.py +40 -21
- mammoth_cli-2.2.56/mammoth_cli/services/explore_cards.py +92 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/input_fields.py +1 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/positionals.py +1 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/pyproject.toml +4 -2
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/view.yaml +143 -7
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/edits-target.source.yaml +2 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/sdk-catalog.source.yaml +8 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/sdk-methods.yaml +14 -2
- mammoth_cli-2.2.54/mammoth_cli/commands/__init__.py +0 -31
- mammoth_cli-2.2.54/mammoth_cli/commands/registry.py +0 -908
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/.gitignore +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/LICENSE +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/README.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/about-mammoth.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/calc.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-qa.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-style.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-template.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/link.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/resolve.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/token.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/database-import.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/scheduling.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/activity.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/addon.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/agent.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/ai.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/annotation.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/automation.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/batch.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/billing.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/browse.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/calc.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/capability.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/client_app.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/completion.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/config.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/connector.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/context.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/dashboard.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/data_app.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/dataset.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/doctor.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/external_key.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/file.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/folder.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/job.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/link.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/notification.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/parameter.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/project.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/report.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/resolve.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/schedule.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/skill.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/snippet.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/support.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/template.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/trash.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/user.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/view_profile.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/webhook.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/workflow.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/commands/workspace.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/context/__init__.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/context/endpoint.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/context/oauth.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/context/profiles.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/context/resolver.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/contracts/__init__.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/contracts/auth.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/embed.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/errors/__init__.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/manifest/__init__.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/messages/__init__.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/output/__init__.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/output/envelope.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/output/normalize.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/output/policy.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/output/progress.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/output/render.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/py.typed +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/__init__.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/confirm.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/dataset_health.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/dryrun.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/dryrun_targets.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/embedded.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/input_loader.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/intent_only.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/invocation.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/locked_files.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/new_data.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/options.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/parents.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/runlog.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/session.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/state.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/strict.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/updates.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/validate.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/runtime/verify.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/__init__.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/append_blank_columns.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/argspec.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/board_values.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/coerce.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/conditional_format.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/dashboard_filters.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/dashboard_pages.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/dashboard_review.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/data_profile.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/data_quality.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/dispatch.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/factory.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/job_outcome.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/listing.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/local_time.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/mapping.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/openapi_types.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/protocol.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/read_queries.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/sdk_service.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/sql_check.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/stored_stats.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/testing.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/text_dates.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/type_system.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/view_analysis.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/view_variants.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/services/write_impact.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/skills/__init__.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/skills/installer.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/skills/steering.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/mammoth_cli/testing.py +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/activity.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/addon.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/agent.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/ai.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/annotation.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/auth.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/automation.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/batch.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/billing.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/browse.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/calc.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/capability.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/client-app.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/completion.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/config.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/connector.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/context.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/dashboard.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/data-app.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/dataset.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/doctor.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/external-key.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/file.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/folder.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/job.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/link.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/log.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/notification.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/parameter.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/project.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/report.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/resolve.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/schedule.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/schema.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/skill.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/snippet.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/support.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/template.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/token.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/trash.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/upgrade.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/user.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/version.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/webhook.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/workflow.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/commands/workspace.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/openapi-operations.yaml +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/manifests/schema-v1.json +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/openapi/metadata.json +0 -0
- {mammoth_cli-2.2.54 → mammoth_cli-2.2.56}/spec/openapi/openapi.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mammoth-cli
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.56
|
|
4
4
|
Summary: Command-line interface for the Mammoth Analytics platform
|
|
5
5
|
Project-URL: homepage, https://mammoth.io
|
|
6
6
|
Project-URL: repository, https://github.com/EdgeMetric/mammothsdk
|
|
@@ -17,7 +17,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
17
17
|
Requires-Python: <3.15,>=3.12
|
|
18
18
|
Requires-Dist: jsonschema>=4.20
|
|
19
19
|
Requires-Dist: keyring<26,>=25.7
|
|
20
|
-
Requires-Dist: mammoth-io<0.9,>=0.8.
|
|
20
|
+
Requires-Dist: mammoth-io<0.9,>=0.8.30
|
|
21
21
|
Requires-Dist: platformdirs<5,>=4.10
|
|
22
22
|
Requires-Dist: pydantic<3,>=2.12.5
|
|
23
23
|
Requires-Dist: pyyaml<7,>=6
|
|
@@ -15,24 +15,25 @@ positionals and options are added per family as each handler is implemented.
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import inspect
|
|
18
|
+
import json
|
|
18
19
|
import re
|
|
19
20
|
import sys
|
|
20
21
|
from collections.abc import Callable, Sequence
|
|
21
22
|
from dataclasses import replace
|
|
22
23
|
from difflib import get_close_matches
|
|
23
24
|
from functools import cache
|
|
24
|
-
from
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
from typing import TYPE_CHECKING, Annotated, Any, cast
|
|
25
27
|
|
|
26
28
|
import typer
|
|
27
29
|
from typer._click import exceptions as _typer_click_exceptions
|
|
28
30
|
from typer._click.core import Command as _ClickCommand
|
|
29
|
-
from typer.core import
|
|
31
|
+
from typer._click.core import Parameter as _ClickParameter
|
|
32
|
+
from typer.core import TyperCommand, TyperGroup
|
|
30
33
|
|
|
31
34
|
from mammoth_cli import __version__
|
|
32
35
|
from mammoth_cli.commands import BESPOKE
|
|
33
|
-
from mammoth_cli.commands.registry import HANDLERS
|
|
34
|
-
from mammoth_cli.commands.schema import IN_PLACE_RECIPE, edits_view_in_place
|
|
35
|
-
from mammoth_cli.context import profiles
|
|
36
|
+
from mammoth_cli.commands.registry import HANDLERS
|
|
36
37
|
from mammoth_cli.errors.envelope import EXIT_USAGE, CliError, not_implemented_error
|
|
37
38
|
from mammoth_cli.manifest.loader import command_by_id, load_commands
|
|
38
39
|
from mammoth_cli.output.policy import (
|
|
@@ -43,17 +44,12 @@ from mammoth_cli.output.policy import (
|
|
|
43
44
|
VALID_OUTPUTS,
|
|
44
45
|
resolve_output,
|
|
45
46
|
)
|
|
46
|
-
from mammoth_cli.runtime import executor, validate
|
|
47
|
-
from mammoth_cli.runtime.dataset_health import with_dataset_health
|
|
48
|
-
from mammoth_cli.runtime.intent_only import refuse_hand_crafted_write
|
|
49
|
-
from mammoth_cli.runtime.invocation import Invocation
|
|
50
|
-
from mammoth_cli.runtime.locked_files import with_locked_files
|
|
51
|
-
from mammoth_cli.runtime.new_data import with_new_data_path
|
|
52
|
-
from mammoth_cli.runtime.state import with_state
|
|
53
|
-
from mammoth_cli.runtime.strict import validate_extra_args
|
|
54
|
-
from mammoth_cli.runtime.verify import with_verify
|
|
55
47
|
from mammoth_cli.services.positionals import PositionalSpec, resolve_positionals
|
|
56
48
|
|
|
49
|
+
if TYPE_CHECKING:
|
|
50
|
+
from mammoth_cli.commands.registry import Handler
|
|
51
|
+
from mammoth_cli.runtime.invocation import Invocation
|
|
52
|
+
|
|
57
53
|
OUTPUT_MODES = VALID_OUTPUTS
|
|
58
54
|
|
|
59
55
|
# Root help is the first piece of discovery most people (and agents) see. The
|
|
@@ -370,7 +366,7 @@ class _EnvelopeGroup(TyperGroup):
|
|
|
370
366
|
loaded: dict[str, Any] = self.__dict__.setdefault("_eager_commands", {})
|
|
371
367
|
for name in _LAZY_GROUP_NAMES:
|
|
372
368
|
if name not in loaded:
|
|
373
|
-
loaded[name] =
|
|
369
|
+
loaded[name] = _load_lazy_root(name)
|
|
374
370
|
return loaded
|
|
375
371
|
|
|
376
372
|
@commands.setter
|
|
@@ -379,14 +375,18 @@ class _EnvelopeGroup(TyperGroup):
|
|
|
379
375
|
|
|
380
376
|
def list_commands(self, ctx: Any) -> list[str]:
|
|
381
377
|
eager = self.__dict__.get("_eager_commands", {})
|
|
382
|
-
|
|
378
|
+
# Top-level leaves list ahead of groups, the order they were registered in.
|
|
379
|
+
lazy = sorted(_LAZY_GROUP_NAMES, key=lambda name: name not in _LAZY_LEAF_IDS)
|
|
380
|
+
return [*eager, *(name for name in lazy if name not in eager)]
|
|
383
381
|
|
|
384
382
|
def get_command(self, ctx: Any, cmd_name: str) -> Any:
|
|
385
383
|
eager: dict[str, Any] = self.__dict__.setdefault("_eager_commands", {})
|
|
386
384
|
if cmd_name not in eager and cmd_name in _LAZY_GROUP_NAMES:
|
|
387
385
|
if self.__dict__.get("_listing_help"):
|
|
386
|
+
if cmd_name in _LAZY_LEAF_IDS:
|
|
387
|
+
return _root_leaf_stub(cmd_name)
|
|
388
388
|
return _group_stub(cmd_name)
|
|
389
|
-
eager[cmd_name] =
|
|
389
|
+
eager[cmd_name] = _load_lazy_root(cmd_name)
|
|
390
390
|
return eager.get(cmd_name)
|
|
391
391
|
|
|
392
392
|
def resolve_command(self, ctx: Any, args: list[str]) -> Any:
|
|
@@ -526,6 +526,8 @@ class _EnvelopeGroup(TyperGroup):
|
|
|
526
526
|
exit_status=EXIT_USAGE,
|
|
527
527
|
hint="Check the command schema with 'mammoth schema get'.",
|
|
528
528
|
)
|
|
529
|
+
from mammoth_cli.runtime import executor
|
|
530
|
+
|
|
529
531
|
executor.emit_error(report, machine=True)
|
|
530
532
|
elif report is None:
|
|
531
533
|
error.show()
|
|
@@ -850,6 +852,8 @@ def _build_leaf(command_id: str, *, is_group_callback: bool = False) -> Callable
|
|
|
850
852
|
positional_names = tuple(spec.name for spec in positionals)
|
|
851
853
|
|
|
852
854
|
def leaf(**params: Any) -> None:
|
|
855
|
+
from mammoth_cli.runtime.invocation import Invocation
|
|
856
|
+
|
|
853
857
|
ctx: typer.Context = params.pop("ctx")
|
|
854
858
|
if is_group_callback and ctx.invoked_subcommand is not None:
|
|
855
859
|
return
|
|
@@ -883,6 +887,14 @@ def _execute(invocation: Invocation) -> None:
|
|
|
883
887
|
# Freeze the fallback profile before opening a service. A recovery command
|
|
884
888
|
# must inspect the same account that submitted/observed a job, rather than
|
|
885
889
|
# resolving the mutable selected-profile pointer after an interrupt.
|
|
890
|
+
from mammoth_cli.context import profiles
|
|
891
|
+
from mammoth_cli.runtime import executor, validate
|
|
892
|
+
from mammoth_cli.runtime.dataset_health import with_dataset_health
|
|
893
|
+
from mammoth_cli.runtime.intent_only import refuse_hand_crafted_write
|
|
894
|
+
from mammoth_cli.runtime.locked_files import with_locked_files
|
|
895
|
+
from mammoth_cli.runtime.new_data import with_new_data_path
|
|
896
|
+
from mammoth_cli.runtime.strict import validate_extra_args
|
|
897
|
+
|
|
886
898
|
if invocation.profile is None:
|
|
887
899
|
invocation = replace(invocation, profile=profiles.get_selected())
|
|
888
900
|
|
|
@@ -938,6 +950,9 @@ def _apply_verify(invocation: Invocation, data: Any) -> Any:
|
|
|
938
950
|
command's manifest ``readback``/``no_readback`` declaration -- see
|
|
939
951
|
:mod:`mammoth_cli.runtime.state`).
|
|
940
952
|
"""
|
|
953
|
+
from mammoth_cli.runtime.state import with_state
|
|
954
|
+
from mammoth_cli.runtime.verify import with_verify
|
|
955
|
+
|
|
941
956
|
record = command_by_id(invocation.command_id) or {}
|
|
942
957
|
if record.get("mutation_class") == "read" or not record.get("sdk_symbol"):
|
|
943
958
|
return data
|
|
@@ -973,6 +988,32 @@ def _dry_run(handler: Handler, invocation: Invocation) -> tuple[Any, dict[str, A
|
|
|
973
988
|
return report, {"profile": invocation.profile, "project_id": resolved_project(invocation)}
|
|
974
989
|
|
|
975
990
|
|
|
991
|
+
def live_command_summary(command_id: str) -> str | None:
|
|
992
|
+
"""The backing handler's docstring first line, the lead of a command's help.
|
|
993
|
+
|
|
994
|
+
Reading it imports the handler's module, so a group listing takes it from
|
|
995
|
+
the generated index (:func:`_indexed_summary`) instead.
|
|
996
|
+
"""
|
|
997
|
+
handler = HANDLERS.get(command_id) or BESPOKE.get(command_id)
|
|
998
|
+
doc = inspect.getdoc(handler) if handler is not None else None
|
|
999
|
+
if not doc:
|
|
1000
|
+
return None
|
|
1001
|
+
# First non-empty line, with RST inline-code backticks flattened to plain
|
|
1002
|
+
# quotes so the help reads as prose rather than reStructuredText.
|
|
1003
|
+
return doc.strip().splitlines()[0].strip().replace("``", "'") or None
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
@cache
|
|
1007
|
+
def _summary_index() -> dict[str, str]:
|
|
1008
|
+
"""Every command's help summary, generated by ``scripts/gen_help_summaries.py``."""
|
|
1009
|
+
path = Path(__file__).parent / "commands" / "help_summaries.json"
|
|
1010
|
+
return cast(dict[str, str], json.loads(path.read_text(encoding="utf-8")))
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
def _indexed_summary(command_id: str) -> str | None:
|
|
1014
|
+
return _summary_index().get(command_id)
|
|
1015
|
+
|
|
1016
|
+
|
|
976
1017
|
def _command_help(command_id: str, record: dict[str, Any] | None) -> str | None:
|
|
977
1018
|
"""Build a command's user-facing ``--help`` summary.
|
|
978
1019
|
|
|
@@ -985,15 +1026,12 @@ def _command_help(command_id: str, record: dict[str, Any] | None) -> str | None:
|
|
|
985
1026
|
every required positional and ``--input`` field. ``known_restrictions``
|
|
986
1027
|
remains available to machines through ``schema get``.
|
|
987
1028
|
"""
|
|
1029
|
+
from mammoth_cli.commands.schema import IN_PLACE_RECIPE, edits_view_in_place
|
|
1030
|
+
|
|
988
1031
|
parts: list[str] = []
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
# First non-empty line, with RST inline-code backticks flattened to plain
|
|
993
|
-
# quotes so the help reads as prose rather than reStructuredText.
|
|
994
|
-
summary = doc.strip().splitlines()[0].strip().replace("``", "'")
|
|
995
|
-
if summary:
|
|
996
|
-
parts.append(summary)
|
|
1032
|
+
summary = live_command_summary(command_id)
|
|
1033
|
+
if summary:
|
|
1034
|
+
parts.append(summary)
|
|
997
1035
|
if record is not None and edits_view_in_place(record):
|
|
998
1036
|
parts.append(IN_PLACE_RECIPE)
|
|
999
1037
|
example = (record or {}).get("agent_example")
|
|
@@ -1089,6 +1127,86 @@ def _group_typer(tokens: tuple[str, ...], command_id: str | None) -> typer.Typer
|
|
|
1089
1127
|
)
|
|
1090
1128
|
|
|
1091
1129
|
|
|
1130
|
+
def _lazy_help_command(command_id: str) -> type[TyperCommand]:
|
|
1131
|
+
"""A command class whose help is read from the handler only when printed.
|
|
1132
|
+
|
|
1133
|
+
Building a group registers every command in it; reading each help text up
|
|
1134
|
+
front imports every handler module of the group, though a run uses one.
|
|
1135
|
+
"""
|
|
1136
|
+
|
|
1137
|
+
class LazyHelpCommand(TyperCommand):
|
|
1138
|
+
@property
|
|
1139
|
+
def help(self) -> str | None:
|
|
1140
|
+
return _command_help(command_id, command_by_id(command_id))
|
|
1141
|
+
|
|
1142
|
+
@help.setter
|
|
1143
|
+
def help(self, value: str | None) -> None:
|
|
1144
|
+
"""Ignore the registration-time placeholder; the handler is the source."""
|
|
1145
|
+
|
|
1146
|
+
@property
|
|
1147
|
+
def short_help(self) -> str | None:
|
|
1148
|
+
"""The group listing prints only the first paragraph, which is the summary."""
|
|
1149
|
+
return _indexed_summary(command_id)
|
|
1150
|
+
|
|
1151
|
+
@short_help.setter
|
|
1152
|
+
def short_help(self, value: str | None) -> None:
|
|
1153
|
+
"""Ignore the registration-time value; the handler is the source."""
|
|
1154
|
+
|
|
1155
|
+
return LazyHelpCommand
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
def _unbuilt_leaf() -> None:
|
|
1159
|
+
"""Registration placeholder: a lazy leaf takes its real callback from the built command."""
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
def _lazy_leaf_command(command_id: str) -> type[TyperCommand]:
|
|
1163
|
+
"""A generic leaf whose parameters and callback are built when first read.
|
|
1164
|
+
|
|
1165
|
+
Building a leaf derives its positionals from the SDK signature, which
|
|
1166
|
+
imports the SDK model modules. A group's ``--help`` lists names and help
|
|
1167
|
+
only, so it never reads them; a run reads them for the one command used.
|
|
1168
|
+
"""
|
|
1169
|
+
|
|
1170
|
+
class LazyLeafCommand(_lazy_help_command(command_id)): # type: ignore[misc]
|
|
1171
|
+
_built: _ClickCommand | None = None
|
|
1172
|
+
|
|
1173
|
+
def _real(self) -> _ClickCommand:
|
|
1174
|
+
if self._built is None:
|
|
1175
|
+
from typer.models import CommandInfo
|
|
1176
|
+
|
|
1177
|
+
info = CommandInfo(
|
|
1178
|
+
name=self.name,
|
|
1179
|
+
callback=_build_leaf(command_id),
|
|
1180
|
+
help=_command_help(command_id, command_by_id(command_id)),
|
|
1181
|
+
rich_help_panel=self.rich_help_panel,
|
|
1182
|
+
context_settings=_leaf_context_settings(command_id),
|
|
1183
|
+
)
|
|
1184
|
+
self._built = typer.main.get_command_from_info(
|
|
1185
|
+
info,
|
|
1186
|
+
pretty_exceptions_short=_LAZY_SETTINGS["pretty_exceptions_short"],
|
|
1187
|
+
rich_markup_mode=self.rich_markup_mode,
|
|
1188
|
+
)
|
|
1189
|
+
return self._built
|
|
1190
|
+
|
|
1191
|
+
@property
|
|
1192
|
+
def params(self) -> list[_ClickParameter]:
|
|
1193
|
+
return self._real().params
|
|
1194
|
+
|
|
1195
|
+
@params.setter
|
|
1196
|
+
def params(self, value: list[_ClickParameter]) -> None:
|
|
1197
|
+
"""Ignore the registration-time parameters; the built command owns them."""
|
|
1198
|
+
|
|
1199
|
+
@property
|
|
1200
|
+
def callback(self) -> Any:
|
|
1201
|
+
return self._real().callback
|
|
1202
|
+
|
|
1203
|
+
@callback.setter
|
|
1204
|
+
def callback(self, value: Any) -> None:
|
|
1205
|
+
"""Ignore the registration-time placeholder callback."""
|
|
1206
|
+
|
|
1207
|
+
return LazyLeafCommand
|
|
1208
|
+
|
|
1209
|
+
|
|
1092
1210
|
def _populate(base: tuple[str, ...], group: typer.Typer) -> None:
|
|
1093
1211
|
"""Register every command below ``base`` (exclusive) on ``group``."""
|
|
1094
1212
|
path_to_command, containers = _command_tree()
|
|
@@ -1121,14 +1239,14 @@ def _populate(base: tuple[str, ...], group: typer.Typer) -> None:
|
|
|
1121
1239
|
for tokens, command_id in sorted(below.items()):
|
|
1122
1240
|
if tokens in containers:
|
|
1123
1241
|
continue
|
|
1124
|
-
|
|
1125
|
-
callback = BESPOKE.get(command_id) or _build_leaf(command_id)
|
|
1242
|
+
bespoke = BESPOKE.get(command_id)
|
|
1126
1243
|
_group_for(tokens[:-1]).command(
|
|
1127
1244
|
name=tokens[-1],
|
|
1128
|
-
|
|
1245
|
+
cls=_lazy_help_command(command_id) if bespoke else _lazy_leaf_command(command_id),
|
|
1246
|
+
help="",
|
|
1129
1247
|
rich_help_panel=_ROOT_HELP_PANELS.get(tokens[0]) if len(tokens) == 1 else None,
|
|
1130
1248
|
context_settings=_leaf_context_settings(command_id),
|
|
1131
|
-
)(
|
|
1249
|
+
)(bespoke or _unbuilt_leaf)
|
|
1132
1250
|
|
|
1133
1251
|
|
|
1134
1252
|
@cache
|
|
@@ -1160,6 +1278,67 @@ def _load_top_level_group(name: str) -> Any:
|
|
|
1160
1278
|
return typer.main.get_group_from_info(info, **_LAZY_SETTINGS)
|
|
1161
1279
|
|
|
1162
1280
|
|
|
1281
|
+
# Root ``--help`` prints each top-level leaf's help; reading it from the handler
|
|
1282
|
+
# would import the handler's module (and its SDK dependencies). A test pins this
|
|
1283
|
+
# table to :func:`_command_help` so it cannot drift.
|
|
1284
|
+
_ROOT_LEAF_HELP: dict[str, str] = {
|
|
1285
|
+
"calc": (
|
|
1286
|
+
"Evaluate one arithmetic expression exactly."
|
|
1287
|
+
"\n\nExample: mammoth calc '2063664 - 1917815'"
|
|
1288
|
+
),
|
|
1289
|
+
"doctor": (
|
|
1290
|
+
"Run environment and connectivity diagnostics."
|
|
1291
|
+
"\n\nExample: mammoth doctor\n\nInput fields: wait (int)"
|
|
1292
|
+
),
|
|
1293
|
+
"link": (
|
|
1294
|
+
"Read the workspace, project, folder, dataset and view ids out of a pasted app URL."
|
|
1295
|
+
"\n\nExample: mammoth link https://app.mammoth.io/workspaces/1/projects/2/data/datasets"
|
|
1296
|
+
),
|
|
1297
|
+
"resolve": (
|
|
1298
|
+
"Say what NAME refers to: a dataset, a view or a project, with ids and projects."
|
|
1299
|
+
"\n\nExample: mammoth resolve uqa-w29-ren"
|
|
1300
|
+
),
|
|
1301
|
+
"upgrade": (
|
|
1302
|
+
"Upgrade the mammoth CLI to the latest (or a specified) version from PyPI."
|
|
1303
|
+
"\n\nExample: mammoth upgrade"
|
|
1304
|
+
),
|
|
1305
|
+
"version": "Example: mammoth version",
|
|
1306
|
+
}
|
|
1307
|
+
_LAZY_LEAF_IDS: dict[str, str] = {}
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
def _load_root_leaf(name: str) -> Any:
|
|
1311
|
+
from typer.models import CommandInfo
|
|
1312
|
+
|
|
1313
|
+
command_id = _LAZY_LEAF_IDS[name]
|
|
1314
|
+
info = CommandInfo(
|
|
1315
|
+
name=name,
|
|
1316
|
+
callback=BESPOKE.get(command_id) or _build_leaf(command_id),
|
|
1317
|
+
help=_command_help(command_id, command_by_id(command_id)),
|
|
1318
|
+
rich_help_panel=_ROOT_HELP_PANELS.get(name),
|
|
1319
|
+
context_settings=_leaf_context_settings(command_id),
|
|
1320
|
+
)
|
|
1321
|
+
return typer.main.get_command_from_info(
|
|
1322
|
+
info,
|
|
1323
|
+
pretty_exceptions_short=_LAZY_SETTINGS["pretty_exceptions_short"],
|
|
1324
|
+
rich_markup_mode=_LAZY_SETTINGS["rich_markup_mode"],
|
|
1325
|
+
)
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
def _root_leaf_stub(name: str) -> Any:
|
|
1329
|
+
"""A placeholder leaf carrying only what the root ``--help`` listing prints."""
|
|
1330
|
+
return TyperCommand(
|
|
1331
|
+
name=name,
|
|
1332
|
+
help=_ROOT_LEAF_HELP[name],
|
|
1333
|
+
rich_help_panel=_ROOT_HELP_PANELS.get(name),
|
|
1334
|
+
rich_markup_mode=_LAZY_SETTINGS["rich_markup_mode"],
|
|
1335
|
+
)
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
def _load_lazy_root(name: str) -> Any:
|
|
1339
|
+
return _load_root_leaf(name) if name in _LAZY_LEAF_IDS else _load_top_level_group(name)
|
|
1340
|
+
|
|
1341
|
+
|
|
1163
1342
|
def _group_stub(name: str) -> Any:
|
|
1164
1343
|
"""A placeholder group carrying only what the root ``--help`` listing prints."""
|
|
1165
1344
|
return TyperGroup(
|
|
@@ -1204,13 +1383,8 @@ def build_app() -> typer.Typer:
|
|
|
1204
1383
|
if (name,) in containers or (name,) not in path_to_command:
|
|
1205
1384
|
lazy.append(name)
|
|
1206
1385
|
continue
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
name=name,
|
|
1210
|
-
help=_command_help(command_id, command_by_id(command_id)),
|
|
1211
|
-
rich_help_panel=_ROOT_HELP_PANELS.get(name),
|
|
1212
|
-
context_settings=_leaf_context_settings(command_id),
|
|
1213
|
-
)(BESPOKE.get(command_id) or _build_leaf(command_id))
|
|
1386
|
+
_LAZY_LEAF_IDS[name] = path_to_command[(name,)]
|
|
1387
|
+
lazy.append(name)
|
|
1214
1388
|
_LAZY_GROUP_NAMES[:] = lazy
|
|
1215
1389
|
_LAZY_SETTINGS.update(
|
|
1216
1390
|
pretty_exceptions_short=root.pretty_exceptions_short,
|
|
@@ -1245,6 +1419,9 @@ def registered_command_paths() -> set[str]:
|
|
|
1245
1419
|
|
|
1246
1420
|
walk(app, ())
|
|
1247
1421
|
for name in _LAZY_GROUP_NAMES:
|
|
1422
|
+
if name in _LAZY_LEAF_IDS:
|
|
1423
|
+
paths.add(name)
|
|
1424
|
+
continue
|
|
1248
1425
|
sub = _top_level_typer(name)
|
|
1249
1426
|
if sub.registered_callback is not None:
|
|
1250
1427
|
paths.add(name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Published CLI command catalog
|
|
2
2
|
|
|
3
|
-
This generated catalog is a lookup table for every command in the published CLI manifest, currently
|
|
3
|
+
This generated catalog is a lookup table for every command in the published CLI manifest, currently 663; each entry carries its release status line. It is a command-contract index, not an assertion that every backend/OpenAPI operation has a CLI binding. For an exact local CLI contract, run `mammoth schema get COMMAND_ID`; `mammoth capability list` is an API-binding inventory and can omit typed/local CLI routes. For focused workflows, read the [recipes index](recipes/index.md). Sensitive structured input must come from a private file or pipe; never put secrets in literal argv.
|
|
4
4
|
|
|
5
5
|
Load only the applicable domain file:
|
|
6
6
|
|
|
@@ -50,8 +50,8 @@ Load only the applicable domain file:
|
|
|
50
50
|
- [upgrade](commands/upgrade.md) — 1 published commands
|
|
51
51
|
- [user](commands/user.md) — 8 published commands
|
|
52
52
|
- [version](commands/version.md) — 1 published commands
|
|
53
|
-
- [view-transform](commands/view-transform.md) —
|
|
54
|
-
- [view](commands/view.md) —
|
|
53
|
+
- [view-transform](commands/view-transform.md) — 34 published commands
|
|
54
|
+
- [view](commands/view.md) — 98 published commands
|
|
55
55
|
- [webhook](commands/webhook.md) — 7 published commands
|
|
56
56
|
- [workflow](commands/workflow.md) — 16 published commands
|
|
57
57
|
- [workspace](commands/workspace.md) — 26 published commands
|
|
@@ -142,6 +142,16 @@ Result: `ViewTransformFilterResult`; mutation `reversible_pipeline`, confirmatio
|
|
|
142
142
|
|
|
143
143
|
Status on release: ran once on CLI 2.0.40 through `view.task.add` and was read back with `view data get`; other inputs for this transform are untried.
|
|
144
144
|
|
|
145
|
+
### `view.transform.first-name`
|
|
146
|
+
|
|
147
|
+
Run: `mammoth view transform first-name`. Exact input fields: `mammoth schema get view.transform.first-name`.
|
|
148
|
+
|
|
149
|
+
Example: `mammoth view transform first-name 123 --input '{"column": "Name", "new_column": "First name", "dataset_id": 456}'`. Placeholders are illustrative; resolve IDs and input from observed reads.
|
|
150
|
+
|
|
151
|
+
Result: `ViewTransformFirstNameResult`; mutation `reversible_pipeline`, confirmation `none`, wait policy `always_wait`.
|
|
152
|
+
|
|
153
|
+
Status on release: untried; it submits through `view.task.add`, but this transform was not among those run.
|
|
154
|
+
|
|
145
155
|
### `view.transform.generate-sql`
|
|
146
156
|
|
|
147
157
|
Run: `mammoth view transform generate-sql`. Exact input fields: `mammoth schema get view.transform.generate-sql`.
|
|
@@ -312,6 +322,16 @@ Result: `ViewTransformUnnestResult`; mutation `reversible_pipeline`, confirmatio
|
|
|
312
322
|
|
|
313
323
|
Status on release: ran once on CLI 2.0.40 through `view.task.add` and was read back with `view data get`; other inputs for this transform are untried.
|
|
314
324
|
|
|
325
|
+
### `view.transform.update-column`
|
|
326
|
+
|
|
327
|
+
Run: `mammoth view transform update-column`. Exact input fields: `mammoth schema get view.transform.update-column`.
|
|
328
|
+
|
|
329
|
+
Example: `mammoth view transform update-column 123 --input '{"column": "Cost", "expression": "Cost + 5", "dataset_id": 456}'`. Placeholders are illustrative; resolve IDs and input from observed reads.
|
|
330
|
+
|
|
331
|
+
Result: `ViewTransformUpdateColumnResult`; mutation `reversible_pipeline`, confirmation `none`, wait policy `always_wait`.
|
|
332
|
+
|
|
333
|
+
Status on release: untried; it submits through `view.task.add`, but this transform was not among those run.
|
|
334
|
+
|
|
315
335
|
### `view.transform.window`
|
|
316
336
|
|
|
317
337
|
Run: `mammoth view transform window`. Exact input fields: `mammoth schema get view.transform.window`.
|
|
@@ -428,7 +428,7 @@ Status on release: untried; no live run recorded.
|
|
|
428
428
|
|
|
429
429
|
Run: `mammoth view explore-panel set`. Exact input fields: `mammoth schema get view.explore-panel.set`.
|
|
430
430
|
|
|
431
|
-
Example: `mammoth view explore-panel set 123 --input '{"panel": {"
|
|
431
|
+
Example: `mammoth view explore-panel set 123 --input '{"panel": {"columns": "all"}}'`. Placeholders are illustrative; resolve IDs and input from observed reads.
|
|
432
432
|
|
|
433
433
|
Result: `ViewExplorePanelSetResult`; mutation `benign_mutation`, confirmation `none`, wait policy `not_async`.
|
|
434
434
|
|
|
@@ -550,6 +550,16 @@ Result: `ViewExportListResult`; mutation `read`, confirmation `none`, wait polic
|
|
|
550
550
|
|
|
551
551
|
Status on release: ran once on CLI 2.0.28 — ILG simulation 2026-09-19: exit 0 on release with CLI 2.0.28. Listed both internal_dataset exports with target_properties (DS_NAME, COLUMN_MAPPING, project fields). Single invocation only.
|
|
552
552
|
|
|
553
|
+
### `view.export.live-link`
|
|
554
|
+
|
|
555
|
+
Run: `mammoth view export live-link`. Exact input fields: `mammoth schema get view.export.live-link`.
|
|
556
|
+
|
|
557
|
+
Example: `mammoth view export live-link 123 123 --input '{"file_name": "report_share.csv"}'`. Illustrative only: append `--yes` after observing an owned target.
|
|
558
|
+
|
|
559
|
+
Result: `ViewExportLiveLinkResult`; mutation `external_effect`, confirmation `yes_always`, wait policy `always_wait`.
|
|
560
|
+
|
|
561
|
+
Status on release: untried; no live run recorded.
|
|
562
|
+
|
|
553
563
|
### `view.export.managed-s3`
|
|
554
564
|
|
|
555
565
|
Run: `mammoth view export managed-s3`. Exact input fields: `mammoth schema get view.export.managed-s3`.
|
|
@@ -29,6 +29,20 @@ If `schema get view.export.csv` rejects requested fields, preserve the
|
|
|
29
29
|
structured error and discover another declared export route rather than using
|
|
30
30
|
raw HTTP.
|
|
31
31
|
|
|
32
|
+
## Share a view as a live link
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
mammoth view export live-link VIEW_ID DATASET_ID --project PROJECT_ID --yes
|
|
36
|
+
# -> {"url": "<the live link>"}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
An S3 export flagged `liveLink`: a public URL that serves the view's data and
|
|
40
|
+
stays current as the view's pipeline re-runs. Optional `--input` fields are
|
|
41
|
+
`file_name` (`<prefix>_<token>.csv`; the server replaces the token), `file_type`
|
|
42
|
+
(`csv`, `json`, `parquet`) and `include_hidden`. A plan without live links is
|
|
43
|
+
refused by the backend; its message comes back as the error. Hand the URL to the
|
|
44
|
+
user as returned; anyone holding it can read the data.
|
|
45
|
+
|
|
32
46
|
## Send a view into another project (parallel send, branch-out)
|
|
33
47
|
|
|
34
48
|
`view export dataset` writes the view's rows into a Mammoth dataset **as a
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""commands layer for the Mammoth CLI.
|
|
2
|
+
|
|
3
|
+
Assembles :data:`BESPOKE`: fully-typed Typer command callbacks that override
|
|
4
|
+
the generic manifest leaf for the command ids they implement. ``app.py``
|
|
5
|
+
imports this module and swaps in a bespoke callback wherever one exists,
|
|
6
|
+
registering it at the exact same manifest path and name as the generic leaf
|
|
7
|
+
it replaces.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
|
|
14
|
+
from mammoth_cli.commands._lazy import LazyTable
|
|
15
|
+
|
|
16
|
+
_TARGETS: dict[str, str] = {
|
|
17
|
+
"auth.login": "mammoth_cli.commands.auth:auth_login",
|
|
18
|
+
"auth.status": "mammoth_cli.commands.auth:auth_status",
|
|
19
|
+
"auth.logout": "mammoth_cli.commands.auth:auth_logout",
|
|
20
|
+
"config.get": "mammoth_cli.commands.config:config_get",
|
|
21
|
+
"config.set": "mammoth_cli.commands.config:config_set",
|
|
22
|
+
"config.list": "mammoth_cli.commands.config:config_list",
|
|
23
|
+
"config.path": "mammoth_cli.commands.config:config_path",
|
|
24
|
+
"context.project.status": "mammoth_cli.commands.context:context_project_status",
|
|
25
|
+
"context.project.use": "mammoth_cli.commands.context:context_project_use",
|
|
26
|
+
"context.project.clear": "mammoth_cli.commands.context:context_project_clear",
|
|
27
|
+
"upgrade": "mammoth_cli.commands.upgrade:upgrade_command",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#: Command id -> bespoke Typer callback, imported from its module on first use.
|
|
31
|
+
BESPOKE: LazyTable[Callable[..., None]] = LazyTable(_TARGETS)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""A read-only table of callables imported on first lookup.
|
|
2
|
+
|
|
3
|
+
The command tree names about 600 handlers across 40 command modules. Importing
|
|
4
|
+
them all to build ``--help``, to suggest a close command name or to run one
|
|
5
|
+
command cost seconds; a table of ``"module:attribute"`` strings costs nothing
|
|
6
|
+
until an entry is looked up.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import importlib
|
|
12
|
+
from collections.abc import Callable, Iterator, Mapping
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class LazyTable[T: Callable[..., Any]](Mapping[str, T]):
|
|
17
|
+
"""Map a key to a callable named by a ``"module:attribute"`` string."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, targets: Mapping[str, str]) -> None:
|
|
20
|
+
self._targets = targets
|
|
21
|
+
self._loaded: dict[str, T] = {}
|
|
22
|
+
|
|
23
|
+
def __getitem__(self, key: str) -> T:
|
|
24
|
+
if key in self._loaded:
|
|
25
|
+
return self._loaded[key]
|
|
26
|
+
module_name, _, attribute = self._targets[key].partition(":")
|
|
27
|
+
value: T = getattr(importlib.import_module(module_name), attribute)
|
|
28
|
+
self._loaded[key] = value
|
|
29
|
+
return value
|
|
30
|
+
|
|
31
|
+
def __iter__(self) -> Iterator[str]:
|
|
32
|
+
return iter(self._targets)
|
|
33
|
+
|
|
34
|
+
def __len__(self) -> int:
|
|
35
|
+
return len(self._targets)
|
|
36
|
+
|
|
37
|
+
def __contains__(self, key: object) -> bool:
|
|
38
|
+
return key in self._targets
|
|
@@ -314,10 +314,10 @@ def _choose_method(
|
|
|
314
314
|
typer.echo(f" 1) Browser (OAuth) {browser_note}", err=True)
|
|
315
315
|
typer.echo(f" 2) Device code {device_note}", err=True)
|
|
316
316
|
typer.echo(" 3) Paste an API token for CI and scripts", err=True)
|
|
317
|
-
default = "1" if available else "3"
|
|
318
317
|
if sys.stdin.isatty():
|
|
319
|
-
return _choose_by_keypress(
|
|
320
|
-
|
|
318
|
+
return _choose_by_keypress()
|
|
319
|
+
# No default: an empty line is asked again, so Enter never picks a method.
|
|
320
|
+
choice = _ask("Choose").strip()
|
|
321
321
|
if choice not in _METHOD_KEYS:
|
|
322
322
|
raise _bad_choice(choice)
|
|
323
323
|
return _METHOD_KEYS[choice]
|
|
@@ -330,31 +330,32 @@ _METHOD_LABELS = {"1": "Browser (OAuth)", "2": "Device code", "3": "API token"}
|
|
|
330
330
|
def _bad_choice(choice: str) -> CliError:
|
|
331
331
|
return CliError(
|
|
332
332
|
code="invalid_login_method",
|
|
333
|
-
message=f"'{choice}' is not
|
|
333
|
+
message=f"'{choice}' is not a valid choice; choose 1, 2 or 3.",
|
|
334
334
|
exit_status=EXIT_USAGE,
|
|
335
335
|
hint="Enter 1 for the browser, 2 for a device code or 3 to paste an API token.",
|
|
336
336
|
)
|
|
337
337
|
|
|
338
338
|
|
|
339
|
-
def _choose_by_keypress(
|
|
340
|
-
"""Read one key on a terminal: 1, 2 or 3 selects at once
|
|
339
|
+
def _choose_by_keypress() -> str:
|
|
340
|
+
"""Read one key on a terminal: 1, 2 or 3 selects at once.
|
|
341
341
|
|
|
342
|
-
|
|
342
|
+
Enter picks nothing: it and any other key ask again, up to three times, then
|
|
343
|
+
error naming the last key. Ctrl-C and Ctrl-D are a usage error, or an invalid
|
|
344
|
+
choice when a wrong key came first.
|
|
343
345
|
"""
|
|
344
346
|
key = ""
|
|
345
|
-
for _attempt in range(
|
|
347
|
+
for _attempt in range(3):
|
|
346
348
|
typer.echo("Choose: ", nl=False, err=True)
|
|
347
349
|
try:
|
|
348
350
|
key = typer.getchar()
|
|
349
351
|
except (KeyboardInterrupt, EOFError):
|
|
350
352
|
typer.echo("", err=True)
|
|
351
|
-
raise _no_choice() from None
|
|
352
|
-
if key in ("\r", "\n"):
|
|
353
|
-
key = default
|
|
353
|
+
raise (_bad_choice(key) if key.strip() else _no_choice()) from None
|
|
354
354
|
if key in _METHOD_KEYS:
|
|
355
355
|
typer.echo(f"{key} {_METHOD_LABELS[key]}", err=True)
|
|
356
356
|
return _METHOD_KEYS[key]
|
|
357
357
|
typer.echo("", err=True)
|
|
358
|
+
typer.echo("Enter 1, 2 or 3.", err=True)
|
|
358
359
|
raise _bad_choice(key)
|
|
359
360
|
|
|
360
361
|
|