mammoth-cli 1.0.0__tar.gz → 1.0.2__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-1.0.2/PKG-INFO +174 -0
- mammoth_cli-1.0.2/README.md +143 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/__init__.py +1 -1
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/app.py +18 -6
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +36 -9
- mammoth_cli-1.0.2/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +28 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/__init__.py +2 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/auth.py +13 -66
- mammoth_cli-1.0.2/mammoth_cli/commands/upgrade.py +347 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/context/endpoint.py +5 -5
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/context/profiles.py +4 -4
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/context/resolver.py +18 -90
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/contracts/auth.py +1 -1
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/output/policy.py +28 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/runtime/invocation.py +17 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/runtime/options.py +11 -3
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/testing.py +14 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/pyproject.toml +2 -2
- mammoth_cli-1.0.2/spec/manifests/commands/upgrade.yaml +35 -0
- mammoth_cli-1.0.0/PKG-INFO +0 -92
- mammoth_cli-1.0.0/README.md +0 -61
- mammoth_cli-1.0.0/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -27
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/LICENSE +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/__main__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/activity.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/addon.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/agent.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/ai.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/annotation.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/automation.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/batch.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/billing.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/browse.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/capability.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/client_app.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/completion.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/config.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/connector.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/context.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/dashboard.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/data_app.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/dataset.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/doctor.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/external_key.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/file.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/folder.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/job.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/notification.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/parameter.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/project.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/registry.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/report.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/schedule.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/schema.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/skill.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/snippet.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/support.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/template.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/trash.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/user.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/view.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/view_ops.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/webhook.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/workflow.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/commands/workspace.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/context/__init__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/context/credentials.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/contracts/__init__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/errors/__init__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/errors/envelope.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/manifest/__init__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/manifest/loader.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/messages/__init__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/output/__init__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/output/envelope.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/output/normalize.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/output/render.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/py.typed +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/runtime/__init__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/runtime/confirm.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/runtime/executor.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/runtime/input_loader.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/runtime/session.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/runtime/strict.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/runtime/validate.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/__init__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/argspec.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/coerce.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/conditions.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/dispatch.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/factory.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/input_fields.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/mapping.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/openapi_types.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/positionals.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/protocol.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/sdk_service.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/testing.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/services/type_system.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/skills/__init__.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/mammoth_cli/skills/installer.py +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/_sdk_introspection.json +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/activity.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/addon.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/agent.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/ai.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/annotation.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/auth.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/automation.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/batch.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/billing.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/browse.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/capability.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/client-app.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/completion.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/config.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/connector.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/context.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/dashboard.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/data-app.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/dataset.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/doctor.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/external-key.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/file.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/folder.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/job.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/notification.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/parameter.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/project.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/report.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/schedule.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/schema.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/skill.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/snippet.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/support.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/template.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/trash.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/user.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/version.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/view.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/webhook.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/workflow.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/commands/workspace.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/openapi-operations.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/schema-v1.json +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/sdk-catalog.source.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/manifests/sdk-methods.yaml +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/openapi/metadata.json +0 -0
- {mammoth_cli-1.0.0 → mammoth_cli-1.0.2}/spec/openapi/openapi.json +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mammoth-cli
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Command-line interface for the Mammoth Analytics platform
|
|
5
|
+
License: Proprietary
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Mammoth Analytics
|
|
8
|
+
Author-email: support@mammoth.io
|
|
9
|
+
Requires-Python: >=3.12,<3.15
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: Other/Proprietary License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Dist: PyYAML (>=6,<7)
|
|
20
|
+
Requires-Dist: keyring (>=25.7,<26)
|
|
21
|
+
Requires-Dist: mammoth-io (>=0.6.0,<0.7)
|
|
22
|
+
Requires-Dist: platformdirs (>=4.10,<5)
|
|
23
|
+
Requires-Dist: pydantic (>=2.13,<3)
|
|
24
|
+
Requires-Dist: rich (>=15,<16)
|
|
25
|
+
Requires-Dist: tomlkit (>=0.15.1,<0.16)
|
|
26
|
+
Requires-Dist: typer (>=0.27,<0.28)
|
|
27
|
+
Project-URL: Homepage, https://mammoth.io
|
|
28
|
+
Project-URL: Repository, https://github.com/EdgeMetric/mammothsdk
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# mammoth-cli
|
|
32
|
+
|
|
33
|
+
Drive the [Mammoth Analytics](https://mammoth.io) platform from your terminal.
|
|
34
|
+
The `mammoth` command uploads data, runs pipeline transformations, manages
|
|
35
|
+
projects and dashboards, and exports results — for people at a shell and for
|
|
36
|
+
autonomous agents alike.
|
|
37
|
+
|
|
38
|
+
[](https://pypi.org/project/mammoth-cli/)
|
|
39
|
+
[](https://pypi.org/project/mammoth-cli/)
|
|
40
|
+
[](https://github.com/EdgeMetric/mammothsdk/blob/main/mammoth-cli/LICENSE)
|
|
41
|
+
|
|
42
|
+
- **Human-friendly by default.** In a terminal, commands print a readable table.
|
|
43
|
+
- **Agent-native.** When output is piped, you get a stable JSON envelope with a
|
|
44
|
+
documented schema, exit codes, and error codes — no flags required.
|
|
45
|
+
- **Safe.** Every mutation carries a reviewed confirmation policy, so a
|
|
46
|
+
destructive command never runs unattended by accident.
|
|
47
|
+
- **Discoverable.** `mammoth capability list` and `mammoth schema get` describe
|
|
48
|
+
every command, so an agent can learn the surface at runtime.
|
|
49
|
+
|
|
50
|
+
The CLI is built on the public [`mammoth-io`](https://pypi.org/project/mammoth-io/)
|
|
51
|
+
SDK. It adds no second HTTP client and calls no private SDK members.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
uv tool install mammoth-cli # recommended: isolated, on your PATH
|
|
57
|
+
# or
|
|
58
|
+
pipx install mammoth-cli
|
|
59
|
+
# or
|
|
60
|
+
python -m pip install mammoth-cli
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Then confirm the install:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
mammoth --version
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The CLI supports Python 3.12, 3.13, and 3.14. For the one-line installers and
|
|
70
|
+
the verified (signed) install flow, see [docs/installation.md](docs/installation.md).
|
|
71
|
+
|
|
72
|
+
## Quick start
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
mammoth auth login -w 4 # log in once; the secret goes to your OS keyring
|
|
76
|
+
mammoth doctor # confirm credentials resolve and the API answers
|
|
77
|
+
mammoth project list # a table in a terminal, JSON when piped
|
|
78
|
+
mammoth dataset list --project 180
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Full walkthrough: [docs/quickstart.md](docs/quickstart.md).
|
|
82
|
+
|
|
83
|
+
## Built for agents and CI
|
|
84
|
+
|
|
85
|
+
Piping or redirecting output yields the machine envelope, and `--no-input` turns
|
|
86
|
+
on automatically off a terminal, so an agent needs no special flags:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
mammoth project list | jq '.data'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
To be explicit, pass `--output json --no-input`. Log in without a prompt with a
|
|
93
|
+
permission-checked file:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
mammoth auth login --input creds.json --output json --no-input
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Feed multi-field requests as one document instead of many flags:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
mammoth view transform math 1039 --project 180 \
|
|
103
|
+
--input '{"expression": "price * qty", "new_column": "total"}'
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Install the bundled agent skill for Claude Code, Codex, and Cursor:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
mammoth skill install
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
See [docs/agents.md](docs/agents.md) and the
|
|
113
|
+
[agent skill](mammoth_cli/bundled_skill/mammoth-cli/SKILL.md).
|
|
114
|
+
|
|
115
|
+
## What you can do
|
|
116
|
+
|
|
117
|
+
| Area | Command families |
|
|
118
|
+
|---|---|
|
|
119
|
+
| Data in and out | `file`, `dataset`, `connector`, `addon` |
|
|
120
|
+
| Shape and analyze | `view`, `dataset`, `ai` |
|
|
121
|
+
| Organize | `project`, `folder`, `dashboard`, `report`, `template` |
|
|
122
|
+
| Automate | `automation`, `workflow`, `schedule`, `batch`, `webhook` |
|
|
123
|
+
| Administer | `workspace`, `user`, `billing`, `client-app`, `external-key` |
|
|
124
|
+
| Operate the CLI | `auth`, `context`, `config`, `doctor`, `capability`, `schema`, `skill`, `upgrade` |
|
|
125
|
+
|
|
126
|
+
The full generated list is in [docs/reference/commands.md](docs/reference/commands.md).
|
|
127
|
+
|
|
128
|
+
## Documentation
|
|
129
|
+
|
|
130
|
+
| Guide | What it covers |
|
|
131
|
+
|---|---|
|
|
132
|
+
| [Installation](docs/installation.md) | Install the CLI and the agent skill. |
|
|
133
|
+
| [Quick start](docs/quickstart.md) | Log in and run your first commands. |
|
|
134
|
+
| [Authentication](docs/authentication.md) | Getting an API key, login, profiles, projects. |
|
|
135
|
+
| [Agent and CI usage](docs/agents.md) | Machine output, structured input, patterns. |
|
|
136
|
+
| [Safe mutation](docs/safety.md) | Mutation classes and confirmation policies. |
|
|
137
|
+
| [Output and errors](docs/reference/output-and-errors.md) | Envelopes, exit codes, error codes. |
|
|
138
|
+
| [Global flags](docs/reference/global-flags.md) | The flags every command shares. |
|
|
139
|
+
| [Troubleshooting](docs/troubleshooting.md) | Exit codes, error envelopes, recovery. |
|
|
140
|
+
| [Upgrade](docs/upgrade.md) / [Uninstall](docs/uninstall.md) | Keep the CLI current, or remove it. |
|
|
141
|
+
| [Command reference](docs/reference/commands.md) | Every command, grouped by family. |
|
|
142
|
+
|
|
143
|
+
Agent-readable indexes: [`docs/llms.txt`](docs/llms.txt) and
|
|
144
|
+
[`docs/llms-full.txt`](docs/llms-full.txt).
|
|
145
|
+
|
|
146
|
+
## Compatibility
|
|
147
|
+
|
|
148
|
+
`mammoth-cli` follows [Semantic Versioning](https://semver.org) for the 1.x
|
|
149
|
+
series:
|
|
150
|
+
|
|
151
|
+
- The machine-output and error-envelope contract is stable. `SCHEMA_VERSION`
|
|
152
|
+
(see `mammoth_cli/__init__.py`) identifies it and never changes incompatibly
|
|
153
|
+
within a major version. New fields may be added; existing ones are preserved.
|
|
154
|
+
- The CLI surface is stable. Command names, flags, and exit codes are not
|
|
155
|
+
removed or repurposed within a major version.
|
|
156
|
+
- Bug fixes ship in patch releases. Additive changes ship in minor releases.
|
|
157
|
+
|
|
158
|
+
## Development
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
pytest tests/ -q # unit + contract tests (live tests deselected)
|
|
162
|
+
ruff check mammoth_cli scripts tests
|
|
163
|
+
mypy mammoth_cli
|
|
164
|
+
make cli-docs-check # documentation gates
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Build scripts under `scripts/` regenerate the manifests and the documentation
|
|
168
|
+
corpus offline. Release and packaging details live in
|
|
169
|
+
[../RELEASING.md](../RELEASING.md).
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
See [LICENSE](LICENSE). Source: https://github.com/EdgeMetric/mammothsdk
|
|
174
|
+
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# mammoth-cli
|
|
2
|
+
|
|
3
|
+
Drive the [Mammoth Analytics](https://mammoth.io) platform from your terminal.
|
|
4
|
+
The `mammoth` command uploads data, runs pipeline transformations, manages
|
|
5
|
+
projects and dashboards, and exports results — for people at a shell and for
|
|
6
|
+
autonomous agents alike.
|
|
7
|
+
|
|
8
|
+
[](https://pypi.org/project/mammoth-cli/)
|
|
9
|
+
[](https://pypi.org/project/mammoth-cli/)
|
|
10
|
+
[](https://github.com/EdgeMetric/mammothsdk/blob/main/mammoth-cli/LICENSE)
|
|
11
|
+
|
|
12
|
+
- **Human-friendly by default.** In a terminal, commands print a readable table.
|
|
13
|
+
- **Agent-native.** When output is piped, you get a stable JSON envelope with a
|
|
14
|
+
documented schema, exit codes, and error codes — no flags required.
|
|
15
|
+
- **Safe.** Every mutation carries a reviewed confirmation policy, so a
|
|
16
|
+
destructive command never runs unattended by accident.
|
|
17
|
+
- **Discoverable.** `mammoth capability list` and `mammoth schema get` describe
|
|
18
|
+
every command, so an agent can learn the surface at runtime.
|
|
19
|
+
|
|
20
|
+
The CLI is built on the public [`mammoth-io`](https://pypi.org/project/mammoth-io/)
|
|
21
|
+
SDK. It adds no second HTTP client and calls no private SDK members.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
uv tool install mammoth-cli # recommended: isolated, on your PATH
|
|
27
|
+
# or
|
|
28
|
+
pipx install mammoth-cli
|
|
29
|
+
# or
|
|
30
|
+
python -m pip install mammoth-cli
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Then confirm the install:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
mammoth --version
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The CLI supports Python 3.12, 3.13, and 3.14. For the one-line installers and
|
|
40
|
+
the verified (signed) install flow, see [docs/installation.md](docs/installation.md).
|
|
41
|
+
|
|
42
|
+
## Quick start
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
mammoth auth login -w 4 # log in once; the secret goes to your OS keyring
|
|
46
|
+
mammoth doctor # confirm credentials resolve and the API answers
|
|
47
|
+
mammoth project list # a table in a terminal, JSON when piped
|
|
48
|
+
mammoth dataset list --project 180
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Full walkthrough: [docs/quickstart.md](docs/quickstart.md).
|
|
52
|
+
|
|
53
|
+
## Built for agents and CI
|
|
54
|
+
|
|
55
|
+
Piping or redirecting output yields the machine envelope, and `--no-input` turns
|
|
56
|
+
on automatically off a terminal, so an agent needs no special flags:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
mammoth project list | jq '.data'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
To be explicit, pass `--output json --no-input`. Log in without a prompt with a
|
|
63
|
+
permission-checked file:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
mammoth auth login --input creds.json --output json --no-input
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Feed multi-field requests as one document instead of many flags:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
mammoth view transform math 1039 --project 180 \
|
|
73
|
+
--input '{"expression": "price * qty", "new_column": "total"}'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Install the bundled agent skill for Claude Code, Codex, and Cursor:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
mammoth skill install
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
See [docs/agents.md](docs/agents.md) and the
|
|
83
|
+
[agent skill](mammoth_cli/bundled_skill/mammoth-cli/SKILL.md).
|
|
84
|
+
|
|
85
|
+
## What you can do
|
|
86
|
+
|
|
87
|
+
| Area | Command families |
|
|
88
|
+
|---|---|
|
|
89
|
+
| Data in and out | `file`, `dataset`, `connector`, `addon` |
|
|
90
|
+
| Shape and analyze | `view`, `dataset`, `ai` |
|
|
91
|
+
| Organize | `project`, `folder`, `dashboard`, `report`, `template` |
|
|
92
|
+
| Automate | `automation`, `workflow`, `schedule`, `batch`, `webhook` |
|
|
93
|
+
| Administer | `workspace`, `user`, `billing`, `client-app`, `external-key` |
|
|
94
|
+
| Operate the CLI | `auth`, `context`, `config`, `doctor`, `capability`, `schema`, `skill`, `upgrade` |
|
|
95
|
+
|
|
96
|
+
The full generated list is in [docs/reference/commands.md](docs/reference/commands.md).
|
|
97
|
+
|
|
98
|
+
## Documentation
|
|
99
|
+
|
|
100
|
+
| Guide | What it covers |
|
|
101
|
+
|---|---|
|
|
102
|
+
| [Installation](docs/installation.md) | Install the CLI and the agent skill. |
|
|
103
|
+
| [Quick start](docs/quickstart.md) | Log in and run your first commands. |
|
|
104
|
+
| [Authentication](docs/authentication.md) | Getting an API key, login, profiles, projects. |
|
|
105
|
+
| [Agent and CI usage](docs/agents.md) | Machine output, structured input, patterns. |
|
|
106
|
+
| [Safe mutation](docs/safety.md) | Mutation classes and confirmation policies. |
|
|
107
|
+
| [Output and errors](docs/reference/output-and-errors.md) | Envelopes, exit codes, error codes. |
|
|
108
|
+
| [Global flags](docs/reference/global-flags.md) | The flags every command shares. |
|
|
109
|
+
| [Troubleshooting](docs/troubleshooting.md) | Exit codes, error envelopes, recovery. |
|
|
110
|
+
| [Upgrade](docs/upgrade.md) / [Uninstall](docs/uninstall.md) | Keep the CLI current, or remove it. |
|
|
111
|
+
| [Command reference](docs/reference/commands.md) | Every command, grouped by family. |
|
|
112
|
+
|
|
113
|
+
Agent-readable indexes: [`docs/llms.txt`](docs/llms.txt) and
|
|
114
|
+
[`docs/llms-full.txt`](docs/llms-full.txt).
|
|
115
|
+
|
|
116
|
+
## Compatibility
|
|
117
|
+
|
|
118
|
+
`mammoth-cli` follows [Semantic Versioning](https://semver.org) for the 1.x
|
|
119
|
+
series:
|
|
120
|
+
|
|
121
|
+
- The machine-output and error-envelope contract is stable. `SCHEMA_VERSION`
|
|
122
|
+
(see `mammoth_cli/__init__.py`) identifies it and never changes incompatibly
|
|
123
|
+
within a major version. New fields may be added; existing ones are preserved.
|
|
124
|
+
- The CLI surface is stable. Command names, flags, and exit codes are not
|
|
125
|
+
removed or repurposed within a major version.
|
|
126
|
+
- Bug fixes ship in patch releases. Additive changes ship in minor releases.
|
|
127
|
+
|
|
128
|
+
## Development
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pytest tests/ -q # unit + contract tests (live tests deselected)
|
|
132
|
+
ruff check mammoth_cli scripts tests
|
|
133
|
+
mypy mammoth_cli
|
|
134
|
+
make cli-docs-check # documentation gates
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Build scripts under `scripts/` regenerate the manifests and the documentation
|
|
138
|
+
corpus offline. Release and packaging details live in
|
|
139
|
+
[../RELEASING.md](../RELEASING.md).
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
See [LICENSE](LICENSE). Source: https://github.com/EdgeMetric/mammothsdk
|
|
@@ -29,7 +29,14 @@ from mammoth_cli.commands import BESPOKE
|
|
|
29
29
|
from mammoth_cli.commands.registry import HANDLERS
|
|
30
30
|
from mammoth_cli.errors.envelope import EXIT_USAGE, CliError, not_implemented_error
|
|
31
31
|
from mammoth_cli.manifest.loader import command_by_id, load_commands
|
|
32
|
-
from mammoth_cli.output.policy import
|
|
32
|
+
from mammoth_cli.output.policy import (
|
|
33
|
+
COLOR_MODES,
|
|
34
|
+
MACHINE_OUTPUTS,
|
|
35
|
+
OUTPUT_AUTO,
|
|
36
|
+
SELECTABLE_OUTPUTS,
|
|
37
|
+
VALID_OUTPUTS,
|
|
38
|
+
resolve_output,
|
|
39
|
+
)
|
|
33
40
|
from mammoth_cli.runtime import executor, validate
|
|
34
41
|
from mammoth_cli.runtime.invocation import Invocation
|
|
35
42
|
from mammoth_cli.runtime.strict import validate_extra_args
|
|
@@ -52,10 +59,12 @@ def _output_mode_from_argv(argv: Sequence[str] | None) -> str:
|
|
|
52
59
|
Used when a Click ``UsageError`` is raised *before* the per-command option
|
|
53
60
|
is parsed (an unknown command, an unexpected argument, a bad option value),
|
|
54
61
|
so the top-level error renderer can still honor the machine-output contract.
|
|
55
|
-
Defaults to the same ``
|
|
62
|
+
Defaults to the same ``auto`` default the ``--output`` option declares, then
|
|
63
|
+
resolves it against whether stdout is a terminal — so a piped invocation
|
|
64
|
+
gets the machine envelope even for an error raised before option parsing.
|
|
56
65
|
"""
|
|
57
66
|
tokens = list(argv) if argv is not None else sys.argv[1:]
|
|
58
|
-
mode =
|
|
67
|
+
mode = OUTPUT_AUTO
|
|
59
68
|
index = 0
|
|
60
69
|
while index < len(tokens):
|
|
61
70
|
token = tokens[index]
|
|
@@ -69,7 +78,7 @@ def _output_mode_from_argv(argv: Sequence[str] | None) -> str:
|
|
|
69
78
|
elif token.startswith("-o") and len(token) > 2:
|
|
70
79
|
mode = token[2:]
|
|
71
80
|
index += 1
|
|
72
|
-
return mode
|
|
81
|
+
return resolve_output(mode, is_tty=sys.stdout.isatty())
|
|
73
82
|
|
|
74
83
|
|
|
75
84
|
class _EnvelopeGroup(TyperGroup):
|
|
@@ -160,11 +169,14 @@ def _shared_option_params() -> list[inspect.Parameter]:
|
|
|
160
169
|
return [
|
|
161
170
|
opt(
|
|
162
171
|
"output",
|
|
163
|
-
|
|
172
|
+
OUTPUT_AUTO,
|
|
164
173
|
Annotated[
|
|
165
174
|
str,
|
|
166
175
|
typer.Option(
|
|
167
|
-
"--output",
|
|
176
|
+
"--output",
|
|
177
|
+
"-o",
|
|
178
|
+
help="Output format. 'auto' picks a table on a terminal, JSON when piped.",
|
|
179
|
+
metavar="|".join(SELECTABLE_OUTPUTS),
|
|
168
180
|
),
|
|
169
181
|
],
|
|
170
182
|
),
|
|
@@ -11,7 +11,9 @@ deterministic machine output, promptless operation, and stable error envelopes.
|
|
|
11
11
|
|
|
12
12
|
## Golden rules for agents
|
|
13
13
|
|
|
14
|
-
1. Always pass `--output json` and `--no-input`.
|
|
14
|
+
1. Always pass `--output json` and `--no-input`. Machine output is automatic
|
|
15
|
+
when piped or redirected, and `--no-input` turns on automatically off a
|
|
16
|
+
terminal, but keeping both flags explicit is fine. Never rely on a prompt.
|
|
15
17
|
2. Discover, do not guess. Use `mammoth capability list` and `mammoth schema get`
|
|
16
18
|
to learn a command before you run it.
|
|
17
19
|
3. Read the exit code, not the text. `0` ok, `2` usage, `4` auth, `5` not found,
|
|
@@ -20,19 +22,33 @@ deterministic machine output, promptless operation, and stable error envelopes.
|
|
|
20
22
|
commands also need `--confirm TARGET`. There is no interactive fallback under
|
|
21
23
|
`--no-input`.
|
|
22
24
|
5. Never put a secret on the command line. Pass credentials through
|
|
23
|
-
`mammoth auth login` (
|
|
24
|
-
`--input`.
|
|
25
|
+
`mammoth auth login` (interactive) or `mammoth auth login --input creds.json`
|
|
26
|
+
(non-interactive), and structured secrets through `--input`.
|
|
25
27
|
|
|
26
28
|
## Authenticate
|
|
27
29
|
|
|
30
|
+
Login is the only way to authenticate. Interactive login prompts for the API
|
|
31
|
+
key and secret (hidden input):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
mammoth auth login -w 4 # -w is the workspace id
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For agents, log in non-interactively from a `0600` JSON file:
|
|
38
|
+
|
|
28
39
|
```bash
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
cat > creds.json <<'JSON'
|
|
41
|
+
{"api_key": "...", "api_secret": "...", "workspace_id": 4, "server_prefix": "app"}
|
|
42
|
+
JSON
|
|
43
|
+
chmod 600 creds.json
|
|
44
|
+
mammoth auth login --input creds.json --output json --no-input
|
|
45
|
+
mammoth doctor --output json --no-input # verify credentials + endpoint
|
|
31
46
|
```
|
|
32
47
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
`server_prefix` is optional (default `app`). You can also pipe the document with
|
|
49
|
+
`--input - --input-format json`. Credentials resolve in this order: explicit
|
|
50
|
+
login, then the saved profile. The endpoint defaults to the `app` server prefix.
|
|
51
|
+
See [references/auth.md](references/auth.md).
|
|
36
52
|
|
|
37
53
|
## Select a project
|
|
38
54
|
|
|
@@ -85,7 +101,7 @@ mammoth view transform bulk-replace VIEW_ID \
|
|
|
85
101
|
|
|
86
102
|
```bash
|
|
87
103
|
mammoth dataset delete 2340 --project 180 --output json --no-input --yes
|
|
88
|
-
mammoth workspace delete
|
|
104
|
+
mammoth workspace delete --output json --no-input --yes --confirm 9
|
|
89
105
|
```
|
|
90
106
|
|
|
91
107
|
See [references/safety.md](references/safety.md).
|
|
@@ -107,3 +123,14 @@ mammoth capability list --output json --no-input # every operation
|
|
|
107
123
|
mammoth schema list --output json --no-input # every command's schema
|
|
108
124
|
mammoth schema get view.transform.filter --output json --no-input
|
|
109
125
|
```
|
|
126
|
+
|
|
127
|
+
## Keep the CLI current
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
mammoth upgrade --check --output json --no-input # read-only: installed vs latest on PyPI
|
|
131
|
+
mammoth upgrade --yes --output json --no-input # upgrade in place (requires --yes when non-interactive)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`mammoth upgrade` detects how the CLI was installed (uv tool, pipx, or pip) and
|
|
135
|
+
upgrades it; `--check` changes nothing. Pin an exact release with
|
|
136
|
+
`--version X.Y.Z`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Authentication and profiles
|
|
2
|
+
|
|
3
|
+
Required: API key, API secret, workspace id. Optional: a one-label server
|
|
4
|
+
prefix (default `app`, resolving to `https://app.mammoth.io/api/v2`).
|
|
5
|
+
|
|
6
|
+
## Precedence
|
|
7
|
+
1. Explicit login handed to the current command (secure prompt or `--input`).
|
|
8
|
+
2. The selected or `--profile` profile's saved credentials.
|
|
9
|
+
|
|
10
|
+
The only supported configuration is the API key, API secret, workspace id, and
|
|
11
|
+
an optional one-label server prefix (default `app`). There is no base-url
|
|
12
|
+
override.
|
|
13
|
+
|
|
14
|
+
## Commands
|
|
15
|
+
```bash
|
|
16
|
+
mammoth auth login -w 4 --output json --no-input # prompts for key + secret
|
|
17
|
+
mammoth auth login --input creds.json --output json --no-input # non-interactive
|
|
18
|
+
mammoth auth status --output json --no-input
|
|
19
|
+
mammoth auth logout --profile default --output json --no-input --yes
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`creds.json` is a `0600` JSON file: `{"api_key": "...", "api_secret": "...",
|
|
23
|
+
"workspace_id": 4, "server_prefix": "app"}` (`server_prefix` optional). You can
|
|
24
|
+
also pipe it with `--input - --input-format json`.
|
|
25
|
+
|
|
26
|
+
Secrets live in the OS keyring (or a `0600` file fallback). They are never
|
|
27
|
+
printed, logged, or included in any envelope. Never pass a secret as a plain
|
|
28
|
+
argument; use the prompt or `--input`.
|
|
@@ -14,6 +14,7 @@ from collections.abc import Callable
|
|
|
14
14
|
from mammoth_cli.commands import auth as auth_cmd
|
|
15
15
|
from mammoth_cli.commands import config as config_cmd
|
|
16
16
|
from mammoth_cli.commands import context as context_cmd
|
|
17
|
+
from mammoth_cli.commands import upgrade as upgrade_cmd
|
|
17
18
|
|
|
18
19
|
BESPOKE: dict[str, Callable[..., None]] = {
|
|
19
20
|
"auth.login": auth_cmd.auth_login,
|
|
@@ -26,4 +27,5 @@ BESPOKE: dict[str, Callable[..., None]] = {
|
|
|
26
27
|
"context.project.status": context_cmd.context_project_status,
|
|
27
28
|
"context.project.use": context_cmd.context_project_use,
|
|
28
29
|
"context.project.clear": context_cmd.context_project_clear,
|
|
30
|
+
"upgrade": upgrade_cmd.upgrade_command,
|
|
29
31
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"""Bespoke `auth` command family: login, status, logout.
|
|
2
2
|
|
|
3
3
|
Authentication has exactly three required inputs (API key, API secret,
|
|
4
|
-
workspace id) and one optional input (server prefix, default ``app
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
document read through the shared ``--input`` option.
|
|
4
|
+
workspace id) and one optional input (server prefix, default ``app``).
|
|
5
|
+
Authentication always requires a login; there is no environment credential
|
|
6
|
+
path. These commands never accept a secret as an ordinary command-line value:
|
|
7
|
+
the API key and secret come from a hidden TTY prompt or a permission-checked
|
|
8
|
+
JSON/YAML login document read through the shared ``--input`` option.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
@@ -24,10 +24,6 @@ from pydantic import ValidationError
|
|
|
24
24
|
from mammoth_cli.context import credentials, profiles
|
|
25
25
|
from mammoth_cli.context.endpoint import resolve_base_url
|
|
26
26
|
from mammoth_cli.context.resolver import (
|
|
27
|
-
ENV_API_KEY,
|
|
28
|
-
ENV_API_SECRET,
|
|
29
|
-
ENV_SERVER_PREFIX,
|
|
30
|
-
ENV_WORKSPACE_ID,
|
|
31
27
|
ResolvedAuth,
|
|
32
28
|
resolve_auth,
|
|
33
29
|
)
|
|
@@ -189,48 +185,12 @@ def _validate_login_document(document: dict[str, Any]) -> LoginRequest:
|
|
|
189
185
|
) from exc
|
|
190
186
|
|
|
191
187
|
|
|
192
|
-
def _read_env_login() -> tuple[str, str, int | None, str | None]:
|
|
193
|
-
"""Read credentials from the four documented ``MAMMOTH_*`` variables.
|
|
194
|
-
|
|
195
|
-
Returns:
|
|
196
|
-
``(api_key, api_secret, workspace_id, server_prefix)``. Workspace id
|
|
197
|
-
and server prefix are None when their variable is unset.
|
|
198
|
-
|
|
199
|
-
Raises:
|
|
200
|
-
CliError: ``missing_env_credentials`` when the API key or secret
|
|
201
|
-
variable is unset.
|
|
202
|
-
"""
|
|
203
|
-
api_key = os.environ.get(ENV_API_KEY)
|
|
204
|
-
api_secret = os.environ.get(ENV_API_SECRET)
|
|
205
|
-
workspace_raw = os.environ.get(ENV_WORKSPACE_ID)
|
|
206
|
-
server_prefix = os.environ.get(ENV_SERVER_PREFIX)
|
|
207
|
-
if not api_key or not api_secret:
|
|
208
|
-
raise CliError(
|
|
209
|
-
code="missing_env_credentials",
|
|
210
|
-
message="MAMMOTH_API_KEY and MAMMOTH_API_SECRET must be set for --from-env.",
|
|
211
|
-
exit_status=EXIT_USAGE,
|
|
212
|
-
)
|
|
213
|
-
workspace_id: int | None = None
|
|
214
|
-
if workspace_raw:
|
|
215
|
-
try:
|
|
216
|
-
workspace_id = int(workspace_raw)
|
|
217
|
-
except ValueError as exc:
|
|
218
|
-
raise CliError(
|
|
219
|
-
code=CODE_INVALID_WORKSPACE_ID,
|
|
220
|
-
message="MAMMOTH_WORKSPACE_ID must be an integer.",
|
|
221
|
-
exit_status=EXIT_USAGE,
|
|
222
|
-
hint="Set MAMMOTH_WORKSPACE_ID to a numeric workspace id.",
|
|
223
|
-
) from exc
|
|
224
|
-
return api_key, api_secret, workspace_id, server_prefix
|
|
225
|
-
|
|
226
|
-
|
|
227
188
|
def _run_login(
|
|
228
189
|
invocation: Invocation,
|
|
229
190
|
*,
|
|
230
191
|
workspace: int | None,
|
|
231
192
|
server_prefix: str | None,
|
|
232
193
|
storage: str,
|
|
233
|
-
from_env: bool,
|
|
234
194
|
) -> tuple[dict[str, Any], dict[str, Any]]:
|
|
235
195
|
"""Validate, connection-check, and persist one `auth login` invocation."""
|
|
236
196
|
if storage not in _STORAGE_MODES:
|
|
@@ -240,12 +200,6 @@ def _run_login(
|
|
|
240
200
|
exit_status=EXIT_USAGE,
|
|
241
201
|
hint=f"Use one of: {', '.join(_STORAGE_MODES)}.",
|
|
242
202
|
)
|
|
243
|
-
if from_env and invocation.input_file is not None:
|
|
244
|
-
raise CliError(
|
|
245
|
-
code="invalid_input_mode",
|
|
246
|
-
message="--from-env and --input are mutually exclusive.",
|
|
247
|
-
exit_status=EXIT_USAGE,
|
|
248
|
-
)
|
|
249
203
|
|
|
250
204
|
policy = resolve_policy(
|
|
251
205
|
output=invocation.output,
|
|
@@ -255,11 +209,8 @@ def _run_login(
|
|
|
255
209
|
color=invocation.color,
|
|
256
210
|
)
|
|
257
211
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
effective_workspace = workspace if workspace is not None else env_workspace
|
|
261
|
-
effective_prefix = server_prefix if server_prefix is not None else env_prefix
|
|
262
|
-
elif invocation.input_file is not None:
|
|
212
|
+
effective_workspace: int | None
|
|
213
|
+
if invocation.input_file is not None:
|
|
263
214
|
document = _load_login_document(invocation.input_file, invocation.input_format)
|
|
264
215
|
request = _validate_login_document(document)
|
|
265
216
|
api_key, api_secret = request.api_key, request.api_secret
|
|
@@ -273,9 +224,9 @@ def _run_login(
|
|
|
273
224
|
else:
|
|
274
225
|
raise CliError(
|
|
275
226
|
code="login_input_required",
|
|
276
|
-
message="Non-interactive login requires --
|
|
227
|
+
message="Non-interactive login requires --input.",
|
|
277
228
|
exit_status=EXIT_USAGE,
|
|
278
|
-
hint="Pass --
|
|
229
|
+
hint="Pass --input FILE|- (with --input-format for stdin), or run in a terminal.",
|
|
279
230
|
)
|
|
280
231
|
|
|
281
232
|
if effective_workspace is None or effective_workspace <= 0:
|
|
@@ -350,22 +301,19 @@ def auth_login(
|
|
|
350
301
|
None,
|
|
351
302
|
"--workspace",
|
|
352
303
|
"-w",
|
|
353
|
-
help="Workspace id. Required unless --
|
|
304
|
+
help="Workspace id. Required unless --input supplies it.",
|
|
354
305
|
),
|
|
355
306
|
server_prefix: str | None = typer.Option(
|
|
356
|
-
None, "--server-prefix", help="Server prefix (one DNS label). Default 'app
|
|
307
|
+
None, "--server-prefix", help="Server prefix (one DNS label). Default 'app'."
|
|
357
308
|
),
|
|
358
309
|
storage: str = typer.Option(
|
|
359
310
|
"auto", "--storage", help="Credential storage backend.", metavar="auto|keyring|file"
|
|
360
311
|
),
|
|
361
|
-
from_env: bool = typer.Option(
|
|
362
|
-
False,
|
|
363
|
-
"--from-env",
|
|
364
|
-
help="Read credentials from MAMMOTH_API_KEY/MAMMOTH_API_SECRET/MAMMOTH_WORKSPACE_ID.",
|
|
365
|
-
),
|
|
366
312
|
) -> None:
|
|
367
313
|
"""Log in and store one profile's credentials.
|
|
368
314
|
|
|
315
|
+
Prompts for the API key and secret in a terminal. For non-interactive use
|
|
316
|
+
(agents, CI), pass ``--input FILE`` with a login document instead.
|
|
369
317
|
Performs a lightweight connection check before saving anything; a failed
|
|
370
318
|
check leaves existing profile state unchanged.
|
|
371
319
|
"""
|
|
@@ -391,7 +339,6 @@ def auth_login(
|
|
|
391
339
|
workspace=workspace,
|
|
392
340
|
server_prefix=server_prefix,
|
|
393
341
|
storage=storage,
|
|
394
|
-
from_env=from_env,
|
|
395
342
|
)
|
|
396
343
|
|
|
397
344
|
executor.run(invocation.command_id, invocation.output, producer)
|