Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 53 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,32 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
- `--no-color` - Disable color output
- `--log-level <level>` - Set log level (trace, debug, info, warn, error, fatal, print)

## JSON Output

Many commands support JSON output for scripting and automation. Use `--output json` or `-o json` to get machine-readable output:

```bash
# Get browser session details as JSON
kernel browsers create -o json

# List apps as JSON
kernel app list -o json

# Deploy with JSONL streaming output (one JSON object per line)
kernel deploy index.ts -o json
```

Commands with JSON output support:
- **Browsers**: `create`, `list`, `get`, `view`
- **Browser Pools**: `create`, `list`, `get`, `update`, `acquire`
- **Profiles**: `create`, `list`, `get`
- **Extensions**: `upload`, `list`
- **Proxies**: `create`, `list`, `get`
- **Apps**: `list`, `history`
- **Deploy**: `deploy` (JSONL streaming), `history`
- **Invoke**: `invoke` (JSONL streaming), `history`
- **Browser Sub-commands**: `replays list/start`, `process exec/spawn`, `fs file-info/list-files`

### Authentication

- `kernel login [--force]` - Login via OAuth 2.0
Expand Down Expand Up @@ -134,6 +160,7 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
- `--force` - Allow overwriting existing version
- `--env <KEY=VALUE>`, `-e` - Set environment variables (can be used multiple times)
- `--env-file <file>` - Load environment variables from file (can be used multiple times)
- `--output json`, `-o json` - Output JSONL (one JSON object per line for each event)

- `kernel deploy logs <deployment_id>` - Stream logs for a deployment

Expand All @@ -143,6 +170,7 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).

- `kernel deploy history [app_name]` - Show deployment history
- `--limit <n>` - Max deployments to return (default: 100; 0 = all)
- `--output json`, `-o json` - Output raw JSON array

### App Management

Expand All @@ -152,14 +180,17 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
- `--payload <json>`, `-p` - JSON payload for the action
- `--payload-file <path>`, `-f` - Read JSON payload from a file (use `-` for stdin)
- `--sync`, `-s` - Invoke synchronously (timeout after 60s)
- `--output json`, `-o json` - Output JSONL (one JSON object per line for each event)

- `kernel app list` - List deployed apps

- `--name <app_name>` - Filter by app name
- `--version <version>` - Filter by version
- `--output json`, `-o json` - Output raw JSON array

- `kernel app history <app_name>` - Show deployment history for an app
- `--limit <n>` - Max deployments to return (default: 100; 0 = all)
- `--output json`, `-o json` - Output raw JSON array

### Logs

Expand All @@ -172,36 +203,44 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
### Browser Management

- `kernel browsers list` - List running browsers
- `--output json`, `-o json` - Output raw JSON array
- `kernel browsers create` - Create a new browser session
- `-s, --stealth` - Launch browser in stealth mode to avoid detection
- `-H, --headless` - Launch browser without GUI access
- `--kiosk` - Launch browser in kiosk mode
- `--pool-id <id>` - Acquire a browser from the specified pool (mutually exclusive with --pool-name; ignores other session flags)
- `--pool-name <name>` - Acquire a browser from the pool name (mutually exclusive with --pool-id; ignores other session flags)
- `--output json`, `-o json` - Output raw JSON object
- _Note: When a pool is specified, omit other session configuration flags—pool settings determine profile, proxy, viewport, etc._
- `kernel browsers delete <id>` - Delete a browser
- `-y, --yes` - Skip confirmation prompt
- `kernel browsers view <id>` - Get live view URL for a browser
- `--output json`, `-o json` - Output JSON with liveViewUrl
- `kernel browsers get <id>` - Get detailed browser session info
- `--output json`, `-o json` - Output raw JSON object

### Browser Pools

