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.
Files changed (115) hide show
  1. package/README.md +264 -148
  2. package/dist/cli/commands/completions.d.ts +9 -0
  3. package/dist/cli/commands/completions.d.ts.map +1 -0
  4. package/dist/cli/commands/completions.js +170 -0
  5. package/dist/cli/commands/completions.js.map +1 -0
  6. package/dist/cli/commands/helpers.d.ts +9 -0
  7. package/dist/cli/commands/helpers.d.ts.map +1 -1
  8. package/dist/cli/commands/helpers.js +19 -1
  9. package/dist/cli/commands/helpers.js.map +1 -1
  10. package/dist/cli/commands/interceptors.d.ts.map +1 -1
  11. package/dist/cli/commands/interceptors.js +142 -0
  12. package/dist/cli/commands/interceptors.js.map +1 -1
  13. package/dist/cli/commands/off.d.ts +0 -5
  14. package/dist/cli/commands/off.d.ts.map +1 -1
  15. package/dist/cli/commands/off.js +24 -23
  16. package/dist/cli/commands/off.js.map +1 -1
  17. package/dist/cli/commands/on.d.ts +27 -0
  18. package/dist/cli/commands/on.d.ts.map +1 -1
  19. package/dist/cli/commands/on.js +71 -17
  20. package/dist/cli/commands/on.js.map +1 -1
  21. package/dist/cli/commands/request.d.ts +6 -0
  22. package/dist/cli/commands/request.d.ts.map +1 -0
  23. package/dist/cli/commands/request.js +160 -0
  24. package/dist/cli/commands/request.js.map +1 -0
  25. package/dist/cli/commands/requests.d.ts +6 -0
  26. package/dist/cli/commands/requests.d.ts.map +1 -0
  27. package/dist/cli/commands/requests.js +282 -0
  28. package/dist/cli/commands/requests.js.map +1 -0
  29. package/dist/cli/commands/sessions.d.ts +6 -0
  30. package/dist/cli/commands/sessions.d.ts.map +1 -0
  31. package/dist/cli/commands/sessions.js +39 -0
  32. package/dist/cli/commands/sessions.js.map +1 -0
  33. package/dist/cli/formatters/colour.d.ts +17 -0
  34. package/dist/cli/formatters/colour.d.ts.map +1 -0
  35. package/dist/cli/formatters/colour.js +23 -0
  36. package/dist/cli/formatters/colour.js.map +1 -0
  37. package/dist/cli/formatters/detail.d.ts +17 -0
  38. package/dist/cli/formatters/detail.d.ts.map +1 -0
  39. package/dist/cli/formatters/detail.js +128 -0
  40. package/dist/cli/formatters/detail.js.map +1 -0
  41. package/dist/cli/formatters/hints.d.ts +17 -0
  42. package/dist/cli/formatters/hints.d.ts.map +1 -0
  43. package/dist/cli/formatters/hints.js +29 -0
  44. package/dist/cli/formatters/hints.js.map +1 -0
  45. package/dist/cli/formatters/table.d.ts +17 -0
  46. package/dist/cli/formatters/table.d.ts.map +1 -0
  47. package/dist/cli/formatters/table.js +75 -0
  48. package/dist/cli/formatters/table.js.map +1 -0
  49. package/dist/cli/index.js +12 -4
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/cli/tui/App.d.ts.map +1 -1
  52. package/dist/cli/tui/App.js +24 -5
  53. package/dist/cli/tui/App.js.map +1 -1
  54. package/dist/cli/tui/components/EventFilterBar.d.ts +27 -0
  55. package/dist/cli/tui/components/EventFilterBar.d.ts.map +1 -0
  56. package/dist/cli/tui/components/EventFilterBar.js +145 -0
  57. package/dist/cli/tui/components/EventFilterBar.js.map +1 -0
  58. package/dist/cli/tui/components/HelpModal.d.ts.map +1 -1
  59. package/dist/cli/tui/components/HelpModal.js +1 -0
  60. package/dist/cli/tui/components/HelpModal.js.map +1 -1
  61. package/dist/cli/tui/components/InfoBar.d.ts +15 -0
  62. package/dist/cli/tui/components/InfoBar.d.ts.map +1 -0
  63. package/dist/cli/tui/components/InfoBar.js +45 -0
  64. package/dist/cli/tui/components/InfoBar.js.map +1 -0
  65. package/dist/cli/tui/components/InfoModal.js +1 -1
  66. package/dist/cli/tui/components/InfoModal.js.map +1 -1
  67. package/dist/cli/tui/components/InterceptorLogModal.d.ts +16 -0
  68. package/dist/cli/tui/components/InterceptorLogModal.d.ts.map +1 -0
  69. package/dist/cli/tui/components/InterceptorLogModal.js +229 -0
  70. package/dist/cli/tui/components/InterceptorLogModal.js.map +1 -0
  71. package/dist/cli/tui/components/RequestList.js +1 -1
  72. package/dist/cli/tui/components/RequestList.js.map +1 -1
  73. package/dist/cli/tui/components/StatusBar.d.ts +7 -2
  74. package/dist/cli/tui/components/StatusBar.d.ts.map +1 -1
  75. package/dist/cli/tui/components/StatusBar.js +11 -6
  76. package/dist/cli/tui/components/StatusBar.js.map +1 -1
  77. package/dist/cli/tui/hooks/useInterceptorEvents.d.ts +33 -0
  78. package/dist/cli/tui/hooks/useInterceptorEvents.d.ts.map +1 -0
  79. package/dist/cli/tui/hooks/useInterceptorEvents.js +88 -0
  80. package/dist/cli/tui/hooks/useInterceptorEvents.js.map +1 -0
  81. package/dist/cli/tui/hooks/useRequests.js +2 -2
  82. package/dist/cli/tui/hooks/useRequests.js.map +1 -1
  83. package/dist/cli/utils/parse-time.d.ts +22 -0
  84. package/dist/cli/utils/parse-time.d.ts.map +1 -0
  85. package/dist/cli/utils/parse-time.js +160 -0
  86. package/dist/cli/utils/parse-time.js.map +1 -0
  87. package/dist/daemon/control.d.ts +2 -0
  88. package/dist/daemon/control.d.ts.map +1 -1
  89. package/dist/daemon/control.js +41 -1
  90. package/dist/daemon/control.js.map +1 -1
  91. package/dist/daemon/index.js +5 -0
  92. package/dist/daemon/index.js.map +1 -1
  93. package/dist/daemon/interceptor-event-log.d.ts +37 -0
  94. package/dist/daemon/interceptor-event-log.d.ts.map +1 -0
  95. package/dist/daemon/interceptor-event-log.js +163 -0
  96. package/dist/daemon/interceptor-event-log.js.map +1 -0
  97. package/dist/daemon/interceptor-loader.d.ts +3 -0
  98. package/dist/daemon/interceptor-loader.d.ts.map +1 -1
  99. package/dist/daemon/interceptor-loader.js +29 -2
  100. package/dist/daemon/interceptor-loader.js.map +1 -1
  101. package/dist/daemon/interceptor-runner.d.ts +3 -0
  102. package/dist/daemon/interceptor-runner.d.ts.map +1 -1
  103. package/dist/daemon/interceptor-runner.js +112 -8
  104. package/dist/daemon/interceptor-runner.js.map +1 -1
  105. package/dist/mcp/server.d.ts.map +1 -1
  106. package/dist/mcp/server.js +51 -1
  107. package/dist/mcp/server.js.map +1 -1
  108. package/dist/shared/control-client.d.ts +22 -1
  109. package/dist/shared/control-client.d.ts.map +1 -1
  110. package/dist/shared/control-client.js +12 -0
  111. package/dist/shared/control-client.js.map +1 -1
  112. package/dist/shared/types.d.ts +14 -0
  113. package/dist/shared/types.d.ts.map +1 -1
  114. package/package.json +1 -1
  115. package/skills/procsi/SKILL.md +2 -3
