checkdk-cli 0.2.5__tar.gz → 0.2.6__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.
Files changed (24) hide show
  1. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/PKG-INFO +21 -45
  2. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/README.md +20 -44
  3. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdk_cli.egg-info/PKG-INFO +21 -45
  4. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/__init__.py +1 -1
  5. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/client.py +24 -2
  6. checkdk_cli-0.2.6/checkdkcli/commands/auth.py +181 -0
  7. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/commands/init.py +12 -3
  8. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/commands/monitor.py +6 -7
  9. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/pyproject.toml +1 -1
  10. checkdk_cli-0.2.5/checkdkcli/commands/auth.py +0 -110
  11. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdk_cli.egg-info/SOURCES.txt +0 -0
  12. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdk_cli.egg-info/dependency_links.txt +0 -0
  13. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdk_cli.egg-info/entry_points.txt +0 -0
  14. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdk_cli.egg-info/requires.txt +0 -0
  15. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdk_cli.egg-info/top_level.txt +0 -0
  16. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/commands/__init__.py +0 -0
  17. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/commands/chaos.py +0 -0
  18. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/commands/docker.py +0 -0
  19. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/commands/kubectl.py +0 -0
  20. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/commands/playground.py +0 -0
  21. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/commands/predict.py +0 -0
  22. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/display.py +0 -0
  23. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/checkdkcli/main.py +0 -0
  24. {checkdk_cli-0.2.5 → checkdk_cli-0.2.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: checkdk-cli
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: checkDK CLI – AI-powered Docker/Kubernetes issue detector and pod failure predictor
5
5
  Author-email: checkDK Team <team@checkdk.app>
6
6
  License: MIT
@@ -50,29 +50,6 @@ dependencies — it is a thin HTTP/WebSocket client with a rich terminal UI.
50
50
 
51
51
  ## Install
52
52
 
53
- ### npm (no Python required)
54
-
55
- The easiest way to install for JavaScript / Node.js users.
56
- Pre-compiled standalone binaries are distributed per-platform — nothing else needs to be installed.
57
-
58
- ```bash
59
- npm install -g @checkdk/cli
60
- ```
61
-
62
- Supported platforms:
63
-
64
- | Platform | Package |
65
- | --------------------------- | --------------------------- |
66
- | Linux x64 | `@checkdk/cli-linux-x64` |
67
- | Linux arm64 | `@checkdk/cli-linux-arm64` |
68
- | macOS x64 (Intel) | `@checkdk/cli-darwin-x64` |
69
- | macOS arm64 (Apple Silicon) | `@checkdk/cli-darwin-arm64` |
70
- | Windows x64 | `@checkdk/cli-win32-x64` |
71
-
72
- After install, `checkdk` is available on your PATH immediately.
73
-
74
- ### pip / pipx (Python required)
75
-
76
53
  ```bash
77
54
  # Recommended — isolated install, checkdk on PATH globally
78
55
  pipx install checkdk-cli
@@ -81,8 +58,6 @@ pipx install checkdk-cli
81
58
  pip install checkdk-cli
82
59
  ```
83
60
 
84
- Requires Python 3.10 or later.
85
-
86
61
  The `checkdk` command is available immediately after install.
87
62
  No configuration required — the CLI talks to `https://checkdk.app/api` by default.
88
63
 
@@ -132,21 +107,21 @@ checkdk predict --cpu 93 --memory 91 --restarts 3 \
132
107
  checkdk predict --cpu 85 --memory 70 --json # CI/scripting output
133
108
  ```
134
109
 
135
- | Option | Default | Description |
136
- | ------------------ | -------- | --------------------------------- |
137
- | `--cpu` | required | CPU usage % |
138
- | `--memory` | required | Memory usage % |
139
- | `--disk` | 50 | Disk usage % |
140
- | `--latency` | 10 | Network latency ms |
141
- | `--restarts` | 0 | Container restart count |
142
- | `--probe-failures` | 0 | Liveness/readiness probe failures |
143
- | `--cpu-pressure` | 0 | Node CPU pressure (0 or 1) |
144
- | `--mem-pressure` | 0 | Node memory pressure (0 or 1) |
145
- | `--age` | 60 | Pod age in minutes |
146
- | `--service` | — | Service/pod name (label only) |
147
- | `--platform` | docker | `docker` or `kubernetes` |
148
- | `--no-ai` | — | Skip LLM, return ML result only |
149
- | `--json` | — | Raw JSON output for scripting |
110
+ | Option | Default | Description |
111
+ |---|---|---|
112
+ | `--cpu` | required | CPU usage % |
113
+ | `--memory` | required | Memory usage % |
114
+ | `--disk` | 50 | Disk usage % |
115
+ | `--latency` | 10 | Network latency ms |
116
+ | `--restarts` | 0 | Container restart count |
117
+ | `--probe-failures` | 0 | Liveness/readiness probe failures |
118
+ | `--cpu-pressure` | 0 | Node CPU pressure (0 or 1) |
119
+ | `--mem-pressure` | 0 | Node memory pressure (0 or 1) |
120
+ | `--age` | 60 | Pod age in minutes |
121
+ | `--service` | — | Service/pod name (label only) |
122
+ | `--platform` | docker | `docker` or `kubernetes` |
123
+ | `--no-ai` | — | Skip LLM, return ML result only |
124
+ | `--json` | — | Raw JSON output for scripting |
150
125
 
151
126
  ### Monitor (real-time)
152
127
 
@@ -177,10 +152,10 @@ Experiments: `cpu`, `memory`, `disk`, `network`, `pod-kill` (k8s only).
177
152
 
178
153
  ## Environment variables
179
154
 
180
- | Variable | Default | Description |
181
- | ----------------- | ------------------------- | -------------------------------------------- |
182
- | `CHECKDK_API_URL` | `https://checkdk.app/api` | Backend API base URL |
183
- | `CHECKDK_TOKEN` | — | JWT auth token (set by `checkdk auth login`) |
155
+ | Variable | Default | Description |
156
+ |---|---|---|
157
+ | `CHECKDK_API_URL` | `https://checkdk.app/api` | Backend API base URL |
158
+ | `CHECKDK_TOKEN` | — | JWT auth token (set by `checkdk auth login`) |
184
159
 
185
160
  The CLI auto-loads `~/.checkdk/.env` and `./.env` on startup.
186
161
 
@@ -208,3 +183,4 @@ pytest
208
183
  # Lint
209
184
  ruff check .
210
185
  ```
186
+
@@ -12,29 +12,6 @@ dependencies — it is a thin HTTP/WebSocket client with a rich terminal UI.
12
12
 
13
13
  ## Install
14
14
 
15
- ### npm (no Python required)
16
-
17
- The easiest way to install for JavaScript / Node.js users.
18
- Pre-compiled standalone binaries are distributed per-platform — nothing else needs to be installed.
19
-
20
- ```bash
21
- npm install -g @checkdk/cli
22
- ```
23
-
24
- Supported platforms:
25
-
26
- | Platform | Package |
27
- | --------------------------- | --------------------------- |
28
- | Linux x64 | `@checkdk/cli-linux-x64` |
29
- | Linux arm64 | `@checkdk/cli-linux-arm64` |
30
- | macOS x64 (Intel) | `@checkdk/cli-darwin-x64` |
31
- | macOS arm64 (Apple Silicon) | `@checkdk/cli-darwin-arm64` |
32
- | Windows x64 | `@checkdk/cli-win32-x64` |
33
-
34
- After install, `checkdk` is available on your PATH immediately.
35
-
36
- ### pip / pipx (Python required)
37
-
38
15
  ```bash
39
16
  # Recommended — isolated install, checkdk on PATH globally
40
17
  pipx install checkdk-cli
@@ -43,8 +20,6 @@ pipx install checkdk-cli
43
20
  pip install checkdk-cli
44
21
  ```
45
22
 
46
- Requires Python 3.10 or later.
47
-
48
23
  The `checkdk` command is available immediately after install.
49
24
  No configuration required — the CLI talks to `https://checkdk.app/api` by default.
50
25
 
@@ -94,21 +69,21 @@ checkdk predict --cpu 93 --memory 91 --restarts 3 \
94
69
  checkdk predict --cpu 85 --memory 70 --json # CI/scripting output
95
70
  ```
96
71
 
97
- | Option | Default | Description |
98
- | ------------------ | -------- | --------------------------------- |
99
- | `--cpu` | required | CPU usage % |
100
- | `--memory` | required | Memory usage % |
101
- | `--disk` | 50 | Disk usage % |
102
- | `--latency` | 10 | Network latency ms |
103
- | `--restarts` | 0 | Container restart count |
104
- | `--probe-failures` | 0 | Liveness/readiness probe failures |
105
- | `--cpu-pressure` | 0 | Node CPU pressure (0 or 1) |
106
- | `--mem-pressure` | 0 | Node memory pressure (0 or 1) |
107
- | `--age` | 60 | Pod age in minutes |
108
- | `--service` | — | Service/pod name (label only) |
109
- | `--platform` | docker | `docker` or `kubernetes` |
110
- | `--no-ai` | — | Skip LLM, return ML result only |
111
- | `--json` | — | Raw JSON output for scripting |
72
+ | Option | Default | Description |
73
+ |---|---|---|
74
+ | `--cpu` | required | CPU usage % |
75
+ | `--memory` | required | Memory usage % |
76
+ | `--disk` | 50 | Disk usage % |
77
+ | `--latency` | 10 | Network latency ms |
78
+ | `--restarts` | 0 | Container restart count |
79
+ | `--probe-failures` | 0 | Liveness/readiness probe failures |
80
+ | `--cpu-pressure` | 0 | Node CPU pressure (0 or 1) |
81
+ | `--mem-pressure` | 0 | Node memory pressure (0 or 1) |
82
+ | `--age` | 60 | Pod age in minutes |
83
+ | `--service` | — | Service/pod name (label only) |
84
+ | `--platform` | docker | `docker` or `kubernetes` |
85
+ | `--no-ai` | — | Skip LLM, return ML result only |
86
+ | `--json` | — | Raw JSON output for scripting |
112
87
 
113
88
  ### Monitor (real-time)
114
89
 
@@ -139,10 +114,10 @@ Experiments: `cpu`, `memory`, `disk`, `network`, `pod-kill` (k8s only).
139
114
 
140
115
  ## Environment variables
141
116
 
142
- | Variable | Default | Description |
143
- | ----------------- | ------------------------- | -------------------------------------------- |
144
- | `CHECKDK_API_URL` | `https://checkdk.app/api` | Backend API base URL |
145
- | `CHECKDK_TOKEN` | — | JWT auth token (set by `checkdk auth login`) |
117
+ | Variable | Default | Description |
118
+ |---|---|---|
119
+ | `CHECKDK_API_URL` | `https://checkdk.app/api` | Backend API base URL |
120
+ | `CHECKDK_TOKEN` | — | JWT auth token (set by `checkdk auth login`) |
146
121
 
147
122
  The CLI auto-loads `~/.checkdk/.env` and `./.env` on startup.
148
123
 
@@ -170,3 +145,4 @@ pytest
170
145
  # Lint
171
146
  ruff check .
172
147
  ```
148
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: checkdk-cli
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: checkDK CLI – AI-powered Docker/Kubernetes issue detector and pod failure predictor
5
5
  Author-email: checkDK Team <team@checkdk.app>
6
6
  License: MIT
@@ -50,29 +50,6 @@ dependencies — it is a thin HTTP/WebSocket client with a rich terminal UI.
50
50
 
51
51
  ## Install
52
52
 
53
- ### npm (no Python required)
54
-
55
- The easiest way to install for JavaScript / Node.js users.
56
- Pre-compiled standalone binaries are distributed per-platform — nothing else needs to be installed.
57
-
58
- ```bash
59
- npm install -g @checkdk/cli
60
- ```
61
-
62
- Supported platforms:
63
-
64
- | Platform | Package |
65
- | --------------------------- | --------------------------- |
66
- | Linux x64 | `@checkdk/cli-linux-x64` |
67
- | Linux arm64 | `@checkdk/cli-linux-arm64` |
68
- | macOS x64 (Intel) | `@checkdk/cli-darwin-x64` |
69
- | macOS arm64 (Apple Silicon) | `@checkdk/cli-darwin-arm64` |
70
- | Windows x64 | `@checkdk/cli-win32-x64` |
71
-
72
- After install, `checkdk` is available on your PATH immediately.
73
-
74
- ### pip / pipx (Python required)
75
-
76
53
  ```bash
77
54
  # Recommended — isolated install, checkdk on PATH globally
78
55
  pipx install checkdk-cli
@@ -81,8 +58,6 @@ pipx install checkdk-cli
81
58
  pip install checkdk-cli
82
59
  ```
83
60
 
84
- Requires Python 3.10 or later.
85
-
86
61
  The `checkdk` command is available immediately after install.
87
62
  No configuration required — the CLI talks to `https://checkdk.app/api` by default.
88
63
 
@@ -132,21 +107,21 @@ checkdk predict --cpu 93 --memory 91 --restarts 3 \
132
107
  checkdk predict --cpu 85 --memory 70 --json # CI/scripting output
133
108
  ```
134
109
 
135
- | Option | Default | Description |
136
- | ------------------ | -------- | --------------------------------- |
137
- | `--cpu` | required | CPU usage % |
138
- | `--memory` | required | Memory usage % |
139
- | `--disk` | 50 | Disk usage % |
140
- | `--latency` | 10 | Network latency ms |
141
- | `--restarts` | 0 | Container restart count |
142
- | `--probe-failures` | 0 | Liveness/readiness probe failures |
143
- | `--cpu-pressure` | 0 | Node CPU pressure (0 or 1) |
144
- | `--mem-pressure` | 0 | Node memory pressure (0 or 1) |
145
- | `--age` | 60 | Pod age in minutes |
146
- | `--service` | — | Service/pod name (label only) |
147
- | `--platform` | docker | `docker` or `kubernetes` |
148
- | `--no-ai` | — | Skip LLM, return ML result only |
149
- | `--json` | — | Raw JSON output for scripting |
110
+ | Option | Default | Description |
111
+ |---|---|---|
112
+ | `--cpu` | required | CPU usage % |
113
+ | `--memory` | required | Memory usage % |
114
+ | `--disk` | 50 | Disk usage % |
115
+ | `--latency` | 10 | Network latency ms |
116
+ | `--restarts` | 0 | Container restart count |
117
+ | `--probe-failures` | 0 | Liveness/readiness probe failures |
118
+ | `--cpu-pressure` | 0 | Node CPU pressure (0 or 1) |
119
+ | `--mem-pressure` | 0 | Node memory pressure (0 or 1) |
120
+ | `--age` | 60 | Pod age in minutes |
121
+ | `--service` | — | Service/pod name (label only) |
122
+ | `--platform` | docker | `docker` or `kubernetes` |
123
+ | `--no-ai` | — | Skip LLM, return ML result only |
124
+ | `--json` | — | Raw JSON output for scripting |
150
125
 
151
126
  ### Monitor (real-time)
152
127
 
@@ -177,10 +152,10 @@ Experiments: `cpu`, `memory`, `disk`, `network`, `pod-kill` (k8s only).
177
152
 
178
153
  ## Environment variables
179
154
 
180
- | Variable | Default | Description |
181
- | ----------------- | ------------------------- | -------------------------------------------- |
182
- | `CHECKDK_API_URL` | `https://checkdk.app/api` | Backend API base URL |
183
- | `CHECKDK_TOKEN` | — | JWT auth token (set by `checkdk auth login`) |
155
+ | Variable | Default | Description |
156
+ |---|---|---|
157
+ | `CHECKDK_API_URL` | `https://checkdk.app/api` | Backend API base URL |
158
+ | `CHECKDK_TOKEN` | — | JWT auth token (set by `checkdk auth login`) |
184
159
 
185
160
  The CLI auto-loads `~/.checkdk/.env` and `./.env` on startup.
186
161
 
@@ -208,3 +183,4 @@ pytest
208
183
  # Lint
209
184
  ruff check .
210
185
  ```
186
+
@@ -1,3 +1,3 @@
1
1
  """checkDK CLI package."""
2
2
 
3
- __version__ = "0.2.5"
3
+ __version__ = "0.2.6"
@@ -21,13 +21,35 @@ def get_api_url() -> str:
21
21
  Priority:
22
22
  1. $CHECKDK_API_URL environment variable
23
23
  2. ~/.checkdk/.env (loaded by python-dotenv at startup)
24
- 3. Fallback to https://checkdk.app/api (production) — override with
25
- CHECKDK_API_URL=http://localhost:8000 for local dev
24
+ 3. Fallback to https://checkdk.app/api (production)
26
25
  """
27
26
  url = os.getenv("CHECKDK_API_URL", "https://checkdk.app/api").strip().rstrip("/")
28
27
  return url
29
28
 
30
29
 
30
+ def get_ws_url() -> str:
31
+ """Return the WebSocket base URL for real-time monitoring.
32
+
33
+ CloudFront does not support WebSocket upgrades on the free plan, so the
34
+ WebSocket connection goes directly to App Runner instead of via checkdk.app.
35
+
36
+ Priority:
37
+ 1. $CHECKDK_WS_URL environment variable
38
+ 2. ~/.checkdk/.env (CHECKDK_WS_URL=...)
39
+ 3. Fallback to the App Runner service URL (wss://)
40
+ """
41
+ stored = os.getenv("CHECKDK_WS_URL")
42
+ if stored:
43
+ return stored.strip().rstrip("/")
44
+ env_file = Path.home() / ".checkdk" / ".env"
45
+ if env_file.exists():
46
+ for line in env_file.read_text().splitlines():
47
+ if line.startswith("CHECKDK_WS_URL="):
48
+ return line.split("=", 1)[1].strip().strip('"').strip("'")
49
+ # Direct App Runner URL — bypasses CloudFront which blocks WebSocket
50
+ return "wss://m7fijvmhiq.us-east-1.awsapprunner.com"
51
+
52
+
31
53
  def get_stored_token() -> Optional[str]:
32
54
  """Read a stored JWT from ~/.checkdk/.env, if present."""
33
55
  token = os.getenv("CHECKDK_TOKEN")
@@ -0,0 +1,181 @@
1
+ """checkdk auth commands - login, logout, whoami."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import socket
7
+ import sys
8
+ import threading
9
+ import time
10
+ import urllib.parse
11
+ import webbrowser
12
+ from http.server import BaseHTTPRequestHandler, HTTPServer
13
+ from pathlib import Path
14
+
15
+ import click
16
+ from rich.console import Console
17
+ from rich.panel import Panel
18
+ from rich.table import Table
19
+
20
+ from ..client import get_api_url, get_current_user, validate_token
21
+
22
+ _console = Console()
23
+ _ENV_FILE = Path.home() / ".checkdk" / ".env"
24
+
25
+
26
+ def _save_token(token: str) -> None:
27
+ _ENV_FILE.parent.mkdir(parents=True, exist_ok=True)
28
+ lines = _ENV_FILE.read_text().splitlines() if _ENV_FILE.exists() else []
29
+ lines = [l for l in lines if not l.startswith("CHECKDK_TOKEN=")]
30
+ lines.append(f"CHECKDK_TOKEN={token}")
31
+ _ENV_FILE.write_text("\n".join(lines) + "\n")
32
+
33
+
34
+ def _remove_token() -> None:
35
+ if not _ENV_FILE.exists():
36
+ return
37
+ lines = [l for l in _ENV_FILE.read_text().splitlines()
38
+ if not l.startswith("CHECKDK_TOKEN=")]
39
+ _ENV_FILE.write_text("\n".join(lines) + "\n")
40
+
41
+
42
+ def _find_free_port() -> int:
43
+ """Return an available localhost port."""
44
+ with socket.socket() as s:
45
+ s.bind(("127.0.0.1", 0))
46
+ return s.getsockname()[1]
47
+
48
+
49
+ def _wait_for_token(port: int, timeout: int = 120) -> "str | None":
50
+ """Start a temporary HTTP server on localhost and wait for the OAuth callback."""
51
+ received: dict = {"token": None}
52
+ server_ready = threading.Event()
53
+
54
+ class _Handler(BaseHTTPRequestHandler):
55
+ def do_GET(self) -> None:
56
+ parsed = urllib.parse.urlparse(self.path)
57
+ params = urllib.parse.parse_qs(parsed.query)
58
+ token = (params.get("token") or [None])[0]
59
+ received["token"] = token
60
+
61
+ if token:
62
+ body = (
63
+ b"<html><body style=\"font-family:sans-serif;text-align:center;"
64
+ b"margin-top:10vh;background:#0f172a;color:#e2e8f0\">"
65
+ b"<h2 style=\"color:#818cf8\">checkDK CLI</h2>"
66
+ b"<p style=\"font-size:1.2rem\">You\'re logged in!"
67
+ b" You can close this tab.</p></body></html>"
68
+ )
69
+ else:
70
+ body = b"<html><body>Authentication failed. Please try again.</body></html>"
71
+
72
+ self.send_response(200)
73
+ self.send_header("Content-Type", "text/html; charset=utf-8")
74
+ self.send_header("Content-Length", str(len(body)))
75
+ self.end_headers()
76
+ self.wfile.write(body)
77
+
78
+ def log_message(self, *_) -> None:
79
+ pass # silence access logs
80
+
81
+ httpd = HTTPServer(("127.0.0.1", port), _Handler)
82
+ httpd.timeout = 1 # poll interval
83
+
84
+ def _serve() -> None:
85
+ server_ready.set()
86
+ deadline = time.time() + timeout
87
+ while received["token"] is None and time.time() < deadline:
88
+ httpd.handle_request()
89
+ httpd.server_close()
90
+
91
+ t = threading.Thread(target=_serve, daemon=True)
92
+ t.start()
93
+ server_ready.wait()
94
+ t.join(timeout + 2)
95
+ return received["token"]
96
+
97
+
98
+ @click.group("auth")
99
+ def auth_cmd() -> None:
100
+ """Authentication - log in, log out, or check who you are."""
101
+
102
+
103
+ @auth_cmd.command("login")
104
+ def login_cmd() -> None:
105
+ """Log in to checkDK via GitHub or Google OAuth.
106
+
107
+ Starts a local callback server, opens the sign-in page in your browser,
108
+ and receives the token automatically - no copy-pasting required.
109
+ """
110
+ port = _find_free_port()
111
+ callback_url = f"http://127.0.0.1:{port}/callback"
112
+
113
+ api = get_api_url()
114
+ base = api[: api.rindex("/api")] if "/api" in api else "https://checkdk.app"
115
+ encoded_cb = urllib.parse.quote(callback_url, safe="")
116
+ login_url = f"{base}/login?cli_callback={encoded_cb}"
117
+
118
+ _console.print("\n[bold]Opening browser for sign-in...[/]")
119
+ _console.print(
120
+ " [dim]If the browser did not open, visit:[/]\n"
121
+ f" [cyan]{login_url}[/]\n"
122
+ )
123
+
124
+ try:
125
+ webbrowser.open(login_url)
126
+ except Exception:
127
+ _console.print(f"[yellow]Open this URL in your browser:[/] [cyan]{login_url}[/]\n")
128
+
129
+ with _console.status("[bold cyan]Waiting for authentication (2-min timeout)...[/]"):
130
+ token = _wait_for_token(port, timeout=120)
131
+
132
+ if not token:
133
+ _console.print("[bold red]Login timed out or was cancelled.[/]")
134
+ sys.exit(1)
135
+
136
+ try:
137
+ user = validate_token(token)
138
+ except Exception as exc:
139
+ _console.print(f"[bold red]Token validation failed:[/] {exc}")
140
+ sys.exit(1)
141
+
142
+ _save_token(token)
143
+ os.environ["CHECKDK_TOKEN"] = token
144
+
145
+ _console.print(Panel(
146
+ f"[bold green]Logged in successfully![/]\n\n"
147
+ f" Name: {user.get('name', '?')}\n"
148
+ f" Email: {user.get('email', '?')}\n"
149
+ f" Provider: {user.get('provider', '?')}\n\n"
150
+ f"[dim]Token saved to {_ENV_FILE}[/]",
151
+ border_style="green",
152
+ ))
153
+
154
+
155
+ @auth_cmd.command("logout")
156
+ def logout_cmd() -> None:
157
+ """Remove the stored JWT token."""
158
+ _remove_token()
159
+ if "CHECKDK_TOKEN" in os.environ:
160
+ del os.environ["CHECKDK_TOKEN"]
161
+ _console.print("[bold green]Logged out.[/] Token removed from local config.")
162
+
163
+
164
+ @auth_cmd.command("whoami")
165
+ def whoami_cmd() -> None:
166
+ """Show the currently logged-in user."""
167
+ try:
168
+ user = get_current_user()
169
+ except Exception as exc:
170
+ _console.print(f"[bold red]Not logged in or API unreachable:[/] {exc}")
171
+ _console.print("[dim]Run [bold]checkdk auth login[/] first.[/]")
172
+ sys.exit(1)
173
+
174
+ t = Table.grid(padding=(0, 2))
175
+ t.add_column(style="bold cyan")
176
+ t.add_column()
177
+ t.add_row("Name:", user.get("name", "?"))
178
+ t.add_row("Email:", user.get("email", "?"))
179
+ t.add_row("Provider:", user.get("provider", "?"))
180
+ t.add_row("User ID:", user.get("userId", "?"))
181
+ _console.print(Panel(t, title="Current User", border_style="cyan"))
@@ -16,7 +16,7 @@ def init_cmd() -> None:
16
16
  """Configure checkDK CLI (set API URL, API keys, etc.)."""
17
17
  console.print("[bold]checkDK CLI configuration[/]\n")
18
18
 
19
- default_url = os.getenv("CHECKDK_API_URL", "http://localhost:8000")
19
+ default_url = os.getenv("CHECKDK_API_URL", "https://checkdk.app/api")
20
20
  api_url = console.input(
21
21
  f" Backend API URL [[dim]{default_url}[/]]: "
22
22
  ).strip() or default_url
@@ -33,10 +33,19 @@ def init_cmd() -> None:
33
33
  ]
34
34
 
35
35
  existing.append(f"CHECKDK_API_URL={api_url}")
36
+
37
+ default_ws = os.getenv("CHECKDK_WS_URL", "wss://m7fijvmhiq.us-east-1.awsapprunner.com")
38
+ ws_url = console.input(
39
+ f" WebSocket URL (for monitor) [[dim]{default_ws}[/]]: "
40
+ ).strip() or default_ws
41
+ existing = [l for l in existing if not l.startswith("CHECKDK_WS_URL=")]
42
+ existing.append(f"CHECKDK_WS_URL={ws_url}")
43
+
36
44
  env_path.write_text("\n".join(existing) + "\n")
37
45
 
38
46
  console.print(
39
47
  f"\n[bold green]✓ Saved to:[/] {env_path}\n"
40
- f" [dim]CHECKDK_API_URL={api_url}[/]\n\n"
41
- "Tip: You can also set [bold cyan]CHECKDK_API_URL[/] as a shell environment variable."
48
+ f" [dim]CHECKDK_API_URL={api_url}[/]\n"
49
+ f" [dim]CHECKDK_WS_URL={ws_url}[/]\n\n"
50
+ "Tip: You can also set these as shell environment variables."
42
51
  )
@@ -14,6 +14,8 @@ from rich.live import Live
14
14
  from rich.table import Table
15
15
  from rich.text import Text
16
16
 
17
+ from ..client import get_ws_url
18
+
17
19
  _console = Console()
18
20
 
19
21
 
@@ -95,9 +97,7 @@ def monitor_cmd() -> None:
95
97
  help="Stop after N seconds (0 = run until Ctrl-C)")
96
98
  @click.option("--interval", default=5, show_default=True, type=int,
97
99
  help="Polling interval in seconds")
98
- @click.option("--api-url", envvar="CHECKDK_API_URL", default="https://checkdk.app/api",
99
- help="Backend base URL")
100
- def monitor_docker(container: str, duration: int, interval: int, api_url: str) -> None:
100
+ def monitor_docker(container: str, duration: int, interval: int) -> None:
101
101
  """Stream live Docker container metrics and predict failure risk.
102
102
 
103
103
  \b
@@ -114,7 +114,7 @@ def monitor_docker(container: str, duration: int, interval: int, api_url: str) -
114
114
 
115
115
  import websocket as ws_lib
116
116
 
117
- ws_url = api_url.replace("http://", "ws://").replace("https://", "wss://") + "/ws/monitor"
117
+ ws_url = get_ws_url() + "/ws/monitor"
118
118
  history: list[dict] = []
119
119
  start = time.time()
120
120
 
@@ -168,8 +168,7 @@ def monitor_docker(container: str, duration: int, interval: int, api_url: str) -
168
168
  @click.option("--namespace", "-n", default="default", show_default=True)
169
169
  @click.option("--duration", default=0, type=int, help="Stop after N seconds (0 = Ctrl-C)")
170
170
  @click.option("--interval", default=5, show_default=True, type=int)
171
- @click.option("--api-url", envvar="CHECKDK_API_URL", default="https://checkdk.app/api")
172
- def monitor_k8s(pod: str, namespace: str, duration: int, interval: int, api_url: str) -> None:
171
+ def monitor_k8s(pod: str, namespace: str, duration: int, interval: int) -> None:
173
172
  """Stream live Kubernetes pod metrics and predict failure risk.
174
173
 
175
174
  \b
@@ -185,7 +184,7 @@ def monitor_k8s(pod: str, namespace: str, duration: int, interval: int, api_url:
185
184
 
186
185
  import websocket as ws_lib
187
186
 
188
- ws_url = api_url.replace("http://", "ws://").replace("https://", "wss://") + "/ws/monitor"
187
+ ws_url = get_ws_url() + "/ws/monitor"
189
188
  history: list[dict] = []
190
189
  start = time.time()
191
190
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "checkdk-cli"
7
- version = "0.2.5"
7
+ version = "0.2.6"
8
8
  description = "checkDK CLI – AI-powered Docker/Kubernetes issue detector and pod failure predictor"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,110 +0,0 @@
1
- """checkdk auth commands - login, logout, whoami."""
2
-
3
- from __future__ import annotations
4
-
5
- import os
6
- import sys
7
- import webbrowser
8
- from pathlib import Path
9
-
10
- import click
11
- from rich.console import Console
12
- from rich.panel import Panel
13
- from rich.table import Table
14
-
15
- from ..client import get_api_url, get_current_user, validate_token
16
-
17
- _console = Console()
18
- _ENV_FILE = Path.home() / ".checkdk" / ".env"
19
-
20
-
21
- def _save_token(token: str) -> None:
22
- _ENV_FILE.parent.mkdir(parents=True, exist_ok=True)
23
- lines = _ENV_FILE.read_text().splitlines() if _ENV_FILE.exists() else []
24
- lines = [l for l in lines if not l.startswith("CHECKDK_TOKEN=")]
25
- lines.append(f"CHECKDK_TOKEN={token}")
26
- _ENV_FILE.write_text("\n".join(lines) + "\n")
27
-
28
-
29
- def _remove_token() -> None:
30
- if not _ENV_FILE.exists():
31
- return
32
- lines = [l for l in _ENV_FILE.read_text().splitlines()
33
- if not l.startswith("CHECKDK_TOKEN=")]
34
- _ENV_FILE.write_text("\n".join(lines) + "\n")
35
-
36
-
37
- @click.group("auth")
38
- def auth_cmd() -> None:
39
- """Authentication - log in, log out, or check who you are."""
40
-
41
-
42
- @auth_cmd.command("login")
43
- def login_cmd() -> None:
44
- """Log in to checkDK via GitHub or Google OAuth.
45
-
46
- Opens the sign-in page in your browser, then prompts you to paste
47
- the JWT token shown after a successful login.
48
- """
49
- login_url = f"{get_api_url().replace('/api', '')}/login" if "/api" in get_api_url() else "https://checkdk.app/login"
50
- _console.print(f"\n[bold]Opening sign-in page:[/] [cyan]{login_url}[/]")
51
- _console.print("[dim]Sign in with GitHub or Google, then copy the token from the page.[/]\n")
52
-
53
- try:
54
- webbrowser.open(login_url)
55
- except Exception:
56
- _console.print("[yellow]Could not open browser automatically.[/]")
57
- _console.print(f"Please visit: [cyan]{login_url}[/]\n")
58
-
59
- token = _console.input("[bold]Paste your JWT token here:[/] ").strip()
60
- if not token:
61
- _console.print("[red]No token provided. Login cancelled.[/]")
62
- sys.exit(1)
63
-
64
- try:
65
- user = validate_token(token)
66
- except Exception as exc:
67
- _console.print(f"[bold red]Token validation failed:[/] {exc}")
68
- _console.print("[yellow]Make sure CHECKDK_API_URL points to a running backend.[/]")
69
- sys.exit(1)
70
-
71
- _save_token(token)
72
- os.environ["CHECKDK_TOKEN"] = token
73
-
74
- _console.print(Panel(
75
- f"[bold green]Logged in successfully![/]\n\n"
76
- f" Name: {user.get('name', '?')}\n"
77
- f" Email: {user.get('email', '?')}\n"
78
- f" Provider: {user.get('provider', '?')}\n\n"
79
- f"[dim]Token saved to {_ENV_FILE}[/]",
80
- border_style="green",
81
- ))
82
-
83
-
84
- @auth_cmd.command("logout")
85
- def logout_cmd() -> None:
86
- """Remove the stored JWT token."""
87
- _remove_token()
88
- if "CHECKDK_TOKEN" in os.environ:
89
- del os.environ["CHECKDK_TOKEN"]
90
- _console.print("[bold green]Logged out.[/] Token removed from local config.")
91
-
92
-
93
- @auth_cmd.command("whoami")
94
- def whoami_cmd() -> None:
95
- """Show the currently logged-in user."""
96
- try:
97
- user = get_current_user()
98
- except Exception as exc:
99
- _console.print(f"[bold red]Not logged in or API unreachable:[/] {exc}")
100
- _console.print("[dim]Run [bold]checkdk auth login[/] first.[/]")
101
- sys.exit(1)
102
-
103
- t = Table.grid(padding=(0, 2))
104
- t.add_column(style="bold cyan")
105
- t.add_column()
106
- t.add_row("Name:", user.get("name", "?"))
107
- t.add_row("Email:", user.get("email", "?"))
108
- t.add_row("Provider:", user.get("provider", "?"))
109
- t.add_row("User ID:", user.get("userId", "?"))
110
- _console.print(Panel(t, title="Current User", border_style="cyan"))
File without changes