- `kernel browser-pools list` - List browser pools
- `-o, --output json` - Output raw JSON response
- `--output json`, `-o json` - Output raw JSON array
- `kernel browser-pools create` - Create a browser pool
- `--name <name>` - Optional unique name for the pool
- `--size <n>` - Number of browsers in the pool (required)
- `--fill-rate <n>` - Percentage of the pool to fill per minute
- `--timeout <seconds>` - Idle timeout for browsers acquired from the pool
- `--stealth`, `--headless`, `--kiosk` - Default pool configuration
- `--profile-id`, `--profile-name`, `--save-changes`, `--proxy-id`, `--extension`, `--viewport` - Same semantics as `kernel browsers create`
- `--output json`, `-o json` - Output raw JSON object
- `kernel browser-pools get <id-or-name>` - Get pool details
- `-o, --output json` - Output raw JSON response
- `--output json`, `-o json` - Output raw JSON object
- `kernel browser-pools update <id-or-name>` - Update pool configuration
- Same flags as create plus `--discard-all-idle` to discard all idle browsers in the pool and refill at the specified fill rate
- `--output json`, `-o json` - Output raw JSON object
- `kernel browser-pools delete <id-or-name>` - Delete a pool
- `--force` - Force delete even if browsers are leased
- `kernel browser-pools acquire <id-or-name>` - Acquire a browser from the pool
- `--timeout <seconds>` - Acquire timeout before returning 204
- `--output json`, `-o json` - Output raw JSON object
- `kernel browser-pools release <id-or-name>` - Release a browser back to the pool
- `--session-id <id>` - Browser session ID to release (required)
- `--reuse` - Reuse the browser instance (default: true)
Expand All @@ -218,12 +257,14 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
### Browser Replays

- `kernel browsers replays list <id>` - List replays for a browser
- `--output json`, `-o json` - Output raw JSON array
- `kernel browsers replays start <id>` - Start a replay recording
- `--framerate <fps>` - Recording framerate (fps)
- `--max-duration <seconds>` - Maximum duration in seconds
- `--output json`, `-o json` - Output raw JSON object
- `kernel browsers replays stop <id> <replay-id>` - Stop a replay recording
- `kernel browsers replays download <id> <replay-id>` - Download a replay video
- `-o, --output <path>` - Output file path for the replay video
- `-f, --output-file <path>` - Output file path for the replay video

### Browser Process Control

Expand All @@ -234,13 +275,15 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
- `--timeout <seconds>` - Timeout in seconds
- `--as-user <user>` - Run as user
- `--as-root` - Run as root
- `--output json`, `-o json` - Output raw JSON object
- `kernel browsers process spawn <id> [--] [command...]` - Execute a command asynchronously
- `--command <cmd>` - Command to execute (optional; if omitted, trailing args are executed via /bin/bash -c)
- `--args <args>` - Command arguments
- `--cwd <path>` - Working directory
- `--timeout <seconds>` - Timeout in seconds
- `--as-user <user>` - Run as user
- `--as-root` - Run as root
- `--output json`, `-o json` - Output raw JSON object
- `kernel browsers process kill <id> <process-id>` - Send a signal to a process
- `--signal <signal>` - Signal to send: TERM, KILL, INT, HUP (default: TERM)
- `kernel browsers process status <id> <process-id>` - Get process status
Expand All @@ -262,8 +305,10 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
- `-o, --output <path>` - Output zip file path
- `kernel browsers fs file-info <id>` - Get file or directory info
- `--path <path>` - Absolute file or directory path (required)
- `--output json`, `-o json` - Output raw JSON object
- `kernel browsers fs list-files <id>` - List files in a directory
- `--path <path>` - Absolute directory path (required)
- `--output json`, `-o json` - Output raw JSON array
- `kernel browsers fs move <id>` - Move or rename a file or directory
- `--src <path>` - Absolute source path (required)
- `--dest <path>` - Absolute destination path (required)
Expand Down Expand Up @@ -344,8 +389,10 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
### Extension Management

- `kernel extensions list` - List all uploaded extensions
- `--output json`, `-o json` - Output raw JSON array
- `kernel extensions upload <directory>` - Upload an unpacked browser extension directory
- `--name <name>` - Optional unique extension name
- `--output json`, `-o json` - Output raw JSON object
- `kernel extensions download <id-or-name>` - Download an extension archive
- `--to <directory>` - Output directory (required)
- `kernel extensions download-web-store <url>` - Download an extension from the Chrome Web Store
Expand All @@ -357,8 +404,11 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
### Proxy Management