package/README.md CHANGED
@@ -4,48 +4,31 @@
4
4
  [![CI](https://github.com/mtford90/procsi/actions/workflows/ci.yml/badge.svg)](https://github.com/mtford90/procsi/actions/workflows/ci.yml)
5
5
  [![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
6
6
 
7
- HTTP interception for the terminal. Each project gets its own proxy, its own traffic database, its own mocks all in a `.procsi/` directory that lives alongside your code.
7
+ Procsi is a terminal-based HTTP proxy with a powerful MCP server. Quickly intercept, inspect & rewrite HTTP traffic.
8
8
 
9
9
  ![procsi demo](demo.gif)
10
10
 
11
- No browser extensions, no global system proxy, no separate apps. A MITM proxy captures your traffic, a lazygit-style TUI lets you browse it, TypeScript files let you mock it, and AI agents can query and manipulate all of it via MCP.
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
- # One-time shell setup
19
- eval "$(procsi init)"
22
+ # Configure environment e.g. HTTP_PROXY
23
+ eval "$(procsi on)"
20
24
 
21
- # In your project directory
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
- ### Shell Setup
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, separate database, separate certificates. You can run procsi in multiple projects at the same time without them interfering with each other.
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` (via the shell wrapper) starts a daemon, sets `HTTP_PROXY`/`HTTPS_PROXY` in your shell, and captures everything that flows through. `procsi off` unsets them. The TUI connects to the daemon via Unix socket.
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 (`procsi off` unsets them). Without the shell wrapper, use `eval "$(procsi vars)"` and `eval "$(procsi vars --clear)"`:
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 init`
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 set proxy environment variables. Use with `eval`:
467
+ Output shell `export` statements to start intercepting HTTP traffic. Use with `eval`:
482
468
 
483
469
  ```bash
484
- eval "$(procsi vars)"
470
+ eval "$(procsi on)"
485
471
  ```
486
472
 
487
- With the shell wrapper from `procsi init`, you can use the simpler `procsi on` instead.
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
- | `--clear` | Output `unset` statements to stop interception |
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
- procsi on # or: eval "$(procsi vars)"
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. Browsers typically don't — use curl, wget, or language-level HTTP clients instead.
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