minitest-cli 0.1.0__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.
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.4
2
+ Name: minitest-cli
3
+ Version: 0.1.0
4
+ Summary: Minitest CLI – command-line interface for the Minitest testing platform
5
+ Keywords: testing,cli,minitest,minitap,automation,qa
6
+ Author: Minitap Team
7
+ Author-email: Minitap Team <support@minitap.ai>
8
+ License-Expression: MIT
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Testing
18
+ Classifier: Typing :: Typed
19
+ Requires-Dist: typer>=0.24.1
20
+ Requires-Dist: httpx>=0.28.1
21
+ Requires-Dist: pydantic>=2.12.5
22
+ Requires-Dist: pydantic-settings>=2.13.1
23
+ Requires-Dist: rich>=14.3.3
24
+ Requires-Dist: ruff>=0.15.6 ; extra == 'dev'
25
+ Requires-Dist: pyright>=1.1.408 ; extra == 'dev'
26
+ Requires-Dist: pytest>=9.0.2 ; extra == 'dev'
27
+ Requires-Python: >=3.12
28
+ Project-URL: Homepage, https://minitap.ai/
29
+ Project-URL: Source, https://github.com/minitap-ai/minitest-cli
30
+ Project-URL: Bug Tracker, https://github.com/minitap-ai/minitest-cli/issues
31
+ Project-URL: Changelog, https://github.com/minitap-ai/minitest-cli/releases
32
+ Provides-Extra: dev
33
+ Description-Content-Type: text/markdown
34
+
35
+ # minitest-cli
36
+
37
+ Command-line interface for the Minitest testing platform.
38
+
39
+ ## Installation
40
+
41
+ ### pip (recommended)
42
+
43
+ ```bash
44
+ pip install minitest-cli
45
+ ```
46
+
47
+ ### uvx (zero-install)
48
+
49
+ Run without installing:
50
+
51
+ ```bash
52
+ uvx --from minitest-cli minitest --help
53
+ ```
54
+
55
+ ### Homebrew
56
+
57
+ ```bash
58
+ brew install minitap-ai/tap/minitest-cli
59
+ ```
60
+
61
+ ### From source
62
+
63
+ ```bash
64
+ git clone https://github.com/minitap-ai/minitest-cli.git
65
+ cd minitest-cli
66
+ uv sync
67
+ uv run minitest --help
68
+ ```
69
+
70
+ ## Quick Start
71
+
72
+ ```bash
73
+ # Authenticate
74
+ minitest auth login
75
+
76
+ # List your apps
77
+ minitest apps list
78
+
79
+ # Run tests
80
+ minitest run --app <app-id>
81
+ ```
82
+
83
+ ## Configuration
84
+
85
+ | Environment Variable | Description | Required |
86
+ |---------------------|-------------|----------|
87
+ | `MINITEST_TOKEN` | API authentication token | Yes (or use `minitest auth login`) |
88
+ | `MINITEST_APP_ID` | Default app ID | No (can use `--app` flag) |
89
+ | `MINITEST_API_URL` | API base URL | No (defaults to production) |
90
+
91
+ ## Global Flags
92
+
93
+ | Flag | Description |
94
+ |------|-------------|
95
+ | `--json` | Output JSON to stdout (diagnostics go to stderr) |
96
+ | `--app <id-or-name>` | Target app for commands that require one |
97
+ | `--version` | Show CLI version |
98
+ | `--help` | Show help |
99
+
100
+ ## Commands
101
+
102
+ | Command | Description |
103
+ |---------|-------------|
104
+ | `minitest auth` | Authentication management |
105
+ | `minitest apps` | App management |
106
+ | `minitest flow` | Testing flow operations |
107
+ | `minitest build` | Build management |
108
+ | `minitest run` | Test execution |
109
+
110
+ ## Exit Codes
111
+
112
+ | Code | Meaning |
113
+ |------|---------|
114
+ | 0 | Success |
115
+ | 1 | General error |
116
+ | 2 | Authentication error |
117
+ | 3 | Network / API error |
118
+ | 4 | Resource not found |
119
+
120
+ ## Development
121
+
122
+ ```bash
123
+ # Install dependencies
124
+ uv sync --dev
125
+
126
+ # Run linter
127
+ uv run ruff check .
128
+
129
+ # Run formatter
130
+ uv run ruff format .
131
+
132
+ # Run type checker
133
+ uv run pyright
134
+
135
+ # Run tests
136
+ uv run pytest
137
+ ```
@@ -0,0 +1,103 @@
1
+ # minitest-cli
2
+
3
+ Command-line interface for the Minitest testing platform.
4
+
5
+ ## Installation
6
+
7
+ ### pip (recommended)
8
+
9
+ ```bash
10
+ pip install minitest-cli
11
+ ```
12
+
13
+ ### uvx (zero-install)
14
+
15
+ Run without installing:
16
+
17
+ ```bash
18
+ uvx --from minitest-cli minitest --help
19
+ ```
20
+
21
+ ### Homebrew
22
+
23
+ ```bash
24
+ brew install minitap-ai/tap/minitest-cli
25
+ ```
26
+
27
+ ### From source
28
+
29
+ ```bash
30
+ git clone https://github.com/minitap-ai/minitest-cli.git
31
+ cd minitest-cli
32
+ uv sync
33
+ uv run minitest --help
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ```bash
39
+ # Authenticate
40
+ minitest auth login
41
+
42
+ # List your apps
43
+ minitest apps list
44
+
45
+ # Run tests
46
+ minitest run --app <app-id>
47
+ ```
48
+
49
+ ## Configuration
50
+
51
+ | Environment Variable | Description | Required |
52
+ |---------------------|-------------|----------|
53
+ | `MINITEST_TOKEN` | API authentication token | Yes (or use `minitest auth login`) |
54
+ | `MINITEST_APP_ID` | Default app ID | No (can use `--app` flag) |
55
+ | `MINITEST_API_URL` | API base URL | No (defaults to production) |
56
+
57
+ ## Global Flags
58
+
59
+ | Flag | Description |
60
+ |------|-------------|
61
+ | `--json` | Output JSON to stdout (diagnostics go to stderr) |
62
+ | `--app <id-or-name>` | Target app for commands that require one |
63
+ | `--version` | Show CLI version |
64
+ | `--help` | Show help |
65
+
66
+ ## Commands
67
+
68
+ | Command | Description |
69
+ |---------|-------------|
70
+ | `minitest auth` | Authentication management |
71
+ | `minitest apps` | App management |
72
+ | `minitest flow` | Testing flow operations |
73
+ | `minitest build` | Build management |
74
+ | `minitest run` | Test execution |
75
+
76
+ ## Exit Codes
77
+
78
+ | Code | Meaning |
79
+ |------|---------|
80
+ | 0 | Success |
81
+ | 1 | General error |
82
+ | 2 | Authentication error |
83
+ | 3 | Network / API error |
84
+ | 4 | Resource not found |
85
+
86
+ ## Development
87
+
88
+ ```bash
89
+ # Install dependencies
90
+ uv sync --dev
91
+
92
+ # Run linter
93
+ uv run ruff check .
94
+
95
+ # Run formatter
96
+ uv run ruff format .
97
+
98
+ # Run type checker
99
+ uv run pyright
100
+
101
+ # Run tests
102
+ uv run pytest
103
+ ```
@@ -0,0 +1,141 @@
1
+ [project]
2
+ name = "minitest-cli"
3
+ version = "0.1.0"
4
+ description = "Minitest CLI – command-line interface for the Minitest testing platform"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+
8
+ authors = [
9
+ { name = "Minitap Team", email = "support@minitap.ai" },
10
+ ]
11
+
12
+ keywords = ["testing", "cli", "minitest", "minitap", "automation", "qa"]
13
+
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Software Development :: Testing",
24
+ "Typing :: Typed",
25
+ ]
26
+
27
+ requires-python = ">=3.12"
28
+
29
+ dependencies = [
30
+ "typer>=0.24.1",
31
+ "httpx>=0.28.1",
32
+ "pydantic>=2.12.5",
33
+ "pydantic-settings>=2.13.1",
34
+ "rich>=14.3.3",
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ dev = [
39
+ "ruff>=0.15.6",
40
+ "pyright>=1.1.408",
41
+ "pytest>=9.0.2",
42
+ ]
43
+
44
+ [project.scripts]
45
+ minitest = "minitest_cli.main:app"
46
+
47
+ [project.urls]
48
+ "Homepage" = "https://minitap.ai/"
49
+ "Source" = "https://github.com/minitap-ai/minitest-cli"
50
+ "Bug Tracker" = "https://github.com/minitap-ai/minitest-cli/issues"
51
+ "Changelog" = "https://github.com/minitap-ai/minitest-cli/releases"
52
+
53
+ [build-system]
54
+ requires = ["uv_build>=0.10.11,<0.11.0"]
55
+ build-backend = "uv_build"
56
+
57
+ [tool.uv.build-backend]
58
+ module-root = "src"
59
+ module-name = "minitest_cli"
60
+
61
+ [tool.ruff]
62
+ exclude = [
63
+ ".bzr",
64
+ ".direnv",
65
+ ".eggs",
66
+ ".git",
67
+ ".git-rewrite",
68
+ ".hg",
69
+ ".ipynb_checkpoints",
70
+ ".mypy_cache",
71
+ ".nox",
72
+ ".pants.d",
73
+ ".pyenv",
74
+ ".pytest_cache",
75
+ ".pytype",
76
+ ".ruff_cache",
77
+ ".svn",
78
+ ".tox",
79
+ ".venv",
80
+ ".vscode",
81
+ "__pypackages__",
82
+ "_build",
83
+ "buck-out",
84
+ "build",
85
+ "dist",
86
+ "node_modules",
87
+ "site-packages",
88
+ "venv",
89
+ ]
90
+
91
+ line-length = 100
92
+ indent-width = 4
93
+
94
+ target-version = "py312"
95
+
96
+ [tool.ruff.lint]
97
+ select = ["E", "F", "TID", "UP"]
98
+ fixable = ["ALL"]
99
+ unfixable = []
100
+ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
101
+
102
+ [tool.ruff.lint.flake8-tidy-imports]
103
+ ban-relative-imports = "all"
104
+
105
+ [tool.ruff.format]
106
+ quote-style = "double"
107
+ indent-style = "space"
108
+ skip-magic-trailing-comma = false
109
+ line-ending = "auto"
110
+
111
+ [tool.pytest.ini_options]
112
+ pythonpath = [
113
+ "."
114
+ ]
115
+ testpaths = [
116
+ "tests"
117
+ ]
118
+ python_files = [
119
+ "*.test.py",
120
+ "test_*.py",
121
+ "*_test.py"
122
+ ]
123
+ python_functions = [
124
+ "test_*"
125
+ ]
126
+ python_classes = [
127
+ "Test*"
128
+ ]
129
+ addopts = [
130
+ "-v",
131
+ "--tb=short",
132
+ "--strict-markers",
133
+ "--disable-warnings",
134
+ ]
135
+
136
+ [dependency-groups]
137
+ dev = [
138
+ "pytest>=9.0.2",
139
+ "pyright>=1.1.408",
140
+ "ruff>=0.15.6",
141
+ ]
@@ -0,0 +1,5 @@
1
+ """Minitest CLI – command-line interface for the Minitest testing platform."""
2
+
3
+ from importlib.metadata import version
4
+
5
+ __version__ = version("minitest-cli")
File without changes
@@ -0,0 +1,69 @@
1
+ """Async HTTP client with automatic auth and channel headers."""
2
+
3
+ from typing import Any
4
+
5
+ import httpx
6
+
7
+ from minitest_cli.core.auth import load_token
8
+ from minitest_cli.core.config import Settings
9
+
10
+ CHANNEL_HEADER = "X-Minitest-Channel"
11
+ CHANNEL_VALUE = "cli"
12
+ DEFAULT_TIMEOUT = 30.0
13
+
14
+
15
+ class ApiClient:
16
+ """Wraps httpx.AsyncClient with auto-injected auth and channel headers.
17
+
18
+ Usage::
19
+
20
+ async with ApiClient(settings) as client:
21
+ response = await client.get("/api/v1/apps")
22
+ """
23
+
24
+ def __init__(self, settings: Settings) -> None:
25
+ self._settings = settings
26
+ self._client: httpx.AsyncClient | None = None
27
+
28
+ async def __aenter__(self) -> "ApiClient":
29
+ token = load_token(self._settings)
30
+ self._client = httpx.AsyncClient(
31
+ base_url=self._settings.api_url,
32
+ headers={
33
+ "Authorization": f"Bearer {token}",
34
+ CHANNEL_HEADER: CHANNEL_VALUE,
35
+ },
36
+ timeout=DEFAULT_TIMEOUT,
37
+ )
38
+ return self
39
+
40
+ async def __aexit__(
41
+ self,
42
+ exc_type: type[BaseException] | None,
43
+ exc_val: BaseException | None,
44
+ exc_tb: object,
45
+ ) -> None:
46
+ if self._client:
47
+ await self._client.aclose()
48
+
49
+ def _ensure_client(self) -> httpx.AsyncClient:
50
+ if self._client is None:
51
+ msg = "ApiClient must be used as an async context manager"
52
+ raise RuntimeError(msg)
53
+ return self._client
54
+
55
+ async def get(self, path: str, **kwargs: Any) -> httpx.Response:
56
+ """Send a GET request."""
57
+ return await self._ensure_client().get(path, **kwargs)
58
+
59
+ async def post(self, path: str, **kwargs: Any) -> httpx.Response:
60
+ """Send a POST request."""
61
+ return await self._ensure_client().post(path, **kwargs)
62
+
63
+ async def patch(self, path: str, **kwargs: Any) -> httpx.Response:
64
+ """Send a PATCH request."""
65
+ return await self._ensure_client().patch(path, **kwargs)
66
+
67
+ async def delete(self, path: str, **kwargs: Any) -> httpx.Response:
68
+ """Send a DELETE request."""
69
+ return await self._ensure_client().delete(path, **kwargs)
File without changes
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>minitest-cli — Authentication</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Archivo:wght@400&display=swap" rel="stylesheet">
10
+ <style>
11
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
12
+ body {
13
+ font-family: 'Archivo', sans-serif;
14
+ font-weight: 400;
15
+ background: #fafafa;
16
+ color: #1a1a1a;
17
+ min-height: 100vh;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ }
22
+ .card {
23
+ background: #fff;
24
+ border-radius: 20px;
25
+ box-shadow: 0 8px 40px rgba(0, 0, 0, 0.08);
26
+ padding: 56px 64px;
27
+ max-width: 540px;
28
+ width: 100%;
29
+ display: flex;
30
+ flex-direction: column;
31
+ align-items: center;
32
+ gap: 32px;
33
+ }
34
+ .logo {
35
+ width: 72px;
36
+ height: 72px;
37
+ border-radius: 14px;
38
+ }
39
+ .message {
40
+ font-size: 24px;
41
+ text-align: center;
42
+ line-height: 1.5;
43
+ }
44
+ .message.success { color: #1a1a1a; }
45
+ .message.error { color: #d32f2f; }
46
+ .divider {
47
+ width: 100%;
48
+ height: 1px;
49
+ background: #e5e5e5;
50
+ }
51
+ .hint {
52
+ font-size: 14px;
53
+ color: #888;
54
+ text-align: center;
55
+ }
56
+ </style>
57
+ </head>
58
+ <body>
59
+ <div class="card">
60
+ <img class="logo" src="data:image/png;base64,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" alt="minitest-cli">
61
+ <p class="message {{status_class}}">{{message}}</p>
62
+ <div class="divider"></div>
63
+ <p class="hint">You can close this tab and return to your terminal.</p>
64
+ </div>
65
+ </body>
66
+ </html>
@@ -0,0 +1,28 @@
1
+ """App management commands: list, show."""
2
+
3
+ import typer
4
+
5
+ from minitest_cli.core.auth import require_auth
6
+ from minitest_cli.core.config import Settings
7
+
8
+ app = typer.Typer(name="apps", help="App management.")
9
+
10
+
11
+ def _get_settings() -> Settings:
12
+ return typer.Context.settings # type: ignore[attr-defined]
13
+
14
+
15
+ @app.command(name="list")
16
+ def list_apps() -> None:
17
+ """List all apps."""
18
+ require_auth(_get_settings())
19
+ typer.echo("apps list – not yet implemented", err=True)
20
+ raise typer.Exit(code=1)
21
+
22
+
23
+ @app.command()
24
+ def show() -> None:
25
+ """Show details for a specific app."""
26
+ require_auth(_get_settings())
27
+ typer.echo("apps show – not yet implemented", err=True)
28
+ raise typer.Exit(code=1)