procsi 0.2.6 → 0.3.1
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/README.md +264 -148
- package/dist/cli/commands/completions.d.ts +9 -0
- package/dist/cli/commands/completions.d.ts.map +1 -0
- package/dist/cli/commands/completions.js +170 -0
- package/dist/cli/commands/completions.js.map +1 -0
- package/dist/cli/commands/helpers.d.ts +9 -0
- package/dist/cli/commands/helpers.d.ts.map +1 -1
- package/dist/cli/commands/helpers.js +19 -1
- package/dist/cli/commands/helpers.js.map +1 -1
- package/dist/cli/commands/interceptors.d.ts.map +1 -1
- package/dist/cli/commands/interceptors.js +142 -0
- package/dist/cli/commands/interceptors.js.map +1 -1
- package/dist/cli/commands/off.d.ts +0 -5
- package/dist/cli/commands/off.d.ts.map +1 -1
- package/dist/cli/commands/off.js +24 -23
- package/dist/cli/commands/off.js.map +1 -1
- package/dist/cli/commands/on.d.ts +27 -0
- package/dist/cli/commands/on.d.ts.map +1 -1
- package/dist/cli/commands/on.js +71 -17
- package/dist/cli/commands/on.js.map +1 -1
- package/dist/cli/commands/request.d.ts +6 -0
- package/dist/cli/commands/request.d.ts.map +1 -0
- package/dist/cli/commands/request.js +160 -0
- package/dist/cli/commands/request.js.map +1 -0
- package/dist/cli/commands/requests.d.ts +6 -0
- package/dist/cli/commands/requests.d.ts.map +1 -0
- package/dist/cli/commands/requests.js +282 -0
- package/dist/cli/commands/requests.js.map +1 -0
- package/dist/cli/commands/sessions.d.ts +6 -0
- package/dist/cli/commands/sessions.d.ts.map +1 -0
- package/dist/cli/commands/sessions.js +39 -0
- package/dist/cli/commands/sessions.js.map +1 -0
- package/dist/cli/formatters/colour.d.ts +17 -0
- package/dist/cli/formatters/colour.d.ts.map +1 -0
- package/dist/cli/formatters/colour.js +23 -0
- package/dist/cli/formatters/colour.js.map +1 -0
- package/dist/cli/formatters/detail.d.ts +17 -0
- package/dist/cli/formatters/detail.d.ts.map +1 -0
- package/dist/cli/formatters/detail.js +128 -0
- package/dist/cli/formatters/detail.js.map +1 -0
- package/dist/cli/formatters/hints.d.ts +17 -0
- package/dist/cli/formatters/hints.d.ts.map +1 -0
- package/dist/cli/formatters/hints.js +29 -0
- package/dist/cli/formatters/hints.js.map +1 -0
- package/dist/cli/formatters/table.d.ts +17 -0
- package/dist/cli/formatters/table.d.ts.map +1 -0
- package/dist/cli/formatters/table.js +75 -0
- package/dist/cli/formatters/table.js.map +1 -0
- package/dist/cli/index.js +12 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/tui/App.d.ts.map +1 -1
- package/dist/cli/tui/App.js +24 -5
- package/dist/cli/tui/App.js.map +1 -1
- package/dist/cli/tui/components/EventFilterBar.d.ts +27 -0
- package/dist/cli/tui/components/EventFilterBar.d.ts.map +1 -0
- package/dist/cli/tui/components/EventFilterBar.js +145 -0
- package/dist/cli/tui/components/EventFilterBar.js.map +1 -0
- package/dist/cli/tui/components/HelpModal.d.ts.map +1 -1
- package/dist/cli/tui/components/HelpModal.js +1 -0
- package/dist/cli/tui/components/HelpModal.js.map +1 -1
- package/dist/cli/tui/components/InfoBar.d.ts +15 -0
- package/dist/cli/tui/components/InfoBar.d.ts.map +1 -0
- package/dist/cli/tui/components/InfoBar.js +45 -0
- package/dist/cli/tui/components/InfoBar.js.map +1 -0
- package/dist/cli/tui/components/InfoModal.js +1 -1
- package/dist/cli/tui/components/InfoModal.js.map +1 -1
- package/dist/cli/tui/components/InterceptorLogModal.d.ts +16 -0
- package/dist/cli/tui/components/InterceptorLogModal.d.ts.map +1 -0
- package/dist/cli/tui/components/InterceptorLogModal.js +229 -0
- package/dist/cli/tui/components/InterceptorLogModal.js.map +1 -0
- package/dist/cli/tui/components/RequestList.js +1 -1
- package/dist/cli/tui/components/RequestList.js.map +1 -1
- package/dist/cli/tui/components/StatusBar.d.ts +7 -2
- package/dist/cli/tui/components/StatusBar.d.ts.map +1 -1
- package/dist/cli/tui/components/StatusBar.js +11 -6
- package/dist/cli/tui/components/StatusBar.js.map +1 -1
- package/dist/cli/tui/hooks/useInterceptorEvents.d.ts +33 -0
- package/dist/cli/tui/hooks/useInterceptorEvents.d.ts.map +1 -0
- package/dist/cli/tui/hooks/useInterceptorEvents.js +88 -0
- package/dist/cli/tui/hooks/useInterceptorEvents.js.map +1 -0
- package/dist/cli/tui/hooks/useRequests.js +2 -2
- package/dist/cli/tui/hooks/useRequests.js.map +1 -1
- package/dist/cli/utils/parse-time.d.ts +22 -0
- package/dist/cli/utils/parse-time.d.ts.map +1 -0
- package/dist/cli/utils/parse-time.js +160 -0
- package/dist/cli/utils/parse-time.js.map +1 -0
- package/dist/daemon/control.d.ts +2 -0
- package/dist/daemon/control.d.ts.map +1 -1
- package/dist/daemon/control.js +41 -1
- package/dist/daemon/control.js.map +1 -1
- package/dist/daemon/index.js +5 -0
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/interceptor-event-log.d.ts +37 -0
- package/dist/daemon/interceptor-event-log.d.ts.map +1 -0
- package/dist/daemon/interceptor-event-log.js +163 -0
- package/dist/daemon/interceptor-event-log.js.map +1 -0
- package/dist/daemon/interceptor-loader.d.ts +3 -0
- package/dist/daemon/interceptor-loader.d.ts.map +1 -1
- package/dist/daemon/interceptor-loader.js +29 -2
- package/dist/daemon/interceptor-loader.js.map +1 -1
- package/dist/daemon/interceptor-runner.d.ts +3 -0
- package/dist/daemon/interceptor-runner.d.ts.map +1 -1
- package/dist/daemon/interceptor-runner.js +112 -8
- package/dist/daemon/interceptor-runner.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +51 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/shared/control-client.d.ts +22 -1
- package/dist/shared/control-client.d.ts.map +1 -1
- package/dist/shared/control-client.js +12 -0
- package/dist/shared/control-client.js.map +1 -1
- package/dist/shared/types.d.ts +14 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/skills/procsi/SKILL.md +2 -3
package/README.md
CHANGED
|
@@ -4,48 +4,31 @@
|
|
|
4
4
|
[](https://github.com/mtford90/procsi/actions/workflows/ci.yml)
|
|
5
5
|
[](https://www.gnu.org/licenses/agpl-3.0)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Procsi is a terminal-based HTTP proxy with a powerful MCP server. Quickly intercept, inspect & rewrite HTTP traffic.
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## Feature Highlights
|
|
12
|
+
|
|
13
|
+
- **Project isolation** — each project gets its own `.procsi/` directory with a separate daemon, database, CA cert and interceptors.
|
|
14
|
+
- **MCP server** — AI agents get full access to your captured traffic and can write interceptor files for you. Search, filter, inspect, mock — all via tool calls.
|
|
15
|
+
- **Interceptors** — mock, modify or observe traffic with `.ts` files. Match on anything, query past traffic from within handlers, compose complex scenarios.
|
|
12
16
|
|
|
13
17
|
## Quick Start
|
|
14
18
|
|
|
15
19
|
```bash
|
|
16
20
|
npm install -g procsi
|
|
17
21
|
|
|
18
|
-
#
|
|
19
|
-
eval "$(procsi
|
|
22
|
+
# Configure environment e.g. HTTP_PROXY
|
|
23
|
+
eval "$(procsi on)"
|
|
20
24
|
|
|
21
|
-
#
|
|
22
|
-
procsi on
|
|
25
|
+
# Send a request
|
|
23
26
|
curl https://api.example.com/users
|
|
24
|
-
procsi tui
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Requires Node.js 20+.
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Run this once per shell session (or add it to your shell profile):
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
eval "$(procsi init)"
|
|
28
|
+
# Open UI
|
|
29
|
+
procsi tui
|
|
35
30
|
```
|
|
36
31
|
|
|
37
|
-
This creates a shell function that lets `procsi on`/`procsi off` set proxy environment variables in your current session.
|
|
38
|
-
|
|
39
|
-
## Features
|
|
40
|
-
|
|
41
|
-
- **Project-scoped** — each project gets its own `.procsi/` directory with a separate daemon, database, CA cert and interceptors. No cross-project bleed.
|
|
42
|
-
- **TypeScript interceptors** — mock, modify or observe traffic with `.ts` files. Match on anything, query past traffic from within handlers, compose complex scenarios.
|
|
43
|
-
- **MCP server** — AI agents get full access to your captured traffic and can write interceptor files for you. Search, filter, inspect, mock — all via tool calls.
|
|
44
|
-
- **Terminal TUI** — vim-style keybindings, mouse support, JSON explorer, filtering. Stays in your terminal where you're already working.
|
|
45
|
-
- **HTTPS** — automatic CA certificate generation and trust
|
|
46
|
-
- **Export** — copy as curl, export as HAR, save bodies to disk
|
|
47
|
-
- **Zero config** — works with curl, wget, Node.js, Python, Go, Rust and anything else that respects `HTTP_PROXY`
|
|
48
|
-
|
|
49
32
|
## Project Isolation
|
|
50
33
|
|
|
51
34
|
procsi doesn't use a global system proxy. Each project gets its own `.procsi/` directory in the project root (detected by `.git` or an existing `.procsi/`):
|
|
@@ -63,7 +46,120 @@ your-project/
|
|
|
63
46
|
└── src/...
|
|
64
47
|
```
|
|
65
48
|
|
|
66
|
-
Separate daemon,
|
|
49
|
+
Separate daemon, database, certificates etc. You can run procsi in multiple projects at the same time without them interfering with each other.
|
|
50
|
+
|
|
51
|
+
## Use cases
|
|
52
|
+
|
|
53
|
+
- AI analysis
|
|
54
|
+
- Chaos monkey
|
|
55
|
+
- Mock out APIs that do not yet exist
|
|
56
|
+
|
|
57
|
+
## MCP Integration
|
|
58
|
+
|
|
59
|
+
procsi has a built-in [MCP](https://modelcontextprotocol.io/) server that gives AI agents full access to your captured traffic and interceptor system. Agents can search through requests, inspect headers and bodies, and write interceptor files directly into `.procsi/interceptors/`.
|
|
60
|
+
|
|
61
|
+
This means you can ask things like:
|
|
62
|
+
|
|
63
|
+
- "Find all failing requests to the payments API and write mocks that return valid responses"
|
|
64
|
+
- "Make every 5th request to /api/users return a 429 so I can test rate limiting"
|
|
65
|
+
- "What's the average response time for requests to the auth service in the last hour?"
|
|
66
|
+
- "Write an interceptor that logs all requests with missing auth headers"
|
|
67
|
+
- "Send me a notification whenever an api request fails"
|
|
68
|
+
|
|
69
|
+
The agent reads your traffic, writes the TypeScript, and procsi hot-reloads it.
|
|
70
|
+
|
|
71
|
+
### Setup
|
|
72
|
+
|
|
73
|
+
Add procsi to your MCP client config:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"procsi": {
|
|
79
|
+
"command": "procsi",
|
|
80
|
+
"args": ["mcp"]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The proxy must be running (`eval "$(procsi on)"`) — the MCP server connects to the same daemon as the TUI.
|
|
87
|
+
|
|
88
|
+
### Agent Skill
|
|
89
|
+
|
|
90
|
+
procsi also ships an agent skill that teaches AI assistants how to use the MCP tools properly. Gets you better results out of the box.
|
|
91
|
+
|
|
92
|
+
**Claude Code:**
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
/plugin marketplace add mtford90/procsi
|
|
96
|
+
/plugin install procsi
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**npm-agentskills** (works with Cursor, Copilot, Codex, etc.):
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx agents export --target claude
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Available Tools
|
|
106
|
+
|
|
107
|
+
| Tool | Description |
|
|
108
|
+
|------|-------------|
|
|
109
|
+
| `procsi_get_status` | Daemon status, proxy port, request count |
|
|
110
|
+
| `procsi_list_requests` | Search and filter captured requests |
|
|
111
|
+
| `procsi_get_request` | Full request details by ID (headers, bodies, timing) |
|
|
112
|
+
| `procsi_search_bodies` | Full-text search through body content |
|
|
113
|
+
| `procsi_query_json` | Extract values from JSON bodies via JSONPath |
|
|
114
|
+
| `procsi_count_requests` | Count matching requests |
|
|
115
|
+
| `procsi_clear_requests` | Delete all captured requests |
|
|
116
|
+
| `procsi_list_sessions` | List active proxy sessions |
|
|
117
|
+
| `procsi_list_interceptors` | List loaded interceptors with status and errors |
|
|
118
|
+
| `procsi_reload_interceptors` | Reload interceptors from disk |
|
|
119
|
+
|
|
120
|
+
### Filtering
|
|
121
|
+
|
|
122
|
+
Most tools accept these filters:
|
|
123
|
+
|
|
124
|
+
| Parameter | Description | Example |
|
|
125
|
+
|-----------|-------------|---------|
|
|
126
|
+
| `method` | HTTP method(s), comma-separated | `"GET,POST"` |
|
|
127
|
+
| `status_range` | Status code, Nxx pattern, or range | `"4xx"`, `"401"`, `"500-503"` |
|
|
128
|
+
| `search` | Substring match on URL/path | `"api/users"` |
|
|
129
|
+
| `host` | Exact or suffix match (prefix with `.`) | `"api.example.com"`, `".example.com"` |
|
|
130
|
+
| `path` | Path prefix match | `"/api/v2"` |
|
|
131
|
+
| `since` / `before` | Time window (ISO 8601) | `"2024-01-15T10:30:00Z"` |
|
|
132
|
+
| `header_name` | Filter by header existence or value | `"content-type"` |
|
|
133
|
+
| `header_value` | Exact header value (requires `header_name`) | `"application/json"` |
|
|
134
|
+
| `header_target` | Which headers to search | `"request"`, `"response"`, `"both"` |
|
|
135
|
+
| `intercepted_by` | Filter by interceptor name | `"mock-users"` |
|
|
136
|
+
| `offset` | Pagination offset (0-based) | `0` |
|
|
137
|
+
| `limit` | Max results (default 50, max 500) | `100` |
|
|
138
|
+
|
|
139
|
+
`procsi_get_request` accepts comma-separated IDs for batch fetching (e.g. `"id1,id2,id3"`).
|
|
140
|
+
|
|
141
|
+
`procsi_query_json` also takes:
|
|
142
|
+
|
|
143
|
+
| Parameter | Description | Example |
|
|
144
|
+
|-----------|-------------|---------|
|
|
145
|
+
| `target` | Which body to query: `"request"`, `"response"`, or `"both"` (default) | `"response"` |
|
|
146
|
+
| `value` | Exact value match after JSONPath extraction | `"active"` |
|
|
147
|
+
|
|
148
|
+
### Output Formats
|
|
149
|
+
|
|
150
|
+
All query tools accept a `format` parameter:
|
|
151
|
+
|
|
152
|
+
- `text` (default) — markdown summaries, readable by humans and AI
|
|
153
|
+
- `json` — structured JSON for programmatic use
|
|
154
|
+
|
|
155
|
+
### Examples
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
procsi_list_requests({ status_range: "5xx", path: "/api" })
|
|
159
|
+
procsi_search_bodies({ query: "error_code", method: "POST" })
|
|
160
|
+
procsi_query_json({ json_path: "$.user.id", target: "response" })
|
|
161
|
+
procsi_list_requests({ header_name: "authorization", header_target: "request" })
|
|
162
|
+
```
|
|
67
163
|
|
|
68
164
|
## Interceptors
|
|
69
165
|
|
|
@@ -189,112 +285,6 @@ export default {
|
|
|
189
285
|
- `ctx.log()` writes to `.procsi/procsi.log` since `console.log` goes nowhere in the daemon
|
|
190
286
|
- Use `satisfies Interceptor` for full intellisense
|
|
191
287
|
|
|
192
|
-
## MCP Integration
|
|
193
|
-
|
|
194
|
-
procsi has a built-in [MCP](https://modelcontextprotocol.io/) server that gives AI agents full access to your captured traffic and interceptor system. Agents can search through requests, inspect headers and bodies, and write interceptor files directly into `.procsi/interceptors/`.
|
|
195
|
-
|
|
196
|
-
This means you can ask things like:
|
|
197
|
-
|
|
198
|
-
- "Find all failing requests to the payments API and write mocks that return valid responses"
|
|
199
|
-
- "Make every 5th request to /api/users return a 429 so I can test rate limiting"
|
|
200
|
-
- "What's the average response time for requests to the auth service in the last hour?"
|
|
201
|
-
- "Write an interceptor that logs all requests with missing auth headers"
|
|
202
|
-
|
|
203
|
-
The agent reads your traffic, writes the TypeScript, and procsi hot-reloads it.
|
|
204
|
-
|
|
205
|
-
### Setup
|
|
206
|
-
|
|
207
|
-
Add procsi to your MCP client config:
|
|
208
|
-
|
|
209
|
-
```json
|
|
210
|
-
{
|
|
211
|
-
"mcpServers": {
|
|
212
|
-
"procsi": {
|
|
213
|
-
"command": "procsi",
|
|
214
|
-
"args": ["mcp"]
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
The proxy must be running (`procsi on` or `eval "$(procsi vars)"`) — the MCP server connects to the same daemon as the TUI.
|
|
221
|
-
|
|
222
|
-
### Agent Skill
|
|
223
|
-
|
|
224
|
-
procsi also ships an agent skill that teaches AI assistants how to use the MCP tools properly. Gets you better results out of the box.
|
|
225
|
-
|
|
226
|
-
**Claude Code:**
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
/plugin marketplace add mtford90/procsi
|
|
230
|
-
/plugin install procsi
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
**npm-agentskills** (works with Cursor, Copilot, Codex, etc.):
|
|
234
|
-
|
|
235
|
-
```bash
|
|
236
|
-
npx agents export --target claude
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Available Tools
|
|
240
|
-
|
|
241
|
-
| Tool | Description |
|
|
242
|
-
|------|-------------|
|
|
243
|
-
| `procsi_get_status` | Daemon status, proxy port, request count |
|
|
244
|
-
| `procsi_list_requests` | Search and filter captured requests |
|
|
245
|
-
| `procsi_get_request` | Full request details by ID (headers, bodies, timing) |
|
|
246
|
-
| `procsi_search_bodies` | Full-text search through body content |
|
|
247
|
-
| `procsi_query_json` | Extract values from JSON bodies via JSONPath |
|
|
248
|
-
| `procsi_count_requests` | Count matching requests |
|
|
249
|
-
| `procsi_clear_requests` | Delete all captured requests |
|
|
250
|
-
| `procsi_list_sessions` | List active proxy sessions |
|
|
251
|
-
| `procsi_list_interceptors` | List loaded interceptors with status and errors |
|
|
252
|
-
| `procsi_reload_interceptors` | Reload interceptors from disk |
|
|
253
|
-
|
|
254
|
-
### Filtering
|
|
255
|
-
|
|
256
|
-
Most tools accept these filters:
|
|
257
|
-
|
|
258
|
-
| Parameter | Description | Example |
|
|
259
|
-
|-----------|-------------|---------|
|
|
260
|
-
| `method` | HTTP method(s), comma-separated | `"GET,POST"` |
|
|
261
|
-
| `status_range` | Status code, Nxx pattern, or range | `"4xx"`, `"401"`, `"500-503"` |
|
|
262
|
-
| `search` | Substring match on URL/path | `"api/users"` |
|
|
263
|
-
| `host` | Exact or suffix match (prefix with `.`) | `"api.example.com"`, `".example.com"` |
|
|
264
|
-
| `path` | Path prefix match | `"/api/v2"` |
|
|
265
|
-
| `since` / `before` | Time window (ISO 8601) | `"2024-01-15T10:30:00Z"` |
|
|
266
|
-
| `header_name` | Filter by header existence or value | `"content-type"` |
|
|
267
|
-
| `header_value` | Exact header value (requires `header_name`) | `"application/json"` |
|
|
268
|
-
| `header_target` | Which headers to search | `"request"`, `"response"`, `"both"` |
|
|
269
|
-
| `intercepted_by` | Filter by interceptor name | `"mock-users"` |
|
|
270
|
-
| `offset` | Pagination offset (0-based) | `0` |
|
|
271
|
-
| `limit` | Max results (default 50, max 500) | `100` |
|
|
272
|
-
|
|
273
|
-
`procsi_get_request` accepts comma-separated IDs for batch fetching (e.g. `"id1,id2,id3"`).
|
|
274
|
-
|
|
275
|
-
`procsi_query_json` also takes:
|
|
276
|
-
|
|
277
|
-
| Parameter | Description | Example |
|
|
278
|
-
|-----------|-------------|---------|
|
|
279
|
-
| `target` | Which body to query: `"request"`, `"response"`, or `"both"` (default) | `"response"` |
|
|
280
|
-
| `value` | Exact value match after JSONPath extraction | `"active"` |
|
|
281
|
-
|
|
282
|
-
### Output Formats
|
|
283
|
-
|
|
284
|
-
All query tools accept a `format` parameter:
|
|
285
|
-
|
|
286
|
-
- `text` (default) — markdown summaries, readable by humans and AI
|
|
287
|
-
- `json` — structured JSON for programmatic use
|
|
288
|
-
|
|
289
|
-
### Examples
|
|
290
|
-
|
|
291
|
-
```
|
|
292
|
-
procsi_list_requests({ status_range: "5xx", path: "/api" })
|
|
293
|
-
procsi_search_bodies({ query: "error_code", method: "POST" })
|
|
294
|
-
procsi_query_json({ json_path: "$.user.id", target: "response" })
|
|
295
|
-
procsi_list_requests({ header_name: "authorization", header_target: "request" })
|
|
296
|
-
```
|
|
297
|
-
|
|
298
288
|
## How It Works
|
|
299
289
|
|
|
300
290
|
```
|
|
@@ -330,11 +320,11 @@ procsi_list_requests({ header_name: "authorization", header_target: "request" })
|
|
|
330
320
|
└─────────────────────────────────────────────────────────────┘
|
|
331
321
|
```
|
|
332
322
|
|
|
333
|
-
`procsi on`
|
|
323
|
+
`eval "$(procsi on)"` starts a daemon, sets `HTTP_PROXY`/`HTTPS_PROXY` in your shell, and captures everything that flows through. `eval "$(procsi off)"` unsets them. The TUI connects to the daemon via Unix socket.
|
|
334
324
|
|
|
335
325
|
### Environment Variables
|
|
336
326
|
|
|
337
|
-
`procsi on` sets these in your shell (`
|
|
327
|
+
`eval "$(procsi on)"` sets these in your shell (`eval "$(procsi off)"` unsets them):
|
|
338
328
|
|
|
339
329
|
| Variable | Purpose |
|
|
340
330
|
|----------|---------|
|
|
@@ -472,25 +462,28 @@ Mouse support: click to select, scroll to navigate, click panels to focus.
|
|
|
472
462
|
| `-v, --verbose` | Increase log verbosity (stackable: `-vv`, `-vvv`) |
|
|
473
463
|
| `-d, --dir <path>` | Override project root directory |
|
|
474
464
|
|
|
475
|
-
### `procsi
|
|
476
|
-
|
|
477
|
-
Output shell wrapper function. Enables `procsi on`/`procsi off` to set environment variables in the current shell.
|
|
478
|
-
|
|
479
|
-
### `procsi vars`
|
|
465
|
+
### `procsi on`
|
|
480
466
|
|
|
481
|
-
Output shell `export` statements to
|
|
467
|
+
Output shell `export` statements to start intercepting HTTP traffic. Use with `eval`:
|
|
482
468
|
|
|
483
469
|
```bash
|
|
484
|
-
eval "$(procsi
|
|
470
|
+
eval "$(procsi on)"
|
|
485
471
|
```
|
|
486
472
|
|
|
487
|
-
|
|
473
|
+
If run directly in a TTY (without `eval`), shows usage instructions.
|
|
488
474
|
|
|
489
475
|
| Flag | Description |
|
|
490
476
|
|------|-------------|
|
|
491
477
|
| `-l, --label <label>` | Label this session (visible in TUI and MCP) |
|
|
492
478
|
| `--no-restart` | Don't auto-restart daemon on version mismatch |
|
|
493
|
-
|
|
479
|
+
|
|
480
|
+
### `procsi off`
|
|
481
|
+
|
|
482
|
+
Output shell `unset` statements to stop intercepting HTTP traffic. Use with `eval`:
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
eval "$(procsi off)"
|
|
486
|
+
```
|
|
494
487
|
|
|
495
488
|
### `procsi tui`
|
|
496
489
|
|
|
@@ -512,6 +505,94 @@ Stop the daemon.
|
|
|
512
505
|
|
|
513
506
|
Restart the daemon (or start it if not running).
|
|
514
507
|
|
|
508
|
+
### `procsi requests`
|
|
509
|
+
|
|
510
|
+
List and filter captured requests. Output is a colour-coded table with short IDs — pipe to other tools or use `--json` for structured output.
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
procsi requests # list recent (default limit 50)
|
|
514
|
+
procsi requests --method GET,POST # filter by method
|
|
515
|
+
procsi requests --status 4xx # filter by status range
|
|
516
|
+
procsi requests --host api.example.com # filter by host
|
|
517
|
+
procsi requests --path /api/v2 # filter by path prefix
|
|
518
|
+
procsi requests --search "keyword" # substring match on URL
|
|
519
|
+
procsi requests --since 5m # last 5 minutes
|
|
520
|
+
procsi requests --since yesterday # since midnight yesterday
|
|
521
|
+
procsi requests --since 10am --before 11am # time window
|
|
522
|
+
procsi requests --header "content-type:application/json" # header filter
|
|
523
|
+
procsi requests --intercepted-by mock-users # interceptor filter
|
|
524
|
+
procsi requests --limit 100 --offset 50 # pagination
|
|
525
|
+
procsi requests --json # JSON output
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
| Flag | Description |
|
|
529
|
+
|------|-------------|
|
|
530
|
+
| `--method <methods>` | Filter by HTTP method (comma-separated) |
|
|
531
|
+
| `--status <range>` | Status range: `2xx`, `4xx`, exact `401`, etc. |
|
|
532
|
+
| `--host <host>` | Filter by hostname |
|
|
533
|
+
| `--path <prefix>` | Filter by path prefix |
|
|
534
|
+
| `--search <text>` | Substring match on URL |
|
|
535
|
+
| `--since <time>` | Since time (5m, 2h, 10am, yesterday, monday, 2024-01-01) |
|
|
536
|
+
| `--before <time>` | Before time (same formats as --since) |
|
|
537
|
+
| `--header <spec>` | Header name or name:value |
|
|
538
|
+
| `--header-target <target>` | `request`, `response`, or `both` (default) |
|
|
539
|
+
| `--intercepted-by <name>` | Filter by interceptor name |
|
|
540
|
+
| `--limit <n>` | Max results (default 50) |
|
|
541
|
+
| `--offset <n>` | Skip results (default 0) |
|
|
542
|
+
| `--json` | JSON output |
|
|
543
|
+
|
|
544
|
+
#### `procsi requests search <query>`
|
|
545
|
+
|
|
546
|
+
Full-text search through request and response bodies.
|
|
547
|
+
|
|
548
|
+
#### `procsi requests query <jsonpath>`
|
|
549
|
+
|
|
550
|
+
Query JSON bodies using JSONPath expressions (e.g. `$.data.id`). Supports `--value`, `--target` (request/response/both).
|
|
551
|
+
|
|
552
|
+
#### `procsi requests count`
|
|
553
|
+
|
|
554
|
+
Count requests matching the current filters.
|
|
555
|
+
|
|
556
|
+
#### `procsi requests clear`
|
|
557
|
+
|
|
558
|
+
Clear all captured requests. Prompts for confirmation unless `--yes` is passed.
|
|
559
|
+
|
|
560
|
+
### `procsi request <id>`
|
|
561
|
+
|
|
562
|
+
View a single request in detail. Accepts full UUIDs or abbreviated prefixes (first 7+ characters).
|
|
563
|
+
|
|
564
|
+
```bash
|
|
565
|
+
procsi request a1b2c3d # full detail view
|
|
566
|
+
procsi request a1b2c3d --json # JSON output
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
#### `procsi request <id> body`
|
|
570
|
+
|
|
571
|
+
Dump the response body to stdout (raw, pipeable). Use `--request` for the request body instead.
|
|
572
|
+
|
|
573
|
+
```bash
|
|
574
|
+
procsi request a1b2c3d body # response body
|
|
575
|
+
procsi request a1b2c3d body --request # request body
|
|
576
|
+
procsi request a1b2c3d body | jq . # pipe to jq
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
#### `procsi request <id> export <format>`
|
|
580
|
+
|
|
581
|
+
Export a request as `curl` or `har`.
|
|
582
|
+
|
|
583
|
+
```bash
|
|
584
|
+
procsi request a1b2c3d export curl
|
|
585
|
+
procsi request a1b2c3d export har
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### `procsi sessions`
|
|
589
|
+
|
|
590
|
+
List active proxy sessions.
|
|
591
|
+
|
|
592
|
+
| Flag | Description |
|
|
593
|
+
|------|-------------|
|
|
594
|
+
| `--json` | JSON output |
|
|
595
|
+
|
|
515
596
|
### `procsi clear`
|
|
516
597
|
|
|
517
598
|
Clear all captured requests.
|
|
@@ -540,6 +621,41 @@ Scaffold an example interceptor in `.procsi/interceptors/`.
|
|
|
540
621
|
|
|
541
622
|
Reload interceptors from disk without restarting the daemon.
|
|
542
623
|
|
|
624
|
+
### `procsi interceptors logs`
|
|
625
|
+
|
|
626
|
+
View the interceptor event log. Events include match results, mock responses, errors, timeouts, and `ctx.log()` output.
|
|
627
|
+
|
|
628
|
+
```bash
|
|
629
|
+
procsi interceptors logs # recent events
|
|
630
|
+
procsi interceptors logs --name mock-users # filter by interceptor
|
|
631
|
+
procsi interceptors logs --level error # filter by level
|
|
632
|
+
procsi interceptors logs --limit 100 # more results
|
|
633
|
+
procsi interceptors logs --follow # live tail (Ctrl+C to stop)
|
|
634
|
+
procsi interceptors logs --follow --json # live tail as NDJSON
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
| Flag | Description |
|
|
638
|
+
|------|-------------|
|
|
639
|
+
| `--name <interceptor>` | Filter by interceptor name |
|
|
640
|
+
| `--level <level>` | Filter by level (info, warn, error) |
|
|
641
|
+
| `--limit <n>` | Max events (default 50) |
|
|
642
|
+
| `--follow` | Live tail — poll for new events |
|
|
643
|
+
| `--json` | JSON output |
|
|
644
|
+
|
|
645
|
+
#### `procsi interceptors logs clear`
|
|
646
|
+
|
|
647
|
+
Clear the interceptor event log.
|
|
648
|
+
|
|
649
|
+
### `procsi completions <shell>`
|
|
650
|
+
|
|
651
|
+
Generate shell completion scripts. Supports `zsh`, `bash`, and `fish`.
|
|
652
|
+
|
|
653
|
+
```bash
|
|
654
|
+
eval "$(procsi completions zsh)" # add to .zshrc
|
|
655
|
+
eval "$(procsi completions bash)" # add to .bashrc
|
|
656
|
+
procsi completions fish | source # add to fish config
|
|
657
|
+
```
|
|
658
|
+
|
|
543
659
|
## Development
|
|
544
660
|
|
|
545
661
|
```bash
|
|
@@ -571,7 +687,7 @@ Check if something else is using the socket:
|
|
|
571
687
|
```bash
|
|
572
688
|
procsi status
|
|
573
689
|
procsi daemon stop
|
|
574
|
-
|
|
690
|
+
eval "$(procsi on)"
|
|
575
691
|
```
|
|
576
692
|
|
|
577
693
|
### Terminal too small
|
|
@@ -580,7 +696,7 @@ The TUI needs at least 60 columns by 10 rows.
|
|
|
580
696
|
|
|
581
697
|
### Requests not appearing
|
|
582
698
|
|
|
583
|
-
Your HTTP client needs to respect proxy environment variables.
|
|
699
|
+
Your HTTP client needs to respect proxy environment variables.
|
|
584
700
|
|
|
585
701
|
## Licence
|
|
586
702
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `procsi completions <shell>` — generate shell completion scripts.
|
|
3
|
+
*
|
|
4
|
+
* Outputs a completion script that the user sources in their shell config.
|
|
5
|
+
* Generated by walking the Commander program tree.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
export declare const completionsCommand: Command;
|
|
9
|
+
//# sourceMappingURL=completions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completions.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/completions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8KpC,eAAO,MAAM,kBAAkB,SAuB3B,CAAC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `procsi completions <shell>` — generate shell completion scripts.
|
|
3
|
+
*
|
|
4
|
+
* Outputs a completion script that the user sources in their shell config.
|
|
5
|
+
* Generated by walking the Commander program tree.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
const SUPPORTED_SHELLS = ["zsh", "bash", "fish"];
|
|
9
|
+
/**
|
|
10
|
+
* Escape a string for use inside a single-quoted shell string.
|
|
11
|
+
* Replaces ' with '\'' (end quote, escaped quote, start quote).
|
|
12
|
+
*/
|
|
13
|
+
function escapeForShell(str) {
|
|
14
|
+
return str.replace(/'/g, "'\\''");
|
|
15
|
+
}
|
|
16
|
+
function collectCommands(cmd) {
|
|
17
|
+
return cmd.commands.map((sub) => ({
|
|
18
|
+
name: sub.name(),
|
|
19
|
+
description: sub.description(),
|
|
20
|
+
options: sub.options.map((opt) => ({
|
|
21
|
+
flags: opt.long ?? opt.short ?? "",
|
|
22
|
+
description: opt.description,
|
|
23
|
+
})),
|
|
24
|
+
subcommands: collectCommands(sub),
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generate a zsh completion script.
|
|
29
|
+
*/
|
|
30
|
+
function generateZshCompletions(program) {
|
|
31
|
+
const commands = collectCommands(program);
|
|
32
|
+
const globalOptions = program.options.map((opt) => `'${escapeForShell(opt.long ?? opt.short ?? "")}[${escapeForShell(opt.description)}]'`);
|
|
33
|
+
const subcmdCases = commands
|
|
34
|
+
.map((cmd) => {
|
|
35
|
+
const opts = cmd.options
|
|
36
|
+
.map((o) => `'${escapeForShell(o.flags)}[${escapeForShell(o.description)}]'`)
|
|
37
|
+
.join(" \\\n ");
|
|
38
|
+
const subs = cmd.subcommands
|
|
39
|
+
.map((s) => `'${escapeForShell(s.name)}:${escapeForShell(s.description)}'`)
|
|
40
|
+
.join(" ");
|
|
41
|
+
const subsSection = subs
|
|
42
|
+
? `\n local -a ${cmd.name}_subcommands\n ${cmd.name}_subcommands=(${subs})\n _describe -t commands '${escapeForShell(cmd.name)} subcommand' ${cmd.name}_subcommands`
|
|
43
|
+
: "";
|
|
44
|
+
return ` ${cmd.name})\n _arguments ${opts}${subsSection}\n ;;`;
|
|
45
|
+
})
|
|
46
|
+
.join("\n");
|
|
47
|
+
const cmdList = commands
|
|
48
|
+
.map((c) => `'${escapeForShell(c.name)}:${escapeForShell(c.description)}'`)
|
|
49
|
+
.join(" \\\n ");
|
|
50
|
+
return `#compdef procsi
|
|
51
|
+
|
|
52
|
+
# Auto-generated by procsi completions zsh
|
|
53
|
+
# Add to your .zshrc: eval "$(procsi completions zsh)"
|
|
54
|
+
|
|
55
|
+
_procsi() {
|
|
56
|
+
local -a commands
|
|
57
|
+
commands=(
|
|
58
|
+
${cmdList}
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
_arguments -C \\
|
|
62
|
+
${globalOptions.join(" \\\n ")} \\
|
|
63
|
+
'1:command:->command' \\
|
|
64
|
+
'*::arg:->args'
|
|
65
|
+
|
|
66
|
+
case "$state" in
|
|
67
|
+
command)
|
|
68
|
+
_describe -t commands 'procsi command' commands
|
|
69
|
+
;;
|
|
70
|
+
args)
|
|
71
|
+
case "$words[1]" in
|
|
72
|
+
${subcmdCases}
|
|
73
|
+
esac
|
|
74
|
+
;;
|
|
75
|
+
esac
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
compdef _procsi procsi
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Generate a bash completion script.
|
|
83
|
+
*/
|
|
84
|
+
function generateBashCompletions(program) {
|
|
85
|
+
const commands = collectCommands(program);
|
|
86
|
+
const cmdNames = commands.map((c) => c.name).join(" ");
|
|
87
|
+
const subcmdCases = commands
|
|
88
|
+
.map((cmd) => {
|
|
89
|
+
const opts = cmd.options.map((o) => escapeForShell(o.flags)).join(" ");
|
|
90
|
+
const subs = cmd.subcommands.map((s) => escapeForShell(s.name)).join(" ");
|
|
91
|
+
return ` ${cmd.name})\n COMPREPLY=($(compgen -W "${opts} ${subs}" -- "$cur"))\n ;;`;
|
|
92
|
+
})
|
|
93
|
+
.join("\n");
|
|
94
|
+
return `# Auto-generated by procsi completions bash
|
|
95
|
+
# Add to your .bashrc: eval "$(procsi completions bash)"
|
|
96
|
+
|
|
97
|
+
_procsi() {
|
|
98
|
+
local cur prev words cword
|
|
99
|
+
_init_completion || return
|
|
100
|
+
|
|
101
|
+
local commands="${cmdNames}"
|
|
102
|
+
|
|
103
|
+
if [[ $cword -eq 1 ]]; then
|
|
104
|
+
COMPREPLY=($(compgen -W "$commands" -- "$cur"))
|
|
105
|
+
return
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
case "\${words[1]}" in
|
|
109
|
+
${subcmdCases}
|
|
110
|
+
esac
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
complete -F _procsi procsi
|
|
114
|
+
`;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Generate a fish completion script.
|
|
118
|
+
*/
|
|
119
|
+
function generateFishCompletions(program) {
|
|
120
|
+
const commands = collectCommands(program);
|
|
121
|
+
const lines = [
|
|
122
|
+
"# Auto-generated by procsi completions fish",
|
|
123
|
+
"# Add to your config: procsi completions fish | source",
|
|
124
|
+
"",
|
|
125
|
+
"# Disable file completions by default",
|
|
126
|
+
"complete -c procsi -f",
|
|
127
|
+
"",
|
|
128
|
+
];
|
|
129
|
+
// Top-level commands
|
|
130
|
+
for (const cmd of commands) {
|
|
131
|
+
lines.push(`complete -c procsi -n '__fish_use_subcommand' -a '${escapeForShell(cmd.name)}' -d '${escapeForShell(cmd.description)}'`);
|
|
132
|
+
}
|
|
133
|
+
lines.push("");
|
|
134
|
+
// Subcommand options
|
|
135
|
+
for (const cmd of commands) {
|
|
136
|
+
for (const opt of cmd.options) {
|
|
137
|
+
const flag = opt.flags.replace(/^--/, "");
|
|
138
|
+
lines.push(`complete -c procsi -n '__fish_seen_subcommand_from ${cmd.name}' -l '${escapeForShell(flag)}' -d '${escapeForShell(opt.description)}'`);
|
|
139
|
+
}
|
|
140
|
+
for (const sub of cmd.subcommands) {
|
|
141
|
+
lines.push(`complete -c procsi -n '__fish_seen_subcommand_from ${cmd.name}' -a '${escapeForShell(sub.name)}' -d '${escapeForShell(sub.description)}'`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return lines.join("\n") + "\n";
|
|
145
|
+
}
|
|
146
|
+
export const completionsCommand = new Command("completions")
|
|
147
|
+
.description("Generate shell completion scripts")
|
|
148
|
+
.argument("<shell>", `shell type (${SUPPORTED_SHELLS.join(", ")})`)
|
|
149
|
+
.action((shell, _opts, command) => {
|
|
150
|
+
if (!SUPPORTED_SHELLS.includes(shell)) {
|
|
151
|
+
console.error(`Unsupported shell: "${shell}"`);
|
|
152
|
+
console.error(`Supported shells: ${SUPPORTED_SHELLS.join(", ")}`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
// Walk up to the root program
|
|
156
|
+
let root = command;
|
|
157
|
+
while (root.parent) {
|
|
158
|
+
root = root.parent;
|
|
159
|
+
}
|
|
160
|
+
if (shell === "zsh") {
|
|
161
|
+
console.log(generateZshCompletions(root));
|
|
162
|
+
}
|
|
163
|
+
else if (shell === "bash") {
|
|
164
|
+
console.log(generateBashCompletions(root));
|
|
165
|
+
}
|
|
166
|
+
else if (shell === "fish") {
|
|
167
|
+
console.log(generateFishCompletions(root));
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=completions.js.map
|