diff --git a/docs/v1.2.1/README.md b/docs/v1.2.1/README.md new file mode 100644 index 0000000..8efe5f3 --- /dev/null +++ b/docs/v1.2.1/README.md @@ -0,0 +1,42 @@ +# KDM CLI — Versioned Command Documentation + +**Version:** v1.2.1 + +This directory contains versioned documentation for all KDM CLI commands. Each section documents a top-level command group with usage, parameters, examples, and troubleshooting. + +## Command Index + +- [show](./show/README.md) — Show running runners, pods, containers, or minikube +- [health](./health/README.md) — Show health status for pods or containers +- [watch](./watch/README.md) — Live monitoring mode +- [logs](./logs/README.md) — Show logs for a container or pod +- [config](./config/README.md) — Manage KDM configuration + +## Quick Start + +```bash +# Install globally +npm install -g kdm-cli + +# Show all workloads +kdm show runners + +# Check pod health +kdm health pods + +# Live watch +kdm watch + +# View logs +kdm logs + +# Configure notifications +kdm config setup +``` + +## Version History + +| Version | Release Date | Notes | +|---------|-------------|-------| +| v1.2.1 | — | Current release. Docker & Kubernetes monitoring, config management. | +| v1.1.0 | — | Initial release with core commands. | diff --git a/docs/v1.2.1/config/README.md b/docs/v1.2.1/config/README.md new file mode 100644 index 0000000..18d5ab9 --- /dev/null +++ b/docs/v1.2.1/config/README.md @@ -0,0 +1,134 @@ +# `kdm config` — Configuration Management + +**Version:** v1.2.1 + +## Overview + +The `kdm config` command group manages KDM CLI configuration, including notification service setup, custom settings, and credential management. Configuration is stored locally using the `conf` package. + +## Syntax + +```bash +kdm config +``` + +## Sub-commands + +### `kdm config setup` + +Interactively sets up the notification service (Discord webhook or Email SMTP). + +**Example:** + +```bash +kdm config setup +``` + +**Interactive Flow:** + +1. Select a notification service: + - **Discord** — Send alerts to a Discord channel via webhook. + - **Email (SMTP)** — Send alerts via email SMTP. + - **None** — Disable notifications. + +2. For **Discord**, you will be prompted for a webhook URL. +3. For **Email**, you will be prompted for SMTP host, port, user, and recipient email. + +**Discord Webhook Setup:** + +1. Open your Discord server settings. +2. Go to **Integrations > Webhooks**. +3. Create a new webhook and choose the alert channel. +4. Copy the webhook URL (must start with `https://discord.com/api/webhooks/`). + +**Email SMTP Setup:** + +| Setting | Default | Description | +|---------|---------|-------------| +| Host | `smtp.gmail.com` | SMTP server address | +| Port | `587` | SMTP port (STARTTLS) | +| User | — | Your email address | +| To | — | Alert recipient email | + +> **Note:** SMTP passwords must be set via the `KDM_SMTP_PASSWORD` environment variable. + +--- + +### `kdm config set ` + +Sets a specific configuration value. + +**Example:** + +```bash +kdm config set alert_cooldown 300 +kdm config set email_port 465 +``` + +**Supported Keys:** + +| Key | Type | Description | +|-----|------|-------------| +| `alert_cooldown` | number | Cooldown period between alerts (seconds) | +| `email_port` | number | SMTP port | +| `notification_service` | string | `discord`, `email`, or `none` | +| `discord_webhook` | string | Discord webhook URL | +| `email_host` | string | SMTP host | +| `email_user` | string | SMTP username | +| `email_to` | string | Alert recipient email | + +--- + +### `kdm config list` + +Lists all current configuration values. + +**Example:** + +```bash +kdm config list +``` + +**Expected Output:** + +``` +Current KDM Configuration: +────────────────────────────────────────────────── + notification_service : discord + discord_webhook : https://discord.com/api/webhooks/... +────────────────────────────────────────────────── + + Note: SMTP passwords must be set via KDM_SMTP_PASSWORD env var. +``` + +--- + +### `kdm config clear` + +Clears all configuration and resets to defaults. + +**Example:** + +```bash +kdm config clear +``` + +**Expected Output:** + +``` +✓ Configuration cleared. +``` + +## Configuration File Location + +Configuration is stored in the default `conf` package location: + +- **macOS:** `~/Library/Application Support/kdm-cli` +- **Linux:** `~/.config/kdm-cli` +- **Windows:** `%APPDATA%\kdm-cli` + +## Common Errors + +- **Invalid webhook URL** — Must match `https://discord.com/api/webhooks//`. +- **Invalid email address** — Must be a valid email format. +- **Invalid port number** — Must be between 1 and 65535. diff --git a/docs/v1.2.1/health/README.md b/docs/v1.2.1/health/README.md new file mode 100644 index 0000000..a9b1251 --- /dev/null +++ b/docs/v1.2.1/health/README.md @@ -0,0 +1,91 @@ +# `kdm health` — Health Status + +**Version:** v1.2.1 + +## Overview + +The `kdm health` command checks and reports the health status of Kubernetes pods or Docker containers. It provides insights into readiness, crash loops, and other health conditions. + +## Syntax + +```bash +kdm health +``` + +## Parameters + +| Parameter | Description | Valid Values | +|-----------|-------------|--------------| +| `target` | The workload type to check | `pods`, `containers`, `all` | + +## Usage + +### `kdm health pods` + +Checks the health status of all Kubernetes pods. + +**Example:** + +```bash +kdm health pods +``` + +**Expected Output:** + +``` +Checking health for pods... +Showing health for pods... +``` + +**Health Indicators:** + +- **Ready** — Pod is running and accepting traffic. +- **Unhealthy** — Pod is running but probes are failing. +- **CrashLoopBackOff** — Pod is repeatedly crashing and restarting. + +**Use Cases:** + +- Monitor pod health in real time. +- Identify failing services before they cause outages. + +--- + +### `kdm health containers` + +Checks the health status of all Docker containers. + +**Example:** + +```bash +kdm health containers +``` + +**Expected Output:** + +``` +Checking health for containers... +Showing health for containers... +``` + +**Use Cases:** + +- Verify container health. +- Detect containers that are unhealthy or restarting. + +--- + +### `kdm health all` + +Checks health for both pods and containers in a single call. + +**Example:** + +```bash +kdm health all +``` + +## Common Errors + +- **Invalid target** — Use `pods`, `containers`, or `all`. +- **Docker daemon not running** — Start Docker before running `kdm health containers`. +- **Kubernetes context not found** — Run `kubectl config get-contexts` to verify your cluster connection. diff --git a/docs/v1.2.1/logs/README.md b/docs/v1.2.1/logs/README.md new file mode 100644 index 0000000..370f419 --- /dev/null +++ b/docs/v1.2.1/logs/README.md @@ -0,0 +1,52 @@ +# `kdm logs` — Show Logs + +**Version:** v1.2.1 + +## Overview + +The `kdm logs` command retrieves and displays logs from a specified Docker container or Kubernetes pod. This is useful for debugging application issues and reviewing runtime events. + +## Syntax + +```bash +kdm logs +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `name` | The name of the container or pod to fetch logs from | + +## Usage + +### `kdm logs ` + +Fetches and displays logs for the specified workload. + +**Example:** + +```bash +kdm logs nginx-abc12 +``` + +**Expected Output:** + +``` +Fetching logs for nginx-abc12... +Logs for nginx-abc12 fetched +[timestamp] GET / 200 12ms +[timestamp] GET /favicon.ico 404 2ms +``` + +**Use Cases:** + +- Debug application errors by reviewing container/pod logs. +- Monitor application events in real time. +- Investigate crash or restart causes. + +## Common Errors + +- **Name not found** — Verify the container or pod name using `kdm show containers` or `kdm show pods`. +- **Docker daemon not running** — Start Docker before fetching container logs. +- **Kubernetes context not found** — Ensure `kubectl` is configured with a valid cluster context. diff --git a/docs/v1.2.1/show/README.md b/docs/v1.2.1/show/README.md new file mode 100644 index 0000000..b11e718 --- /dev/null +++ b/docs/v1.2.1/show/README.md @@ -0,0 +1,134 @@ +# `kdm show` — Show Running Workloads + +**Version:** v1.2.1 + +## Overview + +The `kdm show` command displays information about running workloads — Docker containers, Kubernetes pods, combined runners, or Minikube status. It provides a unified view of your local development environment. + +## Syntax + +```bash +kdm show +``` + +## Parameters + +| Parameter | Description | Valid Values | +|-----------|-------------|--------------| +| `target` | The workload type to display | `runners`, `pods`, `containers`, `minikube` | + +## Sub-commands + +### `kdm show runners` + +Shows a combined view of all running Docker containers and Kubernetes pods in a single table. + +**Example:** + +```bash +kdm show runners +``` + +**Expected Output:** + +``` +┌───────────┬──────────────┬──────────────────────┬─────────┬─────────────────┐ +│ TYPE │ NAME / ID │ NAMESPACE / IMAGE │ STATUS │ NODE / STATE │ +├───────────┼──────────────┼──────────────────────┼─────────┼─────────────────┤ +│ Pod │ nginx-abc12 │ default │ Running │ minikube │ +│ Container │ my-app │ myregistry/app:v1 │ running │ host │ +└───────────┴──────────────┴──────────────────────┴─────────┴─────────────────┘ +``` + +**Use Cases:** + +- Get a quick overview of all services running locally. +- Monitor both Docker and Kubernetes workloads simultaneously. + +**Common Errors:** + +- `Docker is unreachable` — Docker daemon is not running. Start Docker Desktop or `systemctl start docker`. +- `Kubernetes is unreachable` — No kubeconfig found or cluster is down. Check `kubectl cluster-info`. + +--- + +### `kdm show pods` + +Shows all Kubernetes pods in the current namespace. + +**Example:** + +```bash +kdm show pods +``` + +**Expected Output:** + +``` +┌──────────────┬───────────┬─────────┬──────────┬──────────┐ +│ POD NAME │ NAMESPACE │ STATUS │ RESTARTS │ NODE │ +├──────────────┼───────────┼─────────┼──────────┼──────────┤ +│ nginx-abc12 │ default │ Running │ 0 │ minikube │ +│ redis-xyz34 │ default │ Running │ 2 │ minikube │ +└──────────────┴───────────┴─────────┴──────────┴──────────┘ +``` + +**Use Cases:** + +- Inspect pod status and restart counts. +- Identify pods in non-Running states. + +--- + +### `kdm show containers` + +Shows all running Docker containers. + +**Example:** + +```bash +kdm show containers +``` + +**Expected Output:** + +``` +┌────────────┬────────────┬────────────────┬────────┬─────────┐ +│ CONTAINER │ NAME │ IMAGE │ STATUS │ STATE │ +│ ID │ │ │ │ │ +├────────────┼────────────┼────────────────┼────────┼─────────┤ +│ a1b2c3d4e5 │ my-app │ myregistry/app │ Up │ running │ +└────────────┴────────────┴────────────────┴────────┴─────────┘ +``` + +**Use Cases:** + +- List all active containers. +- Verify container states at a glance. + +--- + +### `kdm show minikube` + +Shows the status of Minikube profiles on the local machine. + +**Example:** + +```bash +kdm show minikube +``` + +**Expected Output:** + +``` +┌─────────┬─────────┬─────────┬─────────────┬─────────┐ +│ NAME │ HOST │ KUBELET │ APISERVER │ MESSAGE │ +├─────────┼─────────┼─────────┼─────────────┼─────────┤ +│ default │ Running │ Running │ Running │ │ +└─────────┴─────────┴─────────┴─────────────┴─────────┘ +``` + +**Common Errors:** + +- `Minikube is not installed on this system` — Install Minikube from https://minikube.sigs.k8s.io. diff --git a/docs/v1.2.1/watch/README.md b/docs/v1.2.1/watch/README.md new file mode 100644 index 0000000..66f6a99 --- /dev/null +++ b/docs/v1.2.1/watch/README.md @@ -0,0 +1,52 @@ +# `kdm watch` — Live Monitoring + +**Version:** v1.2.1 + +## Overview + +The `kdm watch` command enters a live monitoring mode, continuously updating the terminal with real-time resource usage and status of running Docker containers and Kubernetes pods. Powered by Ink for an interactive terminal UI. + +## Syntax + +```bash +kdm watch +``` + +## Parameters + +This command takes no arguments. + +## Usage + +### `kdm watch` + +Starts a real-time monitoring dashboard. + +**Example:** + +```bash +kdm watch +``` + +**Expected Output:** + +The terminal will display an interactive, auto-refreshing table showing: + +- Container/pod names +- Current resource usage (CPU, memory) +- Health status +- Restart counts + +The view updates automatically. Press `Ctrl+C` to exit. + +**Use Cases:** + +- Continuously monitor service health during development. +- Watch for resource spikes or pod restarts in real time. +- Debug intermittent failures by observing live status changes. + +## Common Errors + +- **No workloads found** — Ensure at least one Docker container or Kubernetes pod is running. +- **Docker daemon not running** — Start Docker Desktop or `systemctl start docker`. +- **Kubernetes context not configured** — Verify with `kubectl cluster-info`. diff --git a/src/commands/root.ts b/src/commands/root.ts index 4f7a12a..39497ae 100644 --- a/src/commands/root.ts +++ b/src/commands/root.ts @@ -11,6 +11,7 @@ import { registerConfigCommand } from './config'; import { logger } from '../utils/logger'; import { showWelcomeBanner } from '../ui/banner'; import { createSpinner } from '../ui/spinner'; +import { checkForUpdates } from '../utils/version-check'; program .name('kdm') @@ -75,6 +76,9 @@ const run = async () => { } program.parse(process.argv); + + // Non-blocking version check (fires after command execution) + checkForUpdates(); }; run(); diff --git a/src/utils/version-check.ts b/src/utils/version-check.ts new file mode 100644 index 0000000..618ed32 --- /dev/null +++ b/src/utils/version-check.ts @@ -0,0 +1,76 @@ +import chalk from 'chalk'; +import { readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +// Read the actual package.json version at runtime +function getInstalledVersion(): string { + const pkgPath = join(__dirname, '..', '..', 'package.json'); + try { + const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')); + return pkg.version || '0.0.0'; + } catch { + return '0.0.0'; + } +} + +// Compare two semver strings; returns 'lt' if a < b, 'gt' if a > b, 'eq' if equal +function compareSemver(a: string, b: string): 'lt' | 'gt' | 'eq' { + const parse = (v: string) => v.replace(/^v/, '').split('.').map(Number); + const [a1, a2, a3] = parse(a); + const [b1, b2, b3] = parse(b); + if (a1 !== b1) return a1 < b1 ? 'lt' : 'gt'; + if (a2 !== b2) return a2 < b2 ? 'lt' : 'gt'; + if (a3 !== b3) return a3 < b3 ? 'lt' : 'gt'; + return 'eq'; +} + +// Determine update type for messaging +function getUpdateType(installed: string, latest: string): string { + const cmp = compareSemver(installed, latest); + if (cmp === 'eq') return ''; + const [i1] = installed.replace(/^v/, '').split('.').map(Number); + const [l1] = latest.replace(/^v/, '').split('.').map(Number); + if (l1 > i1) return 'major'; +function getUpdateType(installed: string, latest: string): string { + const cmp = compareSemver(installed, latest); + if (cmp === 'eq') return ''; + const [i1 = 0, i2 = 0] = installed.replace(/^v/, '').split('.').map(Number); + const [l1 = 0, l2 = 0] = latest.replace(/^v/, '').split('.').map(Number); + if (l1 > i1) return 'major'; + if (l2 > i2) return 'minor'; + return 'patch'; +} + return 'patch'; +} + +export async function checkForUpdates(): Promise { + try { + const response = await fetch('https://registry.npmjs.org/kdm-cli/latest', { + signal: AbortSignal.timeout(1500), + }); + if (!response.ok) return; + + const data = await response.json() as { version: string }; + const latestVersion = data.version; + const installedVersion = getInstalledVersion(); + + const cmp = compareSemver(installedVersion, latestVersion); + if (cmp === 'lt') { + const updateType = getUpdateType(installedVersion, latestVersion); + const typeLabel = updateType === 'major' ? 'Major' : updateType === 'minor' ? 'Minor' : 'New'; + + console.log(); + console.log(chalk.bold(chalk.yellow(` ${typeLabel} update available!`))); + console.log(chalk.white(` Current Version : v${installedVersion}`)); + console.log(chalk.white(` Latest Version : v${latestVersion}`)); + console.log(chalk.cyan(` Update using : npm install -g kdm-cli@latest`)); + console.log(); + } + } catch { + // Silently fail — version check is non-critical + } +}