Skip to content

Commit 59bc757

Browse files
committed
feat: add --output json flag for machine-readable output
Add JSON output support to CLI commands for scripting and automation: Tier 1 (create/acquire operations): - browsers create - browser-pools create, acquire - profiles create - extensions upload - proxies create - deploy (JSONL streaming) Tier 2 (list/get operations): - browsers list, get, view - browser-pools list, get, update - profiles list, get - extensions list - proxies list, get Tier 3 (app/invoke/browser sub-operations): - app list, history - deploy history - invoke (JSONL streaming), history - browsers replays list, start - browsers process exec, spawn - browsers fs file-info, list-files For streaming commands (deploy, invoke), output is JSONL format (one JSON object per line) for real-time parsing. Usage: --output json or -o json
1 parent 4570261 commit 59bc757

File tree

13 files changed

+701
-63
lines changed

13 files changed

+701
-63
lines changed

README.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,32 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
104104
- `--no-color` - Disable color output
105105
- `--log-level <level>` - Set log level (trace, debug, info, warn, error, fatal, print)
106106

107+
## JSON Output
108+
109+
Many commands support JSON output for scripting and automation. Use `--output json` or `-o json` to get machine-readable output:
110+
111+
```bash
112+
# Get browser session details as JSON
113+
kernel browsers create -o json
114+
115+
# List apps as JSON
116+
kernel app list -o json
117+
118+
# Deploy with JSONL streaming output (one JSON object per line)
119+
kernel deploy index.ts -o json
120+
```
121+
122+
Commands with JSON output support:
123+
- **Browsers**: `create`, `list`, `get`, `view`
124+
- **Browser Pools**: `create`, `list`, `get`, `update`, `acquire`
125+
- **Profiles**: `create`, `list`, `get`
126+
- **Extensions**: `upload`, `list`
127+
- **Proxies**: `create`, `list`, `get`
128+
- **Apps**: `list`, `history`
129+
- **Deploy**: `deploy` (JSONL streaming), `history`
130+
- **Invoke**: `invoke` (JSONL streaming), `history`
131+
- **Browser Sub-commands**: `replays list/start`, `process exec/spawn`, `fs file-info/list-files`
132+
107133
### Authentication
108134

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

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

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

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

147175
### App Management
148176

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

156185
- `kernel app list` - List deployed apps
157186

158187
- `--name <app_name>` - Filter by app name
159188
- `--version <version>` - Filter by version
189+
- `--output json`, `-o json` - Output raw JSON array
160190

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

164195
### Logs
165196

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

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

186222
### Browser Pools
187223

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

220259
- `kernel browsers replays list <id>` - List replays for a browser
260+
- `--output json`, `-o json` - Output raw JSON array
221261
- `kernel browsers replays start <id>` - Start a replay recording
222262
- `--framerate <fps>` - Recording framerate (fps)
223263
- `--max-duration <seconds>` - Maximum duration in seconds
264+
- `--output json`, `-o json` - Output raw JSON object
224265
- `kernel browsers replays stop <id> <replay-id>` - Stop a replay recording
225266
- `kernel browsers replays download <id> <replay-id>` - Download a replay video
226-
- `-o, --output <path>` - Output file path for the replay video
267+
- `-f, --output-file <path>` - Output file path for the replay video
227268

228269
### Browser Process Control
229270