- `kernel proxies list` - List proxy configurations
- `--output json`, `-o json` - Output raw JSON array
- `kernel proxies get <id>` - Get a proxy configuration by ID
- `--output json`, `-o json` - Output raw JSON object
- `kernel proxies create` - Create a new proxy configuration
- `--output json`, `-o json` - Output raw JSON object

- `--name <name>` - Proxy configuration name
- `--type <type>` - Proxy type: datacenter, isp, residential, mobile, custom (required)
Expand Down
47 changes: 45 additions & 2 deletions cmd/app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"encoding/json"
"fmt"
"strings"

Expand Down Expand Up @@ -44,9 +45,11 @@ func init() {
appListCmd.Flags().Int("limit", 20, "Max apps to return (default 20)")
appListCmd.Flags().Int("per-page", 20, "Items per page (alias of --limit)")
appListCmd.Flags().Int("page", 1, "Page number (1-based)")
appListCmd.Flags().StringP("output", "o", "", "Output format: json for raw API response")

// Limit rows returned for app history (0 = all)
appHistoryCmd.Flags().Int("limit", 20, "Max deployments to return (default 20)")
appHistoryCmd.Flags().StringP("output", "o", "", "Output format: json for raw API response")
}

func runAppList(cmd *cobra.Command, args []string) error {
Expand All @@ -56,6 +59,11 @@ func runAppList(cmd *cobra.Command, args []string) error {
lim, _ := cmd.Flags().GetInt("limit")
perPage, _ := cmd.Flags().GetInt("per-page")
page, _ := cmd.Flags().GetInt("page")
output, _ := cmd.Flags().GetString("output")

if output != "" && output != "json" {
return fmt.Errorf("unsupported --output value: use 'json'")
}

// Determine pagination inputs: prefer page/per-page if provided; else map legacy --limit
usePager := cmd.Flags().Changed("per-page") || cmd.Flags().Changed("page")
Expand All @@ -73,7 +81,9 @@ func runAppList(cmd *cobra.Command, args []string) error {
page = 1
}

pterm.Debug.Println("Fetching deployed applications...")
if output != "json" {
pterm.Debug.Println("Fetching deployed applications...")
}

params := kernel.AppListParams{}
if appName != "" {
Expand All @@ -92,6 +102,19 @@ func runAppList(cmd *cobra.Command, args []string) error {
return nil
}

if output == "json" {
if apps == nil || len(apps.Items) == 0 {
fmt.Println("[]")
return nil
}
bs, err := json.MarshalIndent(apps.Items, "", " ")
if err != nil {
return err
}
fmt.Println(string(bs))
return nil
}

if apps == nil || len(apps.Items) == 0 {
pterm.Info.Println("No applications found")
return nil
Expand Down Expand Up @@ -193,8 +216,15 @@ func runAppHistory(cmd *cobra.Command, args []string) error {
client := getKernelClient(cmd)
appName := args[0]
lim, _ := cmd.Flags().GetInt("limit")
output, _ := cmd.Flags().GetString("output")

pterm.Debug.Printf("Fetching deployment history for app '%s'...\n", appName)
if output != "" && output != "json" {
return fmt.Errorf("unsupported --output value: use 'json'")
}

if output != "json" {
pterm.Debug.Printf("Fetching deployment history for app '%s'...\n", appName)
}

params := kernel.DeploymentListParams{}
if appName != "" {
Expand All @@ -207,6 +237,19 @@ func runAppHistory(cmd *cobra.Command, args []string) error {
return nil
}

if output == "json" {
if deployments == nil || len(deployments.Items) == 0 {
fmt.Println("[]")
return nil
}
bs, err := json.MarshalIndent(deployments.Items, "", " ")
if err != nil {
return err
}
fmt.Println(string(bs))
return nil
}

if deployments == nil || len(deployments.Items) == 0 {
pterm.Info.Println("No deployments found for this application")
return nil
Expand Down
Loading