runhuman 2.1.0 → 2.2.0

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 (4) hide show
  1. package/LICENSE +15 -15
  2. package/README.md +947 -926
  3. package/dist/index.js +102 -103
  4. package/package.json +80 -80
package/README.md CHANGED
@@ -1,926 +1,947 @@
1
- # runhuman
2
-
3
- [![npm version](https://img.shields.io/npm/v/runhuman.svg)](https://www.npmjs.com/package/runhuman)
4
- [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
5
-
6
- > AI-orchestrated human QA testing from your terminal
7
-
8
- ## What is Runhuman?
9
-
10
- Runhuman is an AI-orchestrated human QA testing service. Get real human testing of your web applications on-demand, with structured results extracted automatically.
11
-
12
- **Perfect for:**
13
- - AI coding agents that need human verification
14
- - CI/CD pipelines with human QA gates
15
- - Visual/UX testing requiring real human judgment
16
- - On-demand QA without hiring/managing teams
17
-
18
- ## Installation
19
-
20
- ```bash
21
- # Install globally
22
- npm install -g runhuman
23
-
24
- # Or use with npx
25
- npx runhuman --help
26
- ```
27
-
28
- ## Quick Start
29
-
30
- ```bash
31
- # 1. Login (opens browser for OAuth)
32
- runhuman login
33
-
34
- # 2. Create your first test
35
- runhuman create https://google.com \
36
- -d "Search for 'recursion' and confirm the tester experiences a joke about recursion"
37
-
38
- # 3. Check the status
39
- runhuman status job_abc123
40
-
41
- # 4. Get results
42
- runhuman results job_abc123
43
- ```
44
-
45
- ## Truncated IDs
46
-
47
- All commands accept truncated ID prefixes, similar to git short hashes. Instead of typing a full ID, you can use just the first few characters:
48
-
49
- ```bash
50
- # Full ID
51
- runhuman status 712e42ad-8f3b-4a1c-9d5e-1234567890ab
52
-
53
- # Truncated resolves to the same job
54
- runhuman status 712e
55
-
56
- # Hyphens are ignored during matching
57
- runhuman status 712e42ad8f3b
58
- ```
59
-
60
- If a prefix matches multiple resources, you'll be prompted to provide more characters. Matching is case-insensitive and hyphen-insensitive.
61
-
62
- **Destructive operations** (`projects delete`, `keys delete`, `projects transfer --to-org`) require the full ID to prevent accidental mismatches.
63
-
64
- ## Global Flags
65
-
66
- Every command accepts the same four global flags:
67
-
68
- - `-j, --json` emit machine-readable JSON to stdout (otherwise pretty-printed output)
69
- - `-q, --quiet` — suppress success and info messages (stderr deprecation/error output is preserved)
70
- - `-y, --yes` — skip confirmation prompts on destructive operations
71
- - `--no-color` — disable ANSI color codes (also honored from `RUNHUMAN_NO_COLOR=1`)
72
-
73
- **`-f, --force` is reserved for override-a-guard semantics**, not confirmation-skip. Today it only appears on `templates create`, where it means "overwrite an existing template with the same name."
74
-
75
- ### Output modes
76
-
77
- `-j, --json` is the single output-mode flag. The CLI does not offer a `-o, --output` / `--format` choice à la kubectl — pretty output for humans and JSON for scripts are the two supported shapes. Any future structured-text formats (YAML, CSV, etc.) would be added as their own flags rather than via a format matrix.
78
-
79
- This also means `-o` remains bound to `--organization` on every command that has one, matching the noun-first mental model the rest of the CLI uses.
80
-
81
- ### JSON envelope
82
-
83
- Every command that emits JSON uses the same envelope:
84
-
85
- ```jsonc
86
- // Success
87
- {
88
- "success": true,
89
- "data": <payload>, // see below
90
- "pagination": { // only on list commands
91
- "total": 42,
92
- "limit": 20,
93
- "offset": 0,
94
- "hasMore": true
95
- },
96
- "warnings": ["..."], // optional, non-fatal server-side warnings
97
- "timestamp": "2026-04-24T12:34:56.789Z"
98
- }
99
-
100
- // Failure
101
- {
102
- "success": false,
103
- "error": {
104
- "message": "...",
105
- "code": "OPTIONAL_ERROR_CODE",
106
- "details": { /* shape varies */ }
107
- },
108
- "timestamp": "2026-04-24T12:34:56.789Z"
109
- }
110
- ```
111
-
112
- Payload conventions:
113
-
114
- - **List commands** (`projects list`, `jobs list`, `orgs list`, etc.) put their items under `data.items` and their pagination on the envelope. Never `data.jobs` or `data.projects` — always `data.items`.
115
- - **Show / create / update commands** put the entity directly as `data` (e.g. `data: { id, name, ... }`).
116
- - **Delete / archive / cancel commands** return a structured action payload such as `data: { id, deleted: true }`, `data: { id, archived: true }`, `data: { id, cancelled: true }`. The envelope already carries `success: true`; `data` never echoes it.
117
-
118
- A generic script can parse any CLI command's output without inspecting which command was run:
119
-
120
- ```bash
121
- runhuman projects list --json | jq '.data.items[].id'
122
- runhuman projects show <id> --json | jq '.data.id'
123
- runhuman projects delete <id> --json | jq '.data.deleted'
124
- ```
125
-
126
- ## Commands
127
-
128
- ### Jobs
129
-
130
- #### `create [url]`
131
-
132
- Create a new QA test job.
133
-
134
- ```bash
135
- # Basic usage
136
- runhuman create https://google.com \
137
- -d "Search for 'recursion' and confirm the tester experiences a joke about recursion"
138
-
139
- # With template
140
- runhuman create https://google.com --template tmpl_abc123
141
-
142
- # Synchronous (wait for result)
143
- runhuman create https://google.com -d "Test search" --sync
144
-
145
- # With custom schema
146
- runhuman create https://google.com -d "Test search" --schema ./schema.json
147
-
148
- # With tester pool requirements
149
- runhuman create https://google.com -d "Test mobile layout" \
150
- --required-devices ios,android \
151
- --required-languages english
152
- ```
153
-
154
- **Options:**
155
- - `-d, --description <text>` - Test instructions for the human tester
156
- - `-t, --template <name>` - Use a pre-defined template
157
- - `--duration <minutes>` - Target duration (1-60 minutes)
158
- - `--device-class <class>` - Device class: desktop or mobile
159
- - `-S, --schema <file>` - Path to JSON schema for structured output
160
- - `--schema-inline <json>` - Inline JSON schema string
161
- - `--metadata <json>` - Metadata for tracking (JSON string)
162
- - `--github-repo <owner/repo>` - GitHub repo for context
163
- - `--required-devices <devices>` - Required tester devices (comma-separated: ios, android, pc, mac)
164
- - `--required-languages <languages>` - Required tester languages (comma-separated: english, spanish)
165
- - `--require-social-videos` - Require tester to create social videos
166
- - `-s, --sync` - Wait for result before exiting
167
- - `--wait <seconds>` - Max wait time in sync mode (default: 300)
168
- - `-p, --project <id>` - Project ID (or use default from config)
169
- - `-j, --json` - Output as JSON
170
- - `-q, --quiet` - Minimal output (only job ID)
171
-
172
- #### `status <jobId>`
173
-
174
- Check the status of a test job.
175
-
176
- ```bash
177
- runhuman status job_abc123
178
- runhuman status 712e # truncated ID works
179
- ```
180
-
181
- #### `wait <jobId>`
182
-
183
- Wait for a job to complete with live status updates.
184
-
185
- ```bash
186
- runhuman wait job_abc123
187
- runhuman wait job_abc123 --timeout 300
188
- ```
189
-
190
- **Options:**
191
- - `--timeout <seconds>` - Maximum wait time (default: 600)
192
- - `-j, --json` - Output as JSON
193
-
194
- #### `results <jobId>`
195
-
196
- Display detailed test results.
197
-
198
- ```bash
199
- runhuman results job_abc123
200
- runhuman results job_abc123 --json
201
- runhuman results job_abc123 --schema-only # Only extracted schema data
202
- runhuman results job_abc123 --raw # Raw tester response
203
- ```
204
-
205
- **Options:**
206
- - `--schema-only` - Show only extracted schema data
207
- - `--raw` - Show raw tester response without processing
208
- - `-j, --json` - Output as JSON
209
-
210
- #### `list [filter]`
211
-
212
- List all your test jobs with optional status filtering.
213
-
214
- ```bash
215
- # List all jobs
216
- runhuman list
217
-
218
- # Filter by status (positional argument)
219
- runhuman list completed
220
- runhuman list pending
221
-
222
- # Filter by project
223
- runhuman list --project proj_abc123
224
-
225
- # Pagination
226
- runhuman list --limit 20 --offset 40
227
- ```
228
-
229
- **Arguments:**
230
- - `[filter]` - Status filter: all, pending, claimed, in_progress, completed, failed, timeout
231
-
232
- **Options:**
233
- - `-p, --project <id>` - Filter by project
234
- - `--org <id>` - Scope to all projects in an organization (mutually exclusive with `--project`)
235
- - `-n, --limit <number>` - Maximum number of jobs (default: 20)
236
- - `--offset <number>` - Pagination offset (default: 0)
237
- - `-j, --json` - Output as JSON
238
-
239
- #### `artifact <jobId> <type>`
240
-
241
- Download a raw session artifact. Useful for piping transcripts, console logs, or network data into your own tools.
242
-
243
- ```bash
244
- # Print the transcript
245
- runhuman job artifact job_abc123 transcript
246
-
247
- # Pipe raw console logs into jq
248
- runhuman job artifact job_abc123 console-logs --json | jq '.data.consoleMessages[]'
249
- ```
250
-
251
- **Arguments:**
252
- - `<jobId>` - Job ID
253
- - `<type>` - One of: `structured-output`, `transcript`, `console-logs`, `network-requests`, `conversation`, `events`, `key-moments`
254
-
255
- **Options:**
256
- - `-j, --json` - Output as JSON (raw artifact shape wrapped in the standard envelope)
257
-
258
- Rich artifacts are paid-tier gated server-side; ungated requests return a clean "subscription required" error.
259
-
260
- #### `share <jobId>` / `unshare <jobId>`
261
-
262
- Toggle public sharing for a job. `share` enables and prints the public URL; `unshare` disables.
263
-
264
- ```bash
265
- runhuman job share job_abc123
266
- runhuman job unshare job_abc123
267
- ```
268
-
269
- #### `create-issue <jobId> --index <n>`
270
-
271
- File one extracted finding from a completed job as a GitHub issue. Mirrors the web UI's per-finding "Create Issue" button. Simple form only — the CLI submits the finding unedited; use the web UI or `gh issue edit` if you want to change title/body.
272
-
273
- ```bash
274
- # File the first extracted finding to the job's default GitHub repo
275
- runhuman job create-issue job_abc123 --index 0
276
-
277
- # Override the target repo
278
- runhuman job create-issue job_abc123 --index 0 --repo owner/repo
279
- ```
280
-
281
- **Required options:**
282
- - `--index <n>` - Zero-based index into `job.extractedIssues`
283
-
284
- **Options:**
285
- - `--repo <owner/repo>` - Override the job's default GitHub repo
286
- - `-j, --json` - Output as JSON
287
-
288
- #### `delete <jobId>`
289
-
290
- Delete a job.
291
-
292
- ```bash
293
- runhuman delete job_abc123 --force
294
- ```
295
-
296
- **Options:**
297
- - `-f, --force` - Skip confirmation prompt
298
- - `-j, --json` - Output as JSON
299
-
300
- ### Organizations
301
-
302
- #### `orgs list`
303
-
304
- List all organizations you belong to.
305
-
306
- ```bash
307
- runhuman orgs list
308
- runhuman orgs ls # alias
309
- ```
310
-
311
- #### `orgs show <organizationId>`
312
-
313
- Show organization details.
314
-
315
- ```bash
316
- runhuman orgs show org_abc123
317
- runhuman orgs info org_abc123 # alias
318
- ```
319
-
320
- #### `orgs balance <organizationId>`
321
-
322
- Check billing balance.
323
-
324
- ```bash
325
- runhuman orgs balance org_abc123
326
- ```
327
-
328
- #### `orgs projects <organizationId>`
329
-
330
- List all projects in an organization.
331
-
332
- ```bash
333
- runhuman orgs projects org_abc123
334
- ```
335
-
336
- #### `orgs switch <organizationId>`
337
-
338
- Set the default organization for CLI commands.
339
-
340
- ```bash
341
- runhuman orgs switch org_abc123
342
- runhuman orgs switch org_abc123 --global # all directories (default)
343
- ```
344
-
345
- #### `orgs usage [organizationId]`
346
-
347
- Show usage analytics: total jobs, cost, per-project breakdown, over-time series.
348
-
349
- ```bash
350
- # Default: last 30 days
351
- runhuman orgs usage
352
-
353
- # Preset period
354
- runhuman orgs usage --period 7d
355
- runhuman orgs usage --period all
356
-
357
- # Specific month
358
- runhuman orgs usage --year 2026 --month 4
359
-
360
- # Pipe the full response into your own tool
361
- runhuman orgs usage --json | jq '.data.byHour'
362
- ```
363
-
364
- Default rendering shows the summary plus the top 5 projects by job count. `--json` returns the full response including `overTime`, `byHour`, and `bySource` arrays for scripting.
365
-
366
- **Options:**
367
- - `--period <window>` - `7d` | `30d` | `90d` | `all` (mutually exclusive with `--year/--month`)
368
- - `--year <y>` / `--month <m>` - Specific time window (month requires year)
369
- - `-j, --json` - Full response JSON
370
-
371
- #### `orgs invitations list|revoke`
372
-
373
- Manage pending invitations sent via `orgs invite`.
374
-
375
- ```bash
376
- # List pending invitations
377
- runhuman orgs invitations list --organization org_abc123
378
-
379
- # Revoke one
380
- runhuman orgs invitations revoke inv_xyz789 --organization org_abc123 --yes
381
- ```
382
-
383
- ### Projects
384
-
385
- #### `projects list`
386
-
387
- List all your projects.
388
-
389
- ```bash
390
- runhuman projects list
391
- runhuman projects ls # alias
392
- ```
393
-
394
- #### `projects create <name>`
395
-
396
- Create a new project in an organization.
397
-
398
- ```bash
399
- runhuman projects create "My App" --organization org_abc123
400
- runhuman projects create "My App" --organization org_abc123 --set-default
401
- ```
402
-
403
- **Options:**
404
- - `-o, --organization <id>` - Organization ID (required)
405
- - `--default-url <url>` - Default URL for tests
406
- - `--github-repo <owner/repo>` - Link GitHub repository
407
- - `--set-default` - Set as default project after creation
408
-
409
- #### `projects show <projectId>`
410
-
411
- Show project details including organization and balance.
412
-
413
- ```bash
414
- runhuman projects show proj_abc123
415
- runhuman projects info proj_abc123 # alias
416
- runhuman projects get proj_abc123 # alias
417
- ```
418
-
419
- #### `projects update <projectId>`
420
-
421
- Update project settings.
422
-
423
- ```bash
424
- runhuman projects update proj_abc123 --name "New Name"
425
- runhuman projects update proj_abc123 --default-url https://google.com
426
- ```
427
-
428
- **Options:**
429
- - `-n, --name <text>` - New project name
430
- - `-u, --default-url <url>` - New default URL
431
- - `-g, --github-repo <owner/repo>` - New GitHub repository
432
-
433
- #### `projects switch <projectId>`
434
-
435
- Set the default project for CLI commands.
436
-
437
- ```bash
438
- runhuman projects switch proj_abc123
439
- runhuman projects use proj_abc123 # alias
440
- ```
441
-
442
- **Options:**
443
- - `-g, --global` - Set as global default instead of local (default: true)
444
-
445
- #### `projects transfer <projectId>`
446
-
447
- Transfer a project to another organization.
448
-
449
- ```bash
450
- runhuman projects transfer proj_abc123 --to-org org_target123
451
- ```
452
-
453
- **Options:**
454
- - `--to-org <organizationId>` - Target organization ID (required, full ID required)
455
- - `-f, --force` - Skip confirmation prompt
456
-
457
- #### `projects delete <projectId>`
458
-
459
- Delete a project. Requires the full project ID.
460
-
461
- ```bash
462
- runhuman projects delete proj_abc123 --force
463
- ```
464
-
465
- **Options:**
466
- - `-f, --force` - Skip confirmation prompt
467
-
468
- ### Transfers
469
-
470
- #### `transfers list`
471
-
472
- List pending and outgoing project transfers.
473
-
474
- ```bash
475
- runhuman transfers list
476
- runhuman transfers ls # alias
477
- ```
478
-
479
- #### `transfers accept <transferId>`
480
-
481
- Accept an incoming transfer.
482
-
483
- ```bash
484
- runhuman transfers accept xfer_abc123
485
- ```
486
-
487
- #### `transfers reject <transferId>`
488
-
489
- Reject an incoming transfer.
490
-
491
- ```bash
492
- runhuman transfers reject xfer_abc123
493
- ```
494
-
495
- #### `transfers cancel <transferId>`
496
-
497
- Cancel an outgoing transfer you initiated.
498
-
499
- ```bash
500
- runhuman transfers cancel xfer_abc123
501
- ```
502
-
503
- ### API Keys
504
-
505
- #### `keys list`
506
-
507
- List all API keys for an organization.
508
-
509
- ```bash
510
- runhuman keys list --organization org_abc123
511
- runhuman keys ls --organization org_abc123 # alias
512
- runhuman keys list --organization org_abc123 --show-keys
513
- ```
514
-
515
- **Options:**
516
- - `-o, --organization <id>` - Organization ID (required)
517
- - `--show-keys` - Show full API keys (default: masked)
518
- - `-j, --json` - Output as JSON
519
-
520
- #### `keys create <name>`
521
-
522
- Create a new API key for an organization.
523
-
524
- ```bash
525
- runhuman keys create "CI/CD Key" --organization org_abc123
526
- runhuman keys new "CI/CD Key" --organization org_abc123 # alias
527
- ```
528
-
529
- **Options:**
530
- - `-o, --organization <id>` - Organization ID (required)
531
-
532
- #### `keys show <keyId>`
533
-
534
- Show details of a specific API key.
535
-
536
- ```bash
537
- runhuman keys show key_abc123
538
- runhuman keys show key_abc123 --show-key
539
- ```
540
-
541
- **Options:**
542
- - `--show-key` - Show full API key (default: masked)
543
-
544
- #### `keys delete <keyId>`
545
-
546
- Delete an API key. Requires the full key ID.
547
-
548
- ```bash
549
- runhuman keys delete key_abc123 --force
550
- runhuman keys rm key_abc123 --force # alias
551
- runhuman keys revoke key_abc123 --force # alias
552
- ```
553
-
554
- **Options:**
555
- - `-f, --force` - Skip confirmation prompt
556
-
557
- ### Templates
558
-
559
- #### `templates list`
560
-
561
- List all templates for a project.
562
-
563
- ```bash
564
- runhuman templates list --project proj_abc123
565
- runhuman templates ls --project proj_abc123 # alias
566
- ```
567
-
568
- **Options:**
569
- - `-p, --project <id>` - Project ID (required, or use default from config)
570
-
571
- #### `templates create <name>`
572
-
573
- Create a new template.
574
-
575
- ```bash
576
- runhuman templates create "Search Flow Test" --project proj_abc123 \
577
- -d "Search for 'recursion' and confirm the joke appears" \
578
- --duration 180 \
579
- --device-class desktop \
580
- --schema ./schema.json
581
- ```
582
-
583
- **Options:**
584
- - `-p, --project <id>` - Project ID (required, or use default from config)
585
- - `-d, --description <text>` - Template description
586
- - `--duration <seconds>` - Target test duration in seconds
587
- - `--device-class <class>` - Default device class (desktop/mobile)
588
- - `-S, --schema <path>` - Path to JSON schema file
589
-
590
- #### `templates show <templateId>`
591
-
592
- Show template details.
593
-
594
- ```bash
595
- runhuman templates show tmpl_abc123 --project proj_abc123
596
- ```
597
-
598
- #### `templates update <templateId>`
599
-
600
- Update a template.
601
-
602
- ```bash
603
- runhuman templates update tmpl_abc123 --project proj_abc123 --name "New Name"
604
- ```
605
-
606
- **Options:**
607
- - `-n, --name <name>` - New template name
608
- - `-d, --description <text>` - New description
609
- - `--duration <seconds>` - New target duration
610
- - `--device-class <class>` - New default device class
611
- - `-S, --schema <path>` - Path to new JSON schema file
612
-
613
- #### `templates delete <templateId>`
614
-
615
- Delete a template.
616
-
617
- ```bash
618
- runhuman templates delete tmpl_abc123 --project proj_abc123 --force
619
- ```
620
-
621
- **Options:**
622
- - `-f, --force` - Skip confirmation prompt
623
-
624
- ### GitHub Integration
625
-
626
- #### `github link <repo>`
627
-
628
- Link a GitHub repository to your project.
629
-
630
- ```bash
631
- runhuman github link owner/repo --project proj_abc123
632
- ```
633
-
634
- **Options:**
635
- - `-p, --project <id>` - Project ID (required)
636
-
637
- #### `github repos`
638
-
639
- List GitHub repositories accessible to an organization.
640
-
641
- ```bash
642
- runhuman github repos --organization org_abc123
643
- runhuman github repos --organization org_abc123 --search "my-app"
644
- ```
645
-
646
- **Options:**
647
- - `-o, --organization <id>` - Organization ID (required)
648
- - `-s, --search <query>` - Filter by repository name
649
-
650
- #### `github issues <repo>`
651
-
652
- List GitHub issues for a repository.
653
-
654
- ```bash
655
- runhuman github issues owner/repo
656
- runhuman github issues owner/repo --state open
657
- runhuman github issues owner/repo --labels "bug,needs-qa"
658
- ```
659
-
660
- **Options:**
661
- - `-s, --state <state>` - Filter by state (open/closed/all, default: open)
662
- - `-l, --labels <labels>` - Filter by comma-separated labels
663
-
664
- #### `github test <issueNumber>`
665
-
666
- Create a QA test job for a GitHub issue.
667
-
668
- ```bash
669
- runhuman github test 123 -r owner/repo -u https://google.com
670
- runhuman github test 123 -u https://google.com --sync
671
- ```
672
-
673
- **Options:**
674
- - `-r, --repo <owner/repo>` - Repository (or use default from config)
675
- - `-u, --url <url>` - URL to test (required)
676
- - `-t, --template <id>` - Template ID to use
677
- - `-s, --sync` - Wait for result before exiting
678
-
679
- #### `github bulk-test`
680
-
681
- Create QA test jobs for multiple GitHub issues.
682
-
683
- ```bash
684
- runhuman github bulk-test -r owner/repo -u https://google.com
685
- runhuman github bulk-test -r owner/repo -u https://google.com \
686
- -l "bug,needs-qa" \
687
- -n 5
688
- ```
689
-
690
- **Options:**
691
- - `-r, --repo <owner/repo>` - Repository (or use default from config)
692
- - `-u, --url <url>` - URL to test (required)
693
- - `-l, --labels <labels>` - Filter issues by comma-separated labels
694
- - `-s, --state <state>` - Filter by state (open/closed/all, default: open)
695
- - `-t, --template <id>` - Template ID to use
696
- - `-n, --limit <number>` - Maximum number of jobs to create (default: 10)
697
-
698
- #### `github installation refresh`
699
-
700
- Force-refresh a GitHub App installation's repo/permissions list. Use this after granting the app access to new repos if they aren't visible yet.
701
-
702
- ```bash
703
- runhuman github installation refresh --installation 987654321 --organization org_abc123
704
- ```
705
-
706
- **Required options:**
707
- - `--installation <id>` - GitHub installation ID
708
-
709
- **Options:**
710
- - `-o, --organization <id>` - Organization ID (defaults to current org context)
711
-
712
- ### Billing
713
-
714
- User-scoped reads. Purchase flows and plan changes stay in the web UI — use `billing portal` to get there.
715
-
716
- #### `billing balance`
717
-
718
- Show credit balance for the authenticated user's primary organization (or override with `-o`).
719
-
720
- ```bash
721
- runhuman billing balance
722
- runhuman billing balance --organization org_abc123
723
- ```
724
-
725
- #### `billing subscription`
726
-
727
- Show the active subscription (tier, billing cycle, renewal date) plus any active add-ons.
728
-
729
- ```bash
730
- runhuman billing subscription
731
- ```
732
-
733
- #### `billing portal [--open]`
734
-
735
- Return a one-time URL to the Polar customer portal (payment method, invoices, cancellation).
736
-
737
- ```bash
738
- # Print the URL
739
- runhuman billing portal
740
-
741
- # Open it in the browser
742
- runhuman billing portal --open
743
- ```
744
-
745
- ### Authentication
746
-
747
- #### `login`
748
-
749
- Login to Runhuman. Opens your browser for OAuth by default.
750
-
751
- ```bash
752
- runhuman login
753
-
754
- # Login with API key (skip browser)
755
- runhuman login --token <your-api-key>
756
-
757
- # Print auth URL without opening browser
758
- runhuman login --no-browser
759
- ```
760
-
761
- #### `logout`
762
-
763
- Clear saved credentials.
764
-
765
- ```bash
766
- runhuman logout
767
- ```
768
-
769
- #### `whoami`
770
-
771
- Display current user info.
772
-
773
- ```bash
774
- runhuman whoami
775
- ```
776
-
777
- ### Configuration
778
-
779
- #### `config get <key>`
780
-
781
- Get a configuration value.
782
-
783
- ```bash
784
- runhuman config get apiUrl
785
- runhuman config get project
786
- ```
787
-
788
- #### `config set <key> <value>`
789
-
790
- Set a configuration value.
791
-
792
- ```bash
793
- runhuman config set project proj_abc123
794
- runhuman config set color false
795
- runhuman config set project proj_abc123 --global
796
- ```
797
-
798
- **Options:**
799
- - `--global` - Save to global config instead of project config
800
-
801
- #### `config list`
802
-
803
- List all configuration values.
804
-
805
- ```bash
806
- runhuman config list
807
- runhuman config list --show-secrets
808
- ```
809
-
810
- **Options:**
811
- - `--show-secrets` - Show API keys (default: masked)
812
-
813
- #### `config reset`
814
-
815
- Reset configuration to defaults.
816
-
817
- ```bash
818
- runhuman config reset --project --force
819
- runhuman config reset --global --force
820
- runhuman config reset --all --force
821
- ```
822
-
823
- #### `init`
824
-
825
- Initialize a new Runhuman project with interactive prompts.
826
-
827
- ```bash
828
- runhuman init
829
- runhuman init --name "My App" --url https://google.com --yes
830
- ```
831
-
832
- Creates a `.runhumanrc` file in the current directory.
833
-
834
- ## Configuration Hierarchy
835
-
836
- Configuration is loaded from multiple sources with the following priority (highest to lowest):
837
-
838
- 1. **CLI flags** - `--api-key`, `--project`, etc.
839
- 2. **Environment variables** - `RUNHUMAN_API_KEY`, `RUNHUMAN_API_URL`, etc.
840
- 3. **Project config** - `.runhumanrc` in current directory
841
- 4. **Global config** - `~/.config/runhuman/config.json`
842
- 5. **Defaults**
843
-
844
- ### Environment Variables
845
-
846
- ```bash
847
- RUNHUMAN_API_KEY # API key for authentication
848
- RUNHUMAN_API_URL # API base URL (default: https://runhuman.com)
849
- RUNHUMAN_PROJECT_ID # Default project ID
850
- RUNHUMAN_NO_COLOR=true # Disable colored output
851
- ```
852
-
853
- ## JSON Output
854
-
855
- All commands support `-j, --json` for machine-readable output:
856
-
857
- ```bash
858
- runhuman create https://google.com -d "Test search" --json
859
- runhuman status job_abc123 --json
860
- runhuman list --json
861
- ```
862
-
863
- ## Exit Codes
864
-
865
- - `0` - Success
866
- - `1` - General error / ambiguous ID / full ID required
867
- - `2` - Authentication error
868
- - `3` - Not found / no match for ID prefix
869
- - `4` - Validation error
870
- - `5` - Timeout error
871
-
872
- ## Examples
873
-
874
- ### Basic Workflow
875
-
876
- ```bash
877
- # 1. Login
878
- runhuman login
879
-
880
- # 2. Initialize project
881
- runhuman init
882
-
883
- # 3. Create a test
884
- runhuman create https://google.com \
885
- -d "Search for 'recursion' and confirm the tester experiences a joke about recursion"
886
-
887
- # 4. Wait for results (truncated ID)
888
- runhuman wait 712e
889
-
890
- # 5. View detailed results
891
- runhuman results 712e
892
- ```
893
-
894
- ### CI/CD Integration
895
-
896
- ```bash
897
- runhuman create https://staging.google.com \
898
- -d "Search for 'recursion' and confirm the joke appears" \
899
- --sync \
900
- --json > result.json
901
- ```
902
-
903
- ## How It Works
904
-
905
- 1. **You create a job** - Define test instructions and optional output schema
906
- 2. **Job posted to testers** - Request goes to human tester pool
907
- 3. **Human performs test** - Real person tests with video/screenshot recording
908
- 4. **AI extracts data** - AI processes feedback into structured JSON
909
- 5. **You get results** - Clean, typed data ready for automation
910
-
911
- **Pricing:** Pay-per-second ($0.0085/sec of tester time). No monthly fees, no minimums.
912
-
913
- ## Learn More
914
-
915
- - **Website:** [runhuman.com](https://runhuman.com)
916
- - **Documentation:** [runhuman.com/docs](https://runhuman.com/docs)
917
- - **GitHub:** [github.com/volter-ai/runhuman](https://github.com/volter-ai/runhuman)
918
-
919
- ## Support
920
-
921
- - **Email:** hey@runhuman.com
922
- - **Issues:** [GitHub Issues](https://github.com/volter-ai/runhuman/issues)
923
-
924
- ---
925
-
926
- **Built by the [Volter AI](https://volter.ai) team**
1
+ # runhuman
2
+
3
+ [![npm version](https://img.shields.io/npm/v/runhuman.svg)](https://www.npmjs.com/package/runhuman)
4
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
5
+
6
+ > AI-orchestrated human QA testing from your terminal
7
+
8
+ ## What is Runhuman?
9
+
10
+ Runhuman is an AI-orchestrated human QA testing service. Get real human testing of your web applications on-demand, with structured results extracted automatically.
11
+
12
+ **Perfect for:**
13
+ - AI coding agents that need human verification
14
+ - CI/CD pipelines with human QA gates
15
+ - Visual/UX testing requiring real human judgment
16
+ - On-demand QA without hiring/managing teams
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ # Install globally
22
+ npm install -g runhuman
23
+
24
+ # Or use with npx
25
+ npx runhuman --help
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ ```bash
31
+ # 1. Login (opens browser for OAuth)
32
+ runhuman login
33
+
34
+ # 2. Create your first test
35
+ runhuman job create https://google.com \
36
+ -d "Search for 'recursion' and confirm the tester experiences a joke about recursion"
37
+
38
+ # 3. Check the status
39
+ runhuman job status job_abc123
40
+
41
+ # 4. Get results
42
+ runhuman job results job_abc123
43
+ ```
44
+
45
+ Job commands live under the `runhuman job` namespace. The flat shims (`runhuman create`, `runhuman status`, `runhuman wait`, `runhuman results`, `runhuman list`, `runhuman watch`) still work but are deprecated and emit a one-line warning on use; new scripts should use the `job` form.
46
+
47
+ ## Truncated IDs
48
+
49
+ All commands accept truncated ID prefixes, similar to git short hashes. Instead of typing a full ID, you can use just the first few characters:
50
+
51
+ ```bash
52
+ # Full ID
53
+ runhuman job status 712e42ad-8f3b-4a1c-9d5e-1234567890ab
54
+
55
+ # Truncated — resolves to the same job
56
+ runhuman job status 712e
57
+
58
+ # Hyphens are ignored during matching
59
+ runhuman job status 712e42ad8f3b
60
+ ```
61
+
62
+ If a prefix matches multiple resources, you'll be prompted to provide more characters. Matching is case-insensitive and hyphen-insensitive.
63
+
64
+ **Destructive operations** (`projects delete`, `keys delete`, `projects transfer --to-org`) require the full ID to prevent accidental mismatches.
65
+
66
+ ## Global Flags
67
+
68
+ Every command accepts the same four global flags:
69
+
70
+ - `-j, --json` — emit machine-readable JSON to stdout (otherwise pretty-printed output)
71
+ - `-q, --quiet` — suppress success and info messages (stderr deprecation/error output is preserved)
72
+ - `-y, --yes` — skip confirmation prompts on destructive operations
73
+ - `--no-color` disable ANSI color codes (also honored from `RUNHUMAN_NO_COLOR=1`)
74
+
75
+ **`-f, --force` is reserved for override-a-guard semantics**, not confirmation-skip. Today it only appears on `templates create`, where it means "overwrite an existing template with the same name."
76
+
77
+ ### Output modes
78
+
79
+ `-j, --json` is the single output-mode flag. The CLI does not offer a `-o, --output` / `--format` choice à la kubectl pretty output for humans and JSON for scripts are the two supported shapes. Any future structured-text formats (YAML, CSV, etc.) would be added as their own flags rather than via a format matrix.
80
+
81
+ This also means `-o` remains bound to `--organization` on every command that has one, matching the noun-first mental model the rest of the CLI uses.
82
+
83
+ ### JSON envelope
84
+
85
+ Every command that emits JSON uses the same envelope:
86
+
87
+ ```jsonc
88
+ // Success
89
+ {
90
+ "success": true,
91
+ "data": <payload>, // see below
92
+ "pagination": { // only on list commands
93
+ "total": 42,
94
+ "limit": 20,
95
+ "offset": 0,
96
+ "hasMore": true
97
+ },
98
+ "warnings": ["..."], // optional, non-fatal server-side warnings
99
+ "timestamp": "2026-04-24T12:34:56.789Z"
100
+ }
101
+
102
+ // Failure
103
+ {
104
+ "success": false,
105
+ "error": {
106
+ "message": "...",
107
+ "code": "OPTIONAL_ERROR_CODE",
108
+ "details": { /* shape varies */ }
109
+ },
110
+ "timestamp": "2026-04-24T12:34:56.789Z"
111
+ }
112
+ ```
113
+
114
+ Payload conventions:
115
+
116
+ - **List commands** (`projects list`, `jobs list`, `orgs list`, etc.) put their items under `data.items` and their pagination on the envelope. Never `data.jobs` or `data.projects` always `data.items`.
117
+ - **Show / create / update commands** put the entity directly as `data` (e.g. `data: { id, name, ... }`).
118
+ - **Delete / archive / cancel commands** return a structured action payload such as `data: { id, deleted: true }`, `data: { id, archived: true }`, `data: { id, cancelled: true }`. The envelope already carries `success: true`; `data` never echoes it.
119
+
120
+ A generic script can parse any CLI command's output without inspecting which command was run:
121
+
122
+ ```bash
123
+ runhuman projects list --json | jq '.data.items[].id'
124
+ runhuman projects show <id> --json | jq '.data.id'
125
+ runhuman projects delete <id> --json | jq '.data.deleted'
126
+ ```
127
+
128
+ ## Commands
129
+
130
+ ### Jobs
131
+
132
+ All job commands live under the `runhuman job` namespace. Flat shims (`runhuman create`, `runhuman status`, `runhuman wait`, `runhuman results`, `runhuman list`, `runhuman watch`) still resolve but emit a deprecation warning.
133
+
134
+ #### `job create [url]`
135
+
136
+ Create a new QA test job.
137
+
138
+ ```bash
139
+ # Basic usage
140
+ runhuman job create https://google.com \
141
+ -d "Search for 'recursion' and confirm the tester experiences a joke about recursion"
142
+
143
+ # With template
144
+ runhuman job create https://google.com --template tmpl_abc123
145
+
146
+ # Synchronous (wait for result)
147
+ runhuman job create https://google.com -d "Test search" --sync
148
+
149
+ # With custom schema
150
+ runhuman job create https://google.com -d "Test search" --schema ./schema.json
151
+
152
+ # With tester pool requirements
153
+ runhuman job create https://google.com -d "Test mobile layout" \
154
+ --required-devices ios,android \
155
+ --required-languages english
156
+ ```
157
+
158
+ **Options:**
159
+ - `-d, --description <text>` - Test instructions for the human tester
160
+ - `-t, --template <name>` - Use a pre-defined template
161
+ - `--duration <minutes>` - Target duration (1-60 minutes)
162
+ - `--device-class <class>` - Device class: desktop, mobile, or both (default: both)
163
+ - `-S, --schema <file>` - Path to JSON schema for structured output
164
+ - `--schema-inline <json>` - Inline JSON schema string
165
+ - `--metadata <json>` - Metadata for tracking (JSON string)
166
+ - `--github-repo <owner/repo>` - GitHub repo for context
167
+ - `--required-devices <devices>` - Required tester devices (comma-separated: ios, android, pc, mac)
168
+ - `--required-languages <languages>` - Required tester languages (comma-separated: english, spanish)
169
+ - `--require-social-videos` - Require tester capable of recording social-media-style videos (Max+ tier)
170
+ - `-s, --sync` - Wait for result before exiting
171
+ - `--wait <seconds>` - Max wait time in sync mode (default: 300)
172
+ - `-p, --project <id>` - Project ID (or use default from config)
173
+ - `-j, --json` - Output as JSON
174
+ - `-q, --quiet` - Minimal output (only job ID)
175
+
176
+ #### `job status <jobId>`
177
+
178
+ Check the status of a test job. Aliases: `show`, `get`, `info`.
179
+
180
+ ```bash
181
+ runhuman job status job_abc123
182
+ runhuman job status 712e # truncated ID works
183
+ ```
184
+
185
+ #### `job wait <jobId>`
186
+
187
+ Wait for a job to complete with live status updates.
188
+
189
+ ```bash
190
+ runhuman job wait job_abc123
191
+ runhuman job wait job_abc123 --timeout 300
192
+ ```
193
+
194
+ **Options:**
195
+ - `--timeout <seconds>` - Maximum wait time (default: 600)
196
+ - `-j, --json` - Output as JSON
197
+
198
+ #### `job results <jobId>`
199
+
200
+ Display detailed test results, with optional rich-data sections.
201
+
202
+ ```bash
203
+ runhuman job results job_abc123
204
+ runhuman job results job_abc123 --json
205
+ runhuman job results job_abc123 --schema-only # Only extracted schema data
206
+ runhuman job results job_abc123 --raw # Raw tester response
207
+ runhuman job results job_abc123 --transcript --console-logs
208
+ runhuman job results job_abc123 --all # Every rich section
209
+ ```
210
+
211
+ **Options:**
212
+ - `--schema-only` - Show only extracted schema data
213
+ - `--raw` - Show raw tester response without processing
214
+ - `--transcript` - Include the voice transcript
215
+ - `--console-logs` - Include captured console logs
216
+ - `--network` - Include captured network requests
217
+ - `--events` - Include user-interaction events
218
+ - `--key-moments` - Include key-moments timeline
219
+ - `--conversation` - Include the AI ↔ tester conversation
220
+ - `-a, --all` - Include every rich-data section above
221
+ - `-j, --json` - Output as JSON
222
+
223
+ Rich-data sections (transcript, logs, network, events, key moments, conversation) are paid-tier gated server-side.
224
+
225
+ #### `job list [filter]`
226
+
227
+ List all your test jobs with optional status filtering. The `[filter]` matches the chip labels shown on the web Jobs page.
228
+
229
+ ```bash
230
+ # List all jobs
231
+ runhuman job list
232
+
233
+ # Filter by status (positional argument, case-insensitive)
234
+ runhuman job list Completed
235
+ runhuman job list pending
236
+
237
+ # Filter by multiple labels at once
238
+ runhuman job list "Pending,Working,Completed"
239
+
240
+ # Filter by project, or scope to an entire org
241
+ runhuman job list --project proj_abc123
242
+ runhuman job list --org org_abc123
243
+
244
+ # Pagination
245
+ runhuman job list --limit 20 --offset 40
246
+ ```
247
+
248
+ **Arguments:**
249
+ - `[filter]` - Chip label (comma-separated, case-insensitive): `all`, `Pending`, `Queued`, `Working`, `Completed`, `Cancelled`, `Expired`, `Failed`. Admins may pass fine-grain labels.
250
+
251
+ **Options:**
252
+ - `-p, --project <id>` - Filter by project
253
+ - `--org <id>` - Scope to all projects in an organization (mutually exclusive with `--project`)
254
+ - `-n, --limit <number>` - Maximum number of jobs (default: 20)
255
+ - `--offset <number>` - Pagination offset (default: 0)
256
+ - `-j, --json` - Output as JSON
257
+
258
+ #### `job artifact <jobId> <type>`
259
+
260
+ Download a raw session artifact. Useful for piping transcripts, console logs, or network data into your own tools.
261
+
262
+ ```bash
263
+ # Print the transcript
264
+ runhuman job artifact job_abc123 transcript
265
+
266
+ # Pipe raw console logs into jq
267
+ runhuman job artifact job_abc123 console-logs --json | jq '.data.consoleMessages[]'
268
+ ```
269
+
270
+ **Arguments:**
271
+ - `<jobId>` - Job ID
272
+ - `<type>` - One of: `structured-output`, `transcript`, `console-logs`, `network-requests`, `conversation`, `events`, `key-moments`
273
+
274
+ **Options:**
275
+ - `-j, --json` - Output as JSON (raw artifact shape wrapped in the standard envelope)
276
+
277
+ Rich artifacts are paid-tier gated server-side; ungated requests return a clean "subscription required" error.
278
+
279
+ #### `job share <jobId>` / `job unshare <jobId>`
280
+
281
+ Toggle public sharing for a job. `share` enables and prints the public URL; `unshare` disables.
282
+
283
+ ```bash
284
+ runhuman job share job_abc123
285
+ runhuman job unshare job_abc123
286
+ ```
287
+
288
+ #### `job create-issue <jobId> --index <n>`
289
+
290
+ File one extracted finding from a completed job as a GitHub issue. Mirrors the web UI's per-finding "Create Issue" button. Simple form only — the CLI submits the finding unedited; use the web UI or `gh issue edit` if you want to change title/body.
291
+
292
+ ```bash
293
+ # File the first extracted finding to the job's default GitHub repo
294
+ runhuman job create-issue job_abc123 --index 0
295
+
296
+ # Override the target repo
297
+ runhuman job create-issue job_abc123 --index 0 --repo owner/repo
298
+ ```
299
+
300
+ **Required options:**
301
+ - `--index <n>` - Zero-based index into `job.extractedIssues`
302
+
303
+ **Options:**
304
+ - `--repo <owner/repo>` - Override the job's default GitHub repo
305
+ - `-j, --json` - Output as JSON
306
+
307
+ #### `job delete <jobId>`
308
+
309
+ Delete a job (admin-only — customers cannot delete their own jobs; use the dashboard's archive flow to organize your job list).
310
+
311
+ ```bash
312
+ runhuman job delete job_abc123 --force
313
+ ```
314
+
315
+ **Options:**
316
+ - `-f, --force` - Skip confirmation prompt
317
+ - `-j, --json` - Output as JSON
318
+
319
+ There is no `job cancel` command; once a tester is engaged, jobs run through to a terminal state.
320
+
321
+ ### Organizations
322
+
323
+ #### `orgs list`
324
+
325
+ List all organizations you belong to.
326
+
327
+ ```bash
328
+ runhuman orgs list
329
+ runhuman orgs ls # alias
330
+ ```
331
+
332
+ #### `orgs show <organizationId>`
333
+
334
+ Show organization details.
335
+
336
+ ```bash
337
+ runhuman orgs show org_abc123
338
+ runhuman orgs info org_abc123 # alias
339
+ ```
340
+
341
+ #### `orgs balance <organizationId>`
342
+
343
+ Check billing balance.
344
+
345
+ ```bash
346
+ runhuman orgs balance org_abc123
347
+ ```
348
+
349
+ #### `orgs projects <organizationId>`
350
+
351
+ List all projects in an organization.
352
+
353
+ ```bash
354
+ runhuman orgs projects org_abc123
355
+ ```
356
+
357
+ #### `orgs switch <organizationId>`
358
+
359
+ Set the default organization for CLI commands.
360
+
361
+ ```bash
362
+ runhuman orgs switch org_abc123
363
+ runhuman orgs switch org_abc123 --global # all directories (default)
364
+ ```
365
+
366
+ #### `orgs usage [organizationId]`
367
+
368
+ Show usage analytics: total jobs, cost, per-project breakdown, over-time series.
369
+
370
+ ```bash
371
+ # Default: last 30 days
372
+ runhuman orgs usage
373
+
374
+ # Preset period
375
+ runhuman orgs usage --period 7d
376
+ runhuman orgs usage --period all
377
+
378
+ # Specific month
379
+ runhuman orgs usage --year 2026 --month 4
380
+
381
+ # Pipe the full response into your own tool
382
+ runhuman orgs usage --json | jq '.data.byHour'
383
+ ```
384
+
385
+ Default rendering shows the summary plus the top 5 projects by job count. `--json` returns the full response including `overTime`, `byHour`, and `bySource` arrays for scripting.
386
+
387
+ **Options:**
388
+ - `--period <window>` - `7d` | `30d` | `90d` | `all` (mutually exclusive with `--year/--month`)
389
+ - `--year <y>` / `--month <m>` - Specific time window (month requires year)
390
+ - `-j, --json` - Full response JSON
391
+
392
+ #### `orgs invitations list|revoke`
393
+
394
+ Manage pending invitations sent via `orgs invite`.
395
+
396
+ ```bash
397
+ # List pending invitations
398
+ runhuman orgs invitations list --organization org_abc123
399
+
400
+ # Revoke one
401
+ runhuman orgs invitations revoke inv_xyz789 --organization org_abc123 --yes
402
+ ```
403
+
404
+ ### Projects
405
+
406
+ #### `projects list`
407
+
408
+ List all your projects.
409
+
410
+ ```bash
411
+ runhuman projects list
412
+ runhuman projects ls # alias
413
+ ```
414
+
415
+ #### `projects create <name>`
416
+
417
+ Create a new project in an organization.
418
+
419
+ ```bash
420
+ runhuman projects create "My App" --organization org_abc123
421
+ runhuman projects create "My App" --organization org_abc123 --set-default
422
+ ```
423
+
424
+ **Options:**
425
+ - `-o, --organization <id>` - Organization ID (required)
426
+ - `--default-url <url>` - Default URL for tests
427
+ - `--github-repo <owner/repo>` - Link GitHub repository
428
+ - `--set-default` - Set as default project after creation
429
+
430
+ #### `projects show <projectId>`
431
+
432
+ Show project details including organization and balance.
433
+
434
+ ```bash
435
+ runhuman projects show proj_abc123
436
+ runhuman projects info proj_abc123 # alias
437
+ runhuman projects get proj_abc123 # alias
438
+ ```
439
+
440
+ #### `projects update <projectId>`
441
+
442
+ Update project settings.
443
+
444
+ ```bash
445
+ runhuman projects update proj_abc123 --name "New Name"
446
+ runhuman projects update proj_abc123 --default-url https://google.com
447
+ ```
448
+
449
+ **Options:**
450
+ - `-n, --name <text>` - New project name
451
+ - `-u, --default-url <url>` - New default URL
452
+ - `-g, --github-repo <owner/repo>` - New GitHub repository
453
+
454
+ #### `projects switch <projectId>`
455
+
456
+ Set the default project for CLI commands.
457
+
458
+ ```bash
459
+ runhuman projects switch proj_abc123
460
+ runhuman projects use proj_abc123 # alias
461
+ ```
462
+
463
+ **Options:**
464
+ - `-g, --global` - Set as global default instead of local (default: true)
465
+
466
+ #### `projects transfer <projectId>`
467
+
468
+ Transfer a project to another organization.
469
+
470
+ ```bash
471
+ runhuman projects transfer proj_abc123 --to-org org_target123
472
+ ```
473
+
474
+ **Options:**
475
+ - `--to-org <organizationId>` - Target organization ID (required, full ID required)
476
+ - `-f, --force` - Skip confirmation prompt
477
+
478
+ #### `projects delete <projectId>`
479
+
480
+ Delete a project. Requires the full project ID.
481
+
482
+ ```bash
483
+ runhuman projects delete proj_abc123 --force
484
+ ```
485
+
486
+ **Options:**
487
+ - `-f, --force` - Skip confirmation prompt
488
+
489
+ ### Transfers
490
+
491
+ #### `transfers list`
492
+
493
+ List pending and outgoing project transfers.
494
+
495
+ ```bash
496
+ runhuman transfers list
497
+ runhuman transfers ls # alias
498
+ ```
499
+
500
+ #### `transfers accept <transferId>`
501
+
502
+ Accept an incoming transfer.
503
+
504
+ ```bash
505
+ runhuman transfers accept xfer_abc123
506
+ ```
507
+
508
+ #### `transfers reject <transferId>`
509
+
510
+ Reject an incoming transfer.
511
+
512
+ ```bash
513
+ runhuman transfers reject xfer_abc123
514
+ ```
515
+
516
+ #### `transfers cancel <transferId>`
517
+
518
+ Cancel an outgoing transfer you initiated.
519
+
520
+ ```bash
521
+ runhuman transfers cancel xfer_abc123
522
+ ```
523
+
524
+ ### API Keys
525
+
526
+ #### `keys list`
527
+
528
+ List all API keys for an organization.
529
+
530
+ ```bash
531
+ runhuman keys list --organization org_abc123
532
+ runhuman keys ls --organization org_abc123 # alias
533
+ runhuman keys list --organization org_abc123 --show-keys
534
+ ```
535
+
536
+ **Options:**
537
+ - `-o, --organization <id>` - Organization ID (required)
538
+ - `--show-keys` - Show full API keys (default: masked)
539
+ - `-j, --json` - Output as JSON
540
+
541
+ #### `keys create <name>`
542
+
543
+ Create a new API key for an organization.
544
+
545
+ ```bash
546
+ runhuman keys create "CI/CD Key" --organization org_abc123
547
+ runhuman keys new "CI/CD Key" --organization org_abc123 # alias
548
+ ```
549
+
550
+ **Options:**
551
+ - `-o, --organization <id>` - Organization ID (required)
552
+
553
+ #### `keys show <keyId>`
554
+
555
+ Show details of a specific API key.
556
+
557
+ ```bash
558
+ runhuman keys show key_abc123
559
+ runhuman keys show key_abc123 --show-key
560
+ ```
561
+
562
+ **Options:**
563
+ - `--show-key` - Show full API key (default: masked)
564
+
565
+ #### `keys delete <keyId>`
566
+
567
+ Delete an API key. Requires the full key ID.
568
+
569
+ ```bash
570
+ runhuman keys delete key_abc123 --force
571
+ runhuman keys rm key_abc123 --force # alias
572
+ runhuman keys revoke key_abc123 --force # alias
573
+ ```
574
+
575
+ **Options:**
576
+ - `-f, --force` - Skip confirmation prompt
577
+
578
+ ### Templates
579
+
580
+ #### `templates list`
581
+
582
+ List all templates for a project.
583
+
584
+ ```bash
585
+ runhuman templates list --project proj_abc123
586
+ runhuman templates ls --project proj_abc123 # alias
587
+ ```
588
+
589
+ **Options:**
590
+ - `-p, --project <id>` - Project ID (required, or use default from config)
591
+
592
+ #### `templates create <name>`
593
+
594
+ Create a new template.
595
+
596
+ ```bash
597
+ runhuman templates create "Search Flow Test" --project proj_abc123 \
598
+ -d "Search for 'recursion' and confirm the joke appears" \
599
+ --duration 180 \
600
+ --device-class desktop \
601
+ --schema ./schema.json
602
+ ```
603
+
604
+ **Options:**
605
+ - `-p, --project <id>` - Project ID (required, or use default from config)
606
+ - `-d, --description <text>` - Template description
607
+ - `--duration <seconds>` - Target test duration in seconds
608
+ - `--device-class <class>` - Default device class (desktop/mobile/both)
609
+ - `-S, --schema <path>` - Path to JSON schema file
610
+
611
+ #### `templates show <templateId>`
612
+
613
+ Show template details.
614
+
615
+ ```bash
616
+ runhuman templates show tmpl_abc123 --project proj_abc123
617
+ ```
618
+
619
+ #### `templates update <templateId>`
620
+
621
+ Update a template.
622
+
623
+ ```bash
624
+ runhuman templates update tmpl_abc123 --project proj_abc123 --name "New Name"
625
+ ```
626
+
627
+ **Options:**
628
+ - `-n, --name <name>` - New template name
629
+ - `-d, --description <text>` - New description
630
+ - `--duration <seconds>` - New target duration
631
+ - `--device-class <class>` - New default device class
632
+ - `-S, --schema <path>` - Path to new JSON schema file
633
+
634
+ #### `templates delete <templateId>`
635
+
636
+ Delete a template.
637
+
638
+ ```bash
639
+ runhuman templates delete tmpl_abc123 --project proj_abc123 --force
640
+ ```
641
+
642
+ **Options:**
643
+ - `-f, --force` - Skip confirmation prompt
644
+
645
+ ### GitHub Integration
646
+
647
+ #### `github link <repo>`
648
+
649
+ Link a GitHub repository to your project.
650
+
651
+ ```bash
652
+ runhuman github link owner/repo --project proj_abc123
653
+ ```
654
+
655
+ **Options:**
656
+ - `-p, --project <id>` - Project ID (required)
657
+
658
+ #### `github repos`
659
+
660
+ List GitHub repositories accessible to an organization.
661
+
662
+ ```bash
663
+ runhuman github repos --organization org_abc123
664
+ runhuman github repos --organization org_abc123 --search "my-app"
665
+ ```
666
+
667
+ **Options:**
668
+ - `-o, --organization <id>` - Organization ID (required)
669
+ - `-s, --search <query>` - Filter by repository name
670
+
671
+ #### `github issues <repo>`
672
+
673
+ List GitHub issues for a repository.
674
+
675
+ ```bash
676
+ runhuman github issues owner/repo
677
+ runhuman github issues owner/repo --state open
678
+ runhuman github issues owner/repo --labels "bug,needs-qa"
679
+ ```
680
+
681
+ **Options:**
682
+ - `-s, --state <state>` - Filter by state (open/closed/all, default: open)
683
+ - `-l, --labels <labels>` - Filter by comma-separated labels
684
+
685
+ #### `github test <issueNumber>`
686
+
687
+ Create a QA test job for a GitHub issue.
688
+
689
+ ```bash
690
+ runhuman github test 123 -r owner/repo -u https://google.com
691
+ runhuman github test 123 -u https://google.com --sync
692
+ ```
693
+
694
+ **Options:**
695
+ - `-r, --repo <owner/repo>` - Repository (or use default from config)
696
+ - `-u, --url <url>` - URL to test (required)
697
+ - `-t, --template <id>` - Template ID to use
698
+ - `-s, --sync` - Wait for result before exiting
699
+
700
+ #### `github bulk-test`
701
+
702
+ Create QA test jobs for multiple GitHub issues.
703
+
704
+ ```bash
705
+ runhuman github bulk-test -r owner/repo -u https://google.com
706
+ runhuman github bulk-test -r owner/repo -u https://google.com \
707
+ -l "bug,needs-qa" \
708
+ -n 5
709
+ ```
710
+
711
+ **Options:**
712
+ - `-r, --repo <owner/repo>` - Repository (or use default from config)
713
+ - `-u, --url <url>` - URL to test (required)
714
+ - `-l, --labels <labels>` - Filter issues by comma-separated labels
715
+ - `-s, --state <state>` - Filter by state (open/closed/all, default: open)
716
+ - `-t, --template <id>` - Template ID to use
717
+ - `-n, --limit <number>` - Maximum number of jobs to create (default: 10)
718
+
719
+ #### `github installation refresh`
720
+
721
+ Force-refresh a GitHub App installation's repo/permissions list. Use this after granting the app access to new repos if they aren't visible yet.
722
+
723
+ ```bash
724
+ runhuman github installation refresh --installation 987654321 --organization org_abc123
725
+ ```
726
+
727
+ **Required options:**
728
+ - `--installation <id>` - GitHub installation ID
729
+
730
+ **Options:**
731
+ - `-o, --organization <id>` - Organization ID (defaults to current org context)
732
+
733
+ ### Billing
734
+
735
+ User-scoped reads. Purchase flows and plan changes stay in the web UI — use `billing portal` to get there.
736
+
737
+ #### `billing balance`
738
+
739
+ Show credit balance for the authenticated user's primary organization (or override with `-o`).
740
+
741
+ ```bash
742
+ runhuman billing balance
743
+ runhuman billing balance --organization org_abc123
744
+ ```
745
+
746
+ #### `billing subscription`
747
+
748
+ Show the active subscription (tier, billing cycle, renewal date) plus any active add-ons.
749
+
750
+ ```bash
751
+ runhuman billing subscription
752
+ ```
753
+
754
+ #### `billing portal [--open]`
755
+
756
+ Return a one-time URL to the Polar customer portal (payment method, invoices, cancellation).
757
+
758
+ ```bash
759
+ # Print the URL
760
+ runhuman billing portal
761
+
762
+ # Open it in the browser
763
+ runhuman billing portal --open
764
+ ```
765
+
766
+ ### Authentication
767
+
768
+ #### `login`
769
+
770
+ Login to Runhuman. Opens your browser for OAuth by default.
771
+
772
+ ```bash
773
+ runhuman login
774
+
775
+ # Login with API key (skip browser)
776
+ runhuman login --token <your-api-key>
777
+
778
+ # Print auth URL without opening browser
779
+ runhuman login --no-browser
780
+ ```
781
+
782
+ #### `logout`
783
+
784
+ Clear saved credentials.
785
+
786
+ ```bash
787
+ runhuman logout
788
+ ```
789
+
790
+ #### `whoami`
791
+
792
+ Display current user info.
793
+
794
+ ```bash
795
+ runhuman whoami
796
+ ```
797
+
798
+ ### Configuration
799
+
800
+ #### `config get <key>`
801
+
802
+ Get a configuration value.
803
+
804
+ ```bash
805
+ runhuman config get apiUrl
806
+ runhuman config get project
807
+ ```
808
+
809
+ #### `config set <key> <value>`
810
+
811
+ Set a configuration value.
812
+
813
+ ```bash
814
+ runhuman config set project proj_abc123
815
+ runhuman config set color false
816
+ runhuman config set project proj_abc123 --global
817
+ ```
818
+
819
+ **Options:**
820
+ - `--global` - Save to global config instead of project config
821
+
822
+ #### `config list`
823
+
824
+ List all configuration values.
825
+
826
+ ```bash
827
+ runhuman config list
828
+ runhuman config list --show-secrets
829
+ ```
830
+
831
+ **Options:**
832
+ - `--show-secrets` - Show API keys (default: masked)
833
+
834
+ #### `config reset`
835
+
836
+ Reset configuration to defaults.
837
+
838
+ ```bash
839
+ runhuman config reset --project --force
840
+ runhuman config reset --global --force
841
+ runhuman config reset --all --force
842
+ ```
843
+
844
+ #### `init`
845
+
846
+ Initialize a new Runhuman project with interactive prompts.
847
+
848
+ ```bash
849
+ runhuman init
850
+ runhuman init --name "My App" --url https://google.com --yes
851
+ ```
852
+
853
+ Creates a `.runhumanrc` file in the current directory.
854
+
855
+ ## Configuration Hierarchy
856
+
857
+ Configuration is loaded from multiple sources with the following priority (highest to lowest):
858
+
859
+ 1. **CLI flags** - `--api-key`, `--project`, etc.
860
+ 2. **Environment variables** - `RUNHUMAN_API_KEY`, `RUNHUMAN_API_URL`, etc.
861
+ 3. **Project config** - `.runhumanrc` in current directory
862
+ 4. **Global config** - `~/.config/runhuman/config.json`
863
+ 5. **Defaults**
864
+
865
+ ### Environment Variables
866
+
867
+ ```bash
868
+ RUNHUMAN_API_KEY # API key for authentication
869
+ RUNHUMAN_API_URL # API base URL (default: https://runhuman.com)
870
+ RUNHUMAN_PROJECT_ID # Default project ID
871
+ RUNHUMAN_NO_COLOR=true # Disable colored output
872
+ ```
873
+
874
+ ## JSON Output
875
+
876
+ All commands support `-j, --json` for machine-readable output:
877
+
878
+ ```bash
879
+ runhuman job create https://google.com -d "Test search" --json
880
+ runhuman job status job_abc123 --json
881
+ runhuman job list --json
882
+ ```
883
+
884
+ ## Exit Codes
885
+
886
+ - `0` - Success
887
+ - `1` - General error / ambiguous ID / full ID required
888
+ - `2` - Authentication error
889
+ - `3` - Not found / no match for ID prefix
890
+ - `4` - Validation error
891
+ - `5` - Timeout error
892
+
893
+ ## Examples
894
+
895
+ ### Basic Workflow
896
+
897
+ ```bash
898
+ # 1. Login
899
+ runhuman login
900
+
901
+ # 2. Initialize project
902
+ runhuman init
903
+
904
+ # 3. Create a test
905
+ runhuman job create https://google.com \
906
+ -d "Search for 'recursion' and confirm the tester experiences a joke about recursion"
907
+
908
+ # 4. Wait for results (truncated ID)
909
+ runhuman job wait 712e
910
+
911
+ # 5. View detailed results
912
+ runhuman job results 712e
913
+ ```
914
+
915
+ ### CI/CD Integration
916
+
917
+ ```bash
918
+ runhuman job create https://staging.google.com \
919
+ -d "Search for 'recursion' and confirm the joke appears" \
920
+ --sync \
921
+ --json > result.json
922
+ ```
923
+
924
+ ## How It Works
925
+
926
+ 1. **You create a job** - Define test instructions and optional output schema
927
+ 2. **Job posted to testers** - Request goes to human tester pool
928
+ 3. **Human performs test** - Real person tests with video/screenshot recording
929
+ 4. **AI extracts data** - AI processes feedback into structured JSON
930
+ 5. **You get results** - Clean, typed data ready for automation
931
+
932
+ **Pricing:** Pay-per-second ($0.0085/sec of tester time). No monthly fees, no minimums.
933
+
934
+ ## Learn More
935
+
936
+ - **Website:** [runhuman.com](https://runhuman.com)
937
+ - **Documentation:** [runhuman.com/docs](https://runhuman.com/docs)
938
+ - **GitHub:** [github.com/volter-ai/runhuman](https://github.com/volter-ai/runhuman)
939
+
940
+ ## Support
941
+
942
+ - **Email:** hey@runhuman.com
943
+ - **Issues:** [GitHub Issues](https://github.com/volter-ai/runhuman/issues)
944
+
945
+ ---
946
+
947
+ **Built by the [Volter AI](https://volter.ai) team**