@@ -234,13 +275,15 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
234275
- `--timeout <seconds>` - Timeout in seconds
235276
- `--as-user <user>` - Run as user
236277
- `--as-root` - Run as root
278+
- `--output json`, `-o json` - Output raw JSON object
237279
- `kernel browsers process spawn <id> [--] [command...]` - Execute a command asynchronously
238280
- `--command <cmd>` - Command to execute (optional; if omitted, trailing args are executed via /bin/bash -c)
239281
- `--args <args>` - Command arguments
240282
- `--cwd <path>` - Working directory
241283
- `--timeout <seconds>` - Timeout in seconds
242284
- `--as-user <user>` - Run as user
243285
- `--as-root` - Run as root
286+
- `--output json`, `-o json` - Output raw JSON object
244287
- `kernel browsers process kill <id> <process-id>` - Send a signal to a process
245288
- `--signal <signal>` - Signal to send: TERM, KILL, INT, HUP (default: TERM)
246289
- `kernel browsers process status <id> <process-id>` - Get process status
@@ -262,8 +305,10 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
262305
- `-o, --output <path>` - Output zip file path
263306
- `kernel browsers fs file-info <id>` - Get file or directory info
264307
- `--path <path>` - Absolute file or directory path (required)
308+
- `--output json`, `-o json` - Output raw JSON object
265309
- `kernel browsers fs list-files <id>` - List files in a directory
266310
- `--path <path>` - Absolute directory path (required)
311+
- `--output json`, `-o json` - Output raw JSON array
267312
- `kernel browsers fs move <id>` - Move or rename a file or directory
268313
- `--src <path>` - Absolute source path (required)
269314
- `--dest <path>` - Absolute destination path (required)
@@ -344,8 +389,10 @@ Create an API key from the [Kernel dashboard](https://dashboard.onkernel.com).
344389
### Extension Management
345390

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

359406
- `kernel proxies list` - List proxy configurations
407+
- `--output json`, `-o json` - Output raw JSON array
360408
- `kernel proxies get <id>` - Get a proxy configuration by ID
409+
- `--output json`, `-o json` - Output raw JSON object
361410
- `kernel proxies create` - Create a new proxy configuration
411+
- `--output json`, `-o json` - Output raw JSON object
362412

363413
- `--name <name>` - Proxy configuration name
364414
- `--type <type>` - Proxy type: datacenter, isp, residential, mobile, custom (required)

cmd/app.go

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"strings"
67

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

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

5255
func runAppList(cmd *cobra.Command, args []string) error {
@@ -56,6 +59,12 @@ func runAppList(cmd *cobra.Command, args []string) error {
5659
lim, _ := cmd.Flags().GetInt("limit")
5760
perPage, _ := cmd.Flags().GetInt("per-page")
5861
page, _ := cmd.Flags().GetInt("page")
62+
output, _ := cmd.Flags().GetString("output")
63+
64+
if output != "" && output != "json" {
65+
pterm.Error.Println("unsupported --output value: use 'json'")
66+
return nil
67+
}
5968

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

76-
pterm.Debug.Println("Fetching deployed applications...")
85+
if output != "json" {
86+
pterm.Debug.Println("Fetching deployed applications...")
87+
}
7788

7889
params := kernel.AppListParams{}
7990
if appName != "" {
@@ -92,6 +103,19 @@ func runAppList(cmd *cobra.Command, args []string) error {
92103
return nil
93104
}
94105

106+
if output == "json" {
107+
if apps == nil || len(apps.Items) == 0 {
108+
fmt.Println("[]")
109+
return nil
110+
}
111+
bs, err := json.MarshalIndent(apps.Items, "", " ")
112+
if err != nil {
113+
return err
114+
}
115+
fmt.Println(string(bs))
116+
return nil
117+
}
118+
95119
if apps == nil || len(apps.Items) == 0 {
96120
pterm.Info.Println("No applications found")
97121
return nil
@@ -193,8 +217,16 @@ func runAppHistory(cmd *cobra.Command, args []string) error {
193217
client := getKernelClient(cmd)
194218
appName := args[0]
195219
lim, _ := cmd.Flags().GetInt("limit")
220+
output, _ := cmd.Flags().GetString("output")
196221

197-
pterm.Debug.Printf("Fetching deployment history for app '%s'...\n", appName)
222+
if output != "" && output != "json" {
223+
pterm.Error.Println("unsupported --output value: use 'json'")
224+
return nil
225+
}
226+
227+
if output != "json" {
228+
pterm.Debug.Printf("Fetching deployment history for app '%s'...\n", appName)
229+
}
198230

199231
params := kernel.DeploymentListParams{}
200232
if appName != "" {
@@ -207,6 +239,19 @@ func runAppHistory(cmd *cobra.Command, args []string) error {
207239
return nil
208240
}
209241

242+
if output == "json" {
243+
if deployments == nil || len(deployments.Items) == 0 {
244+
fmt.Println("[]")
245+
return nil
246+
}
247+
bs, err := json.MarshalIndent(deployments.Items, "", " ")
248+
if err != nil {
249+
return err
250+
}
251+
fmt.Println(string(bs))
252+
return nil
253+
}
254+
210255
if deployments == nil || len(deployments.Items) == 0 {
211256
pterm.Info.Println("No deployments found for this application")
212257
return nil

0 commit comments

Comments
 (0)