@questpie/probe 0.1.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.
- package/dist/agent-browser-Cxuu-Zz0.js +203 -0
- package/dist/assert-BLP5_JwC.js +212 -0
- package/dist/browser-DoCXU5Bs.js +736 -0
- package/dist/check-Cny-3lkZ.js +41 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +30 -0
- package/dist/codegen-BH3cUNuf.js +61 -0
- package/dist/compose-D5a8qHkg.js +233 -0
- package/dist/config-BUEMgFYN.js +89 -0
- package/dist/duration-D1ya1zLn.js +3 -0
- package/dist/duration-DUrbfMLK.js +30 -0
- package/dist/health-B36ufFzJ.js +62 -0
- package/dist/http-BZouO1Cj.js +187 -0
- package/dist/index.d.ts +119 -0
- package/dist/index.js +4 -0
- package/dist/init-BjTfn_-A.js +92 -0
- package/dist/logs-BCgur07G.js +191 -0
- package/dist/output-CHUjdVDf.js +38 -0
- package/dist/process-manager-CzexpFO4.js +229 -0
- package/dist/process-manager-zzltWvZ0.js +4 -0
- package/dist/ps-DuHF7vmE.js +39 -0
- package/dist/record-C4SmoPsT.js +140 -0
- package/dist/recordings-Cb31alos.js +158 -0
- package/dist/replay-Dg9PHNrg.js +171 -0
- package/dist/reporter-CqWc26OP.js +25 -0
- package/dist/restart-By3Edj5X.js +44 -0
- package/dist/snapshot-diff-CqXEVTAZ.js +51 -0
- package/dist/start-BClY6oJq.js +79 -0
- package/dist/state-DRTSIt_r.js +62 -0
- package/dist/stop-QAP6gbDe.js +47 -0
- package/package.json +72 -0
- package/skills/qprobe/SKILL.md +103 -0
- package/skills/qprobe/references/browser.md +201 -0
- package/skills/qprobe/references/compose.md +128 -0
- package/skills/qprobe/references/http.md +151 -0
- package/skills/qprobe/references/process.md +114 -0
- package/skills/qprobe/references/recording.md +194 -0
- package/skills/qprobe-browser/SKILL.md +87 -0
- package/skills/qprobe-compose/SKILL.md +81 -0
- package/skills/qprobe-http/SKILL.md +67 -0
- package/skills/qprobe-process/SKILL.md +58 -0
- package/skills/qprobe-recording/SKILL.md +63 -0
- package/skills/qprobe-ux/SKILL.md +250 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Browser Control Reference
|
|
2
|
+
|
|
3
|
+
Powered by `agent-browser` (default) or `playwright-cli` (optional). Uses accessibility tree snapshots with compact `@e` refs.
|
|
4
|
+
|
|
5
|
+
## Navigation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
qprobe browser open <url> # navigate (absolute or relative to baseUrl)
|
|
9
|
+
qprobe browser open /login # relative
|
|
10
|
+
qprobe browser back # browser back
|
|
11
|
+
qprobe browser forward # browser forward
|
|
12
|
+
qprobe browser reload # reload current page
|
|
13
|
+
qprobe browser url # print current URL
|
|
14
|
+
qprobe browser title # print page title
|
|
15
|
+
qprobe browser close # close browser
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Snapshot — How the Agent Sees the Page
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
qprobe browser snapshot [flags]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
| Flag | Short | Description |
|
|
25
|
+
|------|-------|-------------|
|
|
26
|
+
| `--interactive` | `-i` | Only interactive elements (buttons, inputs, links) |
|
|
27
|
+
| `--compact` | `-c` | Remove empty structural elements |
|
|
28
|
+
| `--depth <n>` | `-d` | Limit tree depth |
|
|
29
|
+
| `--selector <css>` | `-s` | Scope to CSS selector |
|
|
30
|
+
| `--diff` | | Show only changes since last snapshot |
|
|
31
|
+
|
|
32
|
+
### Output Example (-i -c)
|
|
33
|
+
```
|
|
34
|
+
- heading "Login" [@e1]
|
|
35
|
+
- textbox "Email" [@e2]
|
|
36
|
+
- textbox "Password" [@e3]
|
|
37
|
+
- button "Sign In" [@e4]
|
|
38
|
+
- link "Forgot password?" [@e5]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
~200-400 tokens for a typical page. Each element gets a stable ref like `@e1`.
|
|
42
|
+
|
|
43
|
+
### Diff Output (--diff)
|
|
44
|
+
```
|
|
45
|
+
URL: /login → /dashboard
|
|
46
|
+
REMOVED: textbox "Email" [@e2]
|
|
47
|
+
REMOVED: textbox "Password" [@e3]
|
|
48
|
+
REMOVED: button "Sign In" [@e4]
|
|
49
|
+
ADDED: heading "Dashboard" [@e6]
|
|
50
|
+
ADDED: button "Logout" [@e7]
|
|
51
|
+
ADDED: table (12 rows) [@e8]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Use `-i` by default.** Full snapshots include decorative elements that waste tokens. Add `-c` for even more compression. Use `--diff` after actions to see only what changed.
|
|
55
|
+
|
|
56
|
+
## Interaction
|
|
57
|
+
|
|
58
|
+
All interaction commands accept `@e` refs (from snapshot) or CSS selectors.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
qprobe browser click @e4 # click
|
|
62
|
+
qprobe browser dblclick @e4 # double-click
|
|
63
|
+
qprobe browser fill @e2 "admin@test.com" # clear + fill
|
|
64
|
+
qprobe browser type "hello" # type at current focus
|
|
65
|
+
qprobe browser select @e3 "option-value" # select dropdown
|
|
66
|
+
qprobe browser check @e5 # check checkbox
|
|
67
|
+
qprobe browser uncheck @e5 # uncheck
|
|
68
|
+
qprobe browser press Enter # keyboard key
|
|
69
|
+
qprobe browser press Tab
|
|
70
|
+
qprobe browser press Control+a
|
|
71
|
+
qprobe browser hover @e1 # hover
|
|
72
|
+
qprobe browser scroll down 500 # scroll pixels
|
|
73
|
+
qprobe browser scroll up
|
|
74
|
+
qprobe browser focus @e2 # focus element
|
|
75
|
+
qprobe browser upload @e6 ./file.pdf # file upload
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Console & Errors
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
qprobe browser console # all console messages
|
|
82
|
+
qprobe browser console --level error # only errors
|
|
83
|
+
qprobe browser console --level warn # warnings and above
|
|
84
|
+
qprobe browser console --clear # clear buffer
|
|
85
|
+
qprobe browser console --json # machine-readable
|
|
86
|
+
|
|
87
|
+
qprobe browser errors # uncaught JS exceptions only
|
|
88
|
+
qprobe browser errors --clear
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Output:
|
|
92
|
+
```
|
|
93
|
+
[error] TypeError: Cannot read property 'map' of undefined
|
|
94
|
+
at UserList (src/components/UserList.tsx:23:15)
|
|
95
|
+
[warn] Each child in a list should have a unique "key" prop
|
|
96
|
+
[log] API response: 200 OK
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Network
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
qprobe browser network # all HTTP requests
|
|
103
|
+
qprobe browser network --failed # only 4xx/5xx
|
|
104
|
+
qprobe browser network --method POST # filter by method
|
|
105
|
+
qprobe browser network --grep "api/" # filter by URL pattern
|
|
106
|
+
qprobe browser network --json # machine-readable
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Output:
|
|
110
|
+
```
|
|
111
|
+
200 GET /api/health 12ms
|
|
112
|
+
200 GET /api/users 89ms
|
|
113
|
+
201 POST /api/users 123ms
|
|
114
|
+
500 POST /api/orders 234ms ← FAILED
|
|
115
|
+
404 GET /api/nonexistent 8ms ← FAILED
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Screenshots
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
qprobe browser screenshot # save to tmp/qprobe/shots/
|
|
122
|
+
qprobe browser screenshot ./my-shot.png # custom path
|
|
123
|
+
qprobe browser screenshot --annotate # overlay @e ref labels
|
|
124
|
+
qprobe browser screenshot --full # full page scroll capture
|
|
125
|
+
qprobe browser screenshot --selector "#main" # capture specific element
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Annotated screenshots overlay numbered labels `[1] @e1`, `[2] @e2` on interactive elements — useful for multimodal AI models that can reason about visual layout.
|
|
129
|
+
|
|
130
|
+
## Waiting
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
qprobe browser wait @e1 # wait for element to exist
|
|
134
|
+
qprobe browser wait "#loading" --hidden # wait for element to disappear
|
|
135
|
+
qprobe browser wait --url "/dashboard" # wait for URL change
|
|
136
|
+
qprobe browser wait --text "Welcome" # wait for text to appear
|
|
137
|
+
qprobe browser wait --network idle # wait for no pending requests
|
|
138
|
+
qprobe browser wait --timeout 10s # custom timeout (default 30s)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## JavaScript Execution
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
qprobe browser eval "document.title"
|
|
145
|
+
# "My App - Dashboard"
|
|
146
|
+
|
|
147
|
+
qprobe browser eval "document.querySelectorAll('tr').length"
|
|
148
|
+
# 12
|
|
149
|
+
|
|
150
|
+
qprobe browser eval "localStorage.getItem('token')"
|
|
151
|
+
# "eyJhbG..."
|
|
152
|
+
|
|
153
|
+
qprobe browser text # extract all text content
|
|
154
|
+
qprobe browser text "#main" # text from specific element
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Common Patterns
|
|
158
|
+
|
|
159
|
+
### Login Flow
|
|
160
|
+
```bash
|
|
161
|
+
qprobe browser open /login
|
|
162
|
+
qprobe browser snapshot -i
|
|
163
|
+
qprobe browser fill @e1 "admin@test.com"
|
|
164
|
+
qprobe browser fill @e2 "password"
|
|
165
|
+
qprobe browser click @e3
|
|
166
|
+
qprobe browser wait --url "/dashboard"
|
|
167
|
+
qprobe browser snapshot --diff
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Check for Errors After Action
|
|
171
|
+
```bash
|
|
172
|
+
qprobe browser click @e5 # submit form
|
|
173
|
+
qprobe browser wait --network idle
|
|
174
|
+
qprobe browser console --level error # any JS errors?
|
|
175
|
+
qprobe browser network --failed # any failed requests?
|
|
176
|
+
qprobe browser snapshot --diff # what changed?
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Debug Why Page Looks Wrong
|
|
180
|
+
```bash
|
|
181
|
+
qprobe browser screenshot --annotate # see the visual state
|
|
182
|
+
qprobe browser console --level error # JS errors?
|
|
183
|
+
qprobe browser network --failed # failed API calls?
|
|
184
|
+
qprobe browser eval "document.querySelector('.error')?.textContent"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Driver Selection
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Default: agent-browser (token-efficient, Rust CLI, persistent daemon)
|
|
191
|
+
qprobe browser open /login
|
|
192
|
+
|
|
193
|
+
# Playwright: cross-browser, network interception, test codegen
|
|
194
|
+
qprobe browser open /login --driver playwright
|
|
195
|
+
qprobe browser open /login --driver playwright --browser firefox
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Set default in `qprobe.config.ts`:
|
|
199
|
+
```typescript
|
|
200
|
+
browser: { driver: 'agent-browser' } // or 'playwright'
|
|
201
|
+
```
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Compose Reference
|
|
2
|
+
|
|
3
|
+
## Commands
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
qprobe compose up [flags] # start all services in dependency order
|
|
7
|
+
qprobe compose down # stop all in reverse order
|
|
8
|
+
qprobe compose restart [name] # restart one or all
|
|
9
|
+
qprobe compose status # show all service states
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
| Flag | Description |
|
|
13
|
+
|------|-------------|
|
|
14
|
+
| `--only <name,...>` | Start only these services (+ their dependencies) |
|
|
15
|
+
| `--skip <name,...>` | Skip these services |
|
|
16
|
+
| `--no-health` | Don't wait for health checks |
|
|
17
|
+
| `--config <path>` | Custom config file path |
|
|
18
|
+
|
|
19
|
+
## Config File
|
|
20
|
+
|
|
21
|
+
`qprobe.config.ts` in project root:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { defineConfig } from '@questpie/probe'
|
|
25
|
+
|
|
26
|
+
export default defineConfig({
|
|
27
|
+
services: {
|
|
28
|
+
db: {
|
|
29
|
+
cmd: 'docker compose up postgres',
|
|
30
|
+
ready: 'ready to accept connections',
|
|
31
|
+
health: 'http://localhost:5432',
|
|
32
|
+
stop: 'docker compose down postgres', // custom stop command
|
|
33
|
+
},
|
|
34
|
+
server: {
|
|
35
|
+
cmd: 'bun dev',
|
|
36
|
+
ready: 'ready on http://localhost:3000',
|
|
37
|
+
port: 3000,
|
|
38
|
+
health: '/api/health', // relative to http://localhost:<port>
|
|
39
|
+
depends: ['db'],
|
|
40
|
+
env: {
|
|
41
|
+
DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/dev',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
admin: {
|
|
45
|
+
cmd: 'bun run admin:dev',
|
|
46
|
+
ready: 'ready on http://localhost:3001',
|
|
47
|
+
port: 3001,
|
|
48
|
+
depends: ['server'],
|
|
49
|
+
},
|
|
50
|
+
worker: {
|
|
51
|
+
cmd: 'bun run jobs',
|
|
52
|
+
ready: 'worker started',
|
|
53
|
+
depends: ['db'],
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
browser: {
|
|
57
|
+
driver: 'agent-browser',
|
|
58
|
+
baseUrl: 'http://localhost:3000',
|
|
59
|
+
},
|
|
60
|
+
http: {
|
|
61
|
+
baseUrl: 'http://localhost:3000',
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Dependency Resolution
|
|
67
|
+
|
|
68
|
+
`qprobe compose up` resolves the dependency graph and starts in order:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Given: server depends on db, admin depends on server, worker depends on db
|
|
72
|
+
|
|
73
|
+
Start order:
|
|
74
|
+
1. db (no dependencies)
|
|
75
|
+
2. server + worker (both depend on db, start in parallel)
|
|
76
|
+
3. admin (depends on server)
|
|
77
|
+
|
|
78
|
+
Stop order (reverse):
|
|
79
|
+
1. admin
|
|
80
|
+
2. server + worker
|
|
81
|
+
3. db
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Examples
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Start everything
|
|
88
|
+
qprobe compose up
|
|
89
|
+
# ⏳ Starting db... ready (2.3s)
|
|
90
|
+
# ⏳ Starting server... ready (4.1s)
|
|
91
|
+
# ⏳ Starting worker... ready (1.2s)
|
|
92
|
+
# ⏳ Starting admin... ready (3.5s)
|
|
93
|
+
# ✅ All 4 services ready (11.1s)
|
|
94
|
+
|
|
95
|
+
# Start only server (auto-starts db dependency)
|
|
96
|
+
qprobe compose up --only server
|
|
97
|
+
# ⏳ Starting db... ready (2.3s)
|
|
98
|
+
# ⏳ Starting server... ready (4.1s)
|
|
99
|
+
# ✅ 2 services ready (6.4s)
|
|
100
|
+
|
|
101
|
+
# Skip admin
|
|
102
|
+
qprobe compose up --skip admin
|
|
103
|
+
|
|
104
|
+
# Stop everything
|
|
105
|
+
qprobe compose down
|
|
106
|
+
# ⏳ Stopping admin... stopped
|
|
107
|
+
# ⏳ Stopping server... stopped
|
|
108
|
+
# ⏳ Stopping worker... stopped
|
|
109
|
+
# ⏳ Stopping db... stopped
|
|
110
|
+
# ✅ All services stopped
|
|
111
|
+
|
|
112
|
+
# Restart just the server
|
|
113
|
+
qprobe compose restart server
|
|
114
|
+
|
|
115
|
+
# Check status
|
|
116
|
+
qprobe compose status
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Inline Compose (No Config File)
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
qprobe compose up \
|
|
123
|
+
--service "db: docker compose up postgres | ready to accept" \
|
|
124
|
+
--service "server: bun dev | ready on http://localhost:3000" \
|
|
125
|
+
--depends "server:db"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Format: `--service "name: command | ready-pattern"`
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# HTTP Requests Reference
|
|
2
|
+
|
|
3
|
+
## Basic Usage
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
qprobe http <METHOD> <path> [flags]
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Path is relative to baseUrl (from config, `--base`, or auto-detected from running services).
|
|
10
|
+
|
|
11
|
+
| Flag | Short | Description |
|
|
12
|
+
|------|-------|-------------|
|
|
13
|
+
| `--base <url>` | | Override base URL |
|
|
14
|
+
| `--data <json>` | `-d` | Request body (JSON string) |
|
|
15
|
+
| `--header <k:v>` | `-H` | Header (repeatable) |
|
|
16
|
+
| `--token <jwt>` | | Bearer token shortcut |
|
|
17
|
+
| `--status <code>` | | Assert expected status (exit 1 if different) |
|
|
18
|
+
| `--jq <expr>` | | JQ-style filter on response body |
|
|
19
|
+
| `--raw` | | Raw output (no pretty-print, no status line) |
|
|
20
|
+
| `--timing` | | Show request timing breakdown |
|
|
21
|
+
| `--verbose` | `-v` | Show full request + response headers |
|
|
22
|
+
| `--form` | | Send as form-urlencoded instead of JSON |
|
|
23
|
+
| `--file <path>` | | Upload file as multipart |
|
|
24
|
+
|
|
25
|
+
## BaseUrl Resolution
|
|
26
|
+
|
|
27
|
+
Order of precedence:
|
|
28
|
+
1. `--base` flag
|
|
29
|
+
2. `QPROBE_BASE_URL` env variable
|
|
30
|
+
3. `http.baseUrl` in `qprobe.config.ts`
|
|
31
|
+
4. `browser.baseUrl` in config
|
|
32
|
+
5. First running service with a port → `http://localhost:<port>`
|
|
33
|
+
6. `http://localhost:3000` (fallback)
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
### GET
|
|
38
|
+
```bash
|
|
39
|
+
qprobe http GET /api/users
|
|
40
|
+
# 200 OK (45ms)
|
|
41
|
+
# [
|
|
42
|
+
# { "id": 1, "name": "Admin", "email": "admin@test.com" },
|
|
43
|
+
# { "id": 2, "name": "User", "email": "user@test.com" }
|
|
44
|
+
# ]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### POST with Body
|
|
48
|
+
```bash
|
|
49
|
+
qprobe http POST /api/users -d '{"name":"New User","email":"new@test.com"}'
|
|
50
|
+
# 201 Created (123ms)
|
|
51
|
+
# { "id": 3, "name": "New User", "email": "new@test.com" }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Auth
|
|
55
|
+
```bash
|
|
56
|
+
# Bearer token
|
|
57
|
+
qprobe http GET /api/admin/stats --token "eyJhbGci..."
|
|
58
|
+
|
|
59
|
+
# Custom header
|
|
60
|
+
qprobe http GET /api/data -H "X-API-Key: abc123"
|
|
61
|
+
|
|
62
|
+
# Cookie
|
|
63
|
+
qprobe http GET /api/me -H "Cookie: session=abc123"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Assert Status
|
|
67
|
+
```bash
|
|
68
|
+
qprobe http GET /api/health --status 200
|
|
69
|
+
# ✅ 200 OK (12ms)
|
|
70
|
+
|
|
71
|
+
qprobe http DELETE /api/users/1 --status 204
|
|
72
|
+
# ✅ 204 No Content (89ms)
|
|
73
|
+
|
|
74
|
+
qprobe http GET /api/nonexistent --status 404
|
|
75
|
+
# ✅ 404 Not Found (8ms)
|
|
76
|
+
|
|
77
|
+
qprobe http GET /api/broken --status 200
|
|
78
|
+
# ❌ Expected 200, got 500 Internal Server Error (234ms)
|
|
79
|
+
# { "error": "Database connection failed" }
|
|
80
|
+
# Exit code: 1
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### JQ Filter
|
|
84
|
+
```bash
|
|
85
|
+
qprobe http GET /api/users --jq ".[0].name"
|
|
86
|
+
# "Admin"
|
|
87
|
+
|
|
88
|
+
qprobe http GET /api/users --jq "length"
|
|
89
|
+
# 5
|
|
90
|
+
|
|
91
|
+
qprobe http GET /api/stats --jq ".revenue.total"
|
|
92
|
+
# 125000
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Verbose
|
|
96
|
+
```bash
|
|
97
|
+
qprobe http POST /api/login -d '{"email":"a@b.com","password":"123"}' -v
|
|
98
|
+
# → POST http://localhost:3000/api/login
|
|
99
|
+
# → Content-Type: application/json
|
|
100
|
+
# → Body: {"email":"a@b.com","password":"123"}
|
|
101
|
+
# ← 200 OK (89ms)
|
|
102
|
+
# ← Set-Cookie: session=abc123; HttpOnly; Path=/
|
|
103
|
+
# ← Content-Type: application/json
|
|
104
|
+
# { "token": "eyJ...", "user": { "id": 1, "name": "Admin" } }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### File Upload
|
|
108
|
+
```bash
|
|
109
|
+
qprobe http POST /api/upload --file ./avatar.png -H "Authorization: Bearer eyJ..."
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Raw Output (for piping)
|
|
113
|
+
```bash
|
|
114
|
+
# Pipe JSON to jq
|
|
115
|
+
qprobe http GET /api/users --raw | jq '.[].email'
|
|
116
|
+
|
|
117
|
+
# Save response to file
|
|
118
|
+
qprobe http GET /api/export --raw > export.json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Common Patterns
|
|
122
|
+
|
|
123
|
+
### Login → Use Token
|
|
124
|
+
```bash
|
|
125
|
+
# Login and extract token
|
|
126
|
+
TOKEN=$(qprobe http POST /api/login -d '{"email":"admin@test.com","password":"pass"}' --raw | jq -r '.token')
|
|
127
|
+
|
|
128
|
+
# Use token in subsequent requests
|
|
129
|
+
qprobe http GET /api/admin/users --token "$TOKEN"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Test CRUD Sequence
|
|
133
|
+
```bash
|
|
134
|
+
# Create
|
|
135
|
+
qprobe http POST /api/users -d '{"name":"Test"}' --status 201
|
|
136
|
+
# Read
|
|
137
|
+
qprobe http GET /api/users/3 --status 200
|
|
138
|
+
# Update
|
|
139
|
+
qprobe http PUT /api/users/3 -d '{"name":"Updated"}' --status 200
|
|
140
|
+
# Delete
|
|
141
|
+
qprobe http DELETE /api/users/3 --status 204
|
|
142
|
+
# Verify deleted
|
|
143
|
+
qprobe http GET /api/users/3 --status 404
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Health Check with Retry
|
|
147
|
+
```bash
|
|
148
|
+
# Wait for server, then test
|
|
149
|
+
qprobe health http://localhost:3000/api/health
|
|
150
|
+
qprobe http GET /api/users --status 200
|
|
151
|
+
```
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Process Management Reference
|
|
2
|
+
|
|
3
|
+
## Start a Process
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
qprobe start <name> "<command>" [flags]
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
| Flag | Default | Description |
|
|
10
|
+
|------|---------|-------------|
|
|
11
|
+
| `--ready "<pattern>"` | — | String/regex in stdout that signals ready |
|
|
12
|
+
| `--timeout <dur>` | `60s` | Max wait for ready pattern |
|
|
13
|
+
| `--port <n>` | — | Port for health checks and baseUrl |
|
|
14
|
+
| `--env KEY=VAL` | — | Environment variables (repeatable) |
|
|
15
|
+
| `--cwd <path>` | `.` | Working directory |
|
|
16
|
+
|
|
17
|
+
### Examples
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Database
|
|
21
|
+
qprobe start db "docker compose up postgres" --ready "ready to accept" --timeout 30s
|
|
22
|
+
|
|
23
|
+
# Dev server
|
|
24
|
+
qprobe start server "bun dev" --ready "ready on" --port 3000
|
|
25
|
+
|
|
26
|
+
# Worker with env
|
|
27
|
+
qprobe start worker "bun run jobs" --ready "worker started" --env QUEUE=default
|
|
28
|
+
|
|
29
|
+
# No ready pattern — just start and return immediately
|
|
30
|
+
qprobe start redis "redis-server"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### What Happens
|
|
34
|
+
|
|
35
|
+
1. Spawns child process (detached, survives between CLI calls)
|
|
36
|
+
2. Pipes stdout/stderr → `tmp/qprobe/logs/<name>.log` (timestamped)
|
|
37
|
+
3. Monitors stdout for `--ready` pattern
|
|
38
|
+
4. Returns when ready OR exits with code 2 on timeout
|
|
39
|
+
5. Saves PID to `tmp/qprobe/pids/<name>.pid`
|
|
40
|
+
6. Saves config to `tmp/qprobe/state/<name>.json` (for restart)
|
|
41
|
+
|
|
42
|
+
## Stop
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
qprobe stop <name> # stop one service
|
|
46
|
+
qprobe stop --all # stop everything
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Sends SIGTERM → waits 5s → SIGKILL if still alive.
|
|
50
|
+
|
|
51
|
+
## Restart
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
qprobe restart <name> # stop + start with original config
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Process Status
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
qprobe ps # table view
|
|
61
|
+
qprobe ps --json # machine-readable
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Output:
|
|
65
|
+
```
|
|
66
|
+
NAME PID PORT STATUS UPTIME MEM
|
|
67
|
+
db 12345 5432 ready 5m 23s 128MB
|
|
68
|
+
server 12346 3000 ready 5m 20s 256MB
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Health Check
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
qprobe health <url> [flags]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
| Flag | Default | Description |
|
|
78
|
+
|------|---------|-------------|
|
|
79
|
+
| `--interval <dur>` | `1s` | Polling interval |
|
|
80
|
+
| `--timeout <dur>` | `30s` | Max total wait |
|
|
81
|
+
| `--status <code>` | `200` | Expected HTTP status |
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
qprobe health http://localhost:3000/api/health
|
|
85
|
+
# ✅ Responding (200 OK, 45ms) after 3.2s
|
|
86
|
+
|
|
87
|
+
qprobe health http://localhost:5432 --timeout 60s
|
|
88
|
+
# ✅ Responding after 8.1s
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Common Patterns
|
|
92
|
+
|
|
93
|
+
### Start server, wait, then test
|
|
94
|
+
```bash
|
|
95
|
+
qprobe start server "bun dev" --ready "ready on" --port 3000
|
|
96
|
+
qprobe health http://localhost:3000/api/health
|
|
97
|
+
qprobe http GET /api/users
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Restart after code change
|
|
101
|
+
```bash
|
|
102
|
+
qprobe restart server
|
|
103
|
+
qprobe health http://localhost:3000/api/health
|
|
104
|
+
qprobe check
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Check if something crashed
|
|
108
|
+
```bash
|
|
109
|
+
qprobe ps
|
|
110
|
+
# If server shows "stopped" or is missing:
|
|
111
|
+
qprobe logs server --lines 50
|
|
112
|
+
# Look for the crash reason, then:
|
|
113
|
+
qprobe restart server
|
|
114
|
+
```
|