procsi 0.2.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +341 -214
  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.map +1 -1
  14. package/dist/cli/commands/off.js +1 -0
  15. package/dist/cli/commands/off.js.map +1 -1
  16. package/dist/cli/commands/on.d.ts.map +1 -1
  17. package/dist/cli/commands/on.js +3 -1
  18. package/dist/cli/commands/on.js.map +1 -1
  19. package/dist/cli/commands/request.d.ts +6 -0
  20. package/dist/cli/commands/request.d.ts.map +1 -0
  21. package/dist/cli/commands/request.js +216 -0
  22. package/dist/cli/commands/request.js.map +1 -0
  23. package/dist/cli/commands/requests.d.ts +6 -0
  24. package/dist/cli/commands/requests.d.ts.map +1 -0
  25. package/dist/cli/commands/requests.js +290 -0
  26. package/dist/cli/commands/requests.js.map +1 -0
  27. package/dist/cli/commands/sessions.d.ts +6 -0
  28. package/dist/cli/commands/sessions.d.ts.map +1 -0
  29. package/dist/cli/commands/sessions.js +39 -0
  30. package/dist/cli/commands/sessions.js.map +1 -0
  31. package/dist/cli/formatters/colour.d.ts +17 -0
  32. package/dist/cli/formatters/colour.d.ts.map +1 -0
  33. package/dist/cli/formatters/colour.js +23 -0
  34. package/dist/cli/formatters/colour.js.map +1 -0
  35. package/dist/cli/formatters/detail.d.ts +17 -0
  36. package/dist/cli/formatters/detail.d.ts.map +1 -0
  37. package/dist/cli/formatters/detail.js +135 -0
  38. package/dist/cli/formatters/detail.js.map +1 -0
  39. package/dist/cli/formatters/hints.d.ts +17 -0
  40. package/dist/cli/formatters/hints.d.ts.map +1 -0
  41. package/dist/cli/formatters/hints.js +29 -0
  42. package/dist/cli/formatters/hints.js.map +1 -0
  43. package/dist/cli/formatters/table.d.ts +17 -0
  44. package/dist/cli/formatters/table.d.ts.map +1 -0
  45. package/dist/cli/formatters/table.js +85 -0
  46. package/dist/cli/formatters/table.js.map +1 -0
  47. package/dist/cli/index.js +8 -0
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/cli/tui/App.d.ts.map +1 -1
  50. package/dist/cli/tui/App.js +67 -6
  51. package/dist/cli/tui/App.js.map +1 -1
  52. package/dist/cli/tui/components/AccordionPanel.d.ts.map +1 -1
  53. package/dist/cli/tui/components/AccordionPanel.js +1 -1
  54. package/dist/cli/tui/components/AccordionPanel.js.map +1 -1
  55. package/dist/cli/tui/components/EventFilterBar.d.ts +27 -0
  56. package/dist/cli/tui/components/EventFilterBar.d.ts.map +1 -0
  57. package/dist/cli/tui/components/EventFilterBar.js +145 -0
  58. package/dist/cli/tui/components/EventFilterBar.js.map +1 -0
  59. package/dist/cli/tui/components/FilterBar.d.ts.map +1 -1
  60. package/dist/cli/tui/components/FilterBar.js +34 -3
  61. package/dist/cli/tui/components/FilterBar.js.map +1 -1
  62. package/dist/cli/tui/components/HelpModal.d.ts.map +1 -1
  63. package/dist/cli/tui/components/HelpModal.js +3 -0
  64. package/dist/cli/tui/components/HelpModal.js.map +1 -1
  65. package/dist/cli/tui/components/InfoBar.d.ts +15 -0
  66. package/dist/cli/tui/components/InfoBar.d.ts.map +1 -0
  67. package/dist/cli/tui/components/InfoBar.js +45 -0
  68. package/dist/cli/tui/components/InfoBar.js.map +1 -0
  69. package/dist/cli/tui/components/InterceptorLogModal.d.ts +16 -0
  70. package/dist/cli/tui/components/InterceptorLogModal.d.ts.map +1 -0
  71. package/dist/cli/tui/components/InterceptorLogModal.js +229 -0
  72. package/dist/cli/tui/components/InterceptorLogModal.js.map +1 -0
  73. package/dist/cli/tui/components/RequestListItem.d.ts.map +1 -1
  74. package/dist/cli/tui/components/RequestListItem.js +3 -2
  75. package/dist/cli/tui/components/RequestListItem.js.map +1 -1
  76. package/dist/cli/tui/components/StatusBar.d.ts +7 -2
  77. package/dist/cli/tui/components/StatusBar.d.ts.map +1 -1
  78. package/dist/cli/tui/components/StatusBar.js +13 -6
  79. package/dist/cli/tui/components/StatusBar.js.map +1 -1
  80. package/dist/cli/tui/hooks/useInterceptorEvents.d.ts +33 -0
  81. package/dist/cli/tui/hooks/useInterceptorEvents.d.ts.map +1 -0
  82. package/dist/cli/tui/hooks/useInterceptorEvents.js +88 -0
  83. package/dist/cli/tui/hooks/useInterceptorEvents.js.map +1 -0
  84. package/dist/cli/tui/hooks/useRequests.d.ts +4 -0
  85. package/dist/cli/tui/hooks/useRequests.d.ts.map +1 -1
  86. package/dist/cli/tui/hooks/useRequests.js +36 -0
  87. package/dist/cli/tui/hooks/useRequests.js.map +1 -1
  88. package/dist/cli/tui/utils/filters.d.ts.map +1 -1
  89. package/dist/cli/tui/utils/filters.js +3 -1
  90. package/dist/cli/tui/utils/filters.js.map +1 -1
  91. package/dist/cli/utils/parse-time.d.ts +22 -0
  92. package/dist/cli/utils/parse-time.d.ts.map +1 -0
  93. package/dist/cli/utils/parse-time.js +160 -0
  94. package/dist/cli/utils/parse-time.js.map +1 -0
  95. package/dist/daemon/control.d.ts +2 -0
  96. package/dist/daemon/control.d.ts.map +1 -1
  97. package/dist/daemon/control.js +64 -2
  98. package/dist/daemon/control.js.map +1 -1
  99. package/dist/daemon/index.js +6 -1
  100. package/dist/daemon/index.js.map +1 -1
  101. package/dist/daemon/interceptor-event-log.d.ts +37 -0
  102. package/dist/daemon/interceptor-event-log.d.ts.map +1 -0
  103. package/dist/daemon/interceptor-event-log.js +163 -0
  104. package/dist/daemon/interceptor-event-log.js.map +1 -0
  105. package/dist/daemon/interceptor-loader.d.ts +3 -0
  106. package/dist/daemon/interceptor-loader.d.ts.map +1 -1
  107. package/dist/daemon/interceptor-loader.js +34 -2
  108. package/dist/daemon/interceptor-loader.js.map +1 -1
  109. package/dist/daemon/interceptor-runner.d.ts +3 -0
  110. package/dist/daemon/interceptor-runner.d.ts.map +1 -1
  111. package/dist/daemon/interceptor-runner.js +112 -8
  112. package/dist/daemon/interceptor-runner.js.map +1 -1
  113. package/dist/daemon/proxy.d.ts.map +1 -1
  114. package/dist/daemon/proxy.js +99 -4
  115. package/dist/daemon/proxy.js.map +1 -1
  116. package/dist/daemon/storage.d.ts +18 -4
  117. package/dist/daemon/storage.d.ts.map +1 -1
  118. package/dist/daemon/storage.js +111 -25
  119. package/dist/daemon/storage.js.map +1 -1
  120. package/dist/mcp/server.d.ts +3 -0
  121. package/dist/mcp/server.d.ts.map +1 -1
  122. package/dist/mcp/server.js +116 -3
  123. package/dist/mcp/server.js.map +1 -1
  124. package/dist/overrides/node.d.ts.map +1 -1
  125. package/dist/overrides/node.js +62 -0
  126. package/dist/overrides/node.js.map +1 -1
  127. package/dist/shared/constants.d.ts +10 -0
  128. package/dist/shared/constants.d.ts.map +1 -0
  129. package/dist/shared/constants.js +10 -0
  130. package/dist/shared/constants.js.map +1 -0
  131. package/dist/shared/control-client.d.ts +36 -3
  132. package/dist/shared/control-client.d.ts.map +1 -1
  133. package/dist/shared/control-client.js +27 -3
  134. package/dist/shared/control-client.js.map +1 -1
  135. package/dist/shared/process-name.d.ts +10 -0
  136. package/dist/shared/process-name.d.ts.map +1 -0
  137. package/dist/shared/process-name.js +27 -0
  138. package/dist/shared/process-name.js.map +1 -0
  139. package/dist/shared/types.d.ts +24 -0
  140. package/dist/shared/types.d.ts.map +1 -1
  141. package/package.json +2 -1
  142. package/skills/procsi/SKILL.md +5 -4
package/README.md CHANGED
@@ -4,35 +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, project-isolated HTTP proxy with a powerful CLI & MCP server. Quickly intercept, inspect & rewrite HTTP traffic from the comfort of your terminal or favourite AI agent.
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
- # In your project directory
22
+ # Configure environment e.g. HTTP_PROXY
19
23
  eval "$(procsi on)"
24
+
25
+ # Send a request
20
26
  curl https://api.example.com/users
27
+
28
+ # Open UI
21
29
  procsi tui
22
30
  ```
23
31
 
24
- Requires Node.js 20+.
25
-
26
- ## Features
27
-
28
- - **Project-scoped** — each project gets its own `.procsi/` directory with a separate daemon, database, CA cert and interceptors. No cross-project bleed.
29
- - **TypeScript interceptors** — mock, modify or observe traffic with `.ts` files. Match on anything, query past traffic from within handlers, compose complex scenarios.
30
- - **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.
31
- - **Terminal TUI** — vim-style keybindings, mouse support, JSON explorer, filtering. Stays in your terminal where you're already working.
32
- - **HTTPS** — automatic CA certificate generation and trust
33
- - **Export** — copy as curl, export as HAR, save bodies to disk
34
- - **Zero config** — works with curl, wget, Node.js, Python, Go, Rust and anything else that respects `HTTP_PROXY`
35
-
36
32
  ## Project Isolation
37
33
 
38
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/`):
@@ -50,7 +46,121 @@ your-project/
50
46
  └── src/...
51
47
  ```
52
48
 
53
- 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
+ | `source` | Filter by request source | `"node"`, `"python"` |
136
+ | `intercepted_by` | Filter by interceptor name | `"mock-users"` |
137
+ | `offset` | Pagination offset (0-based) | `0` |
138
+ | `limit` | Max results (default 50, max 500) | `100` |
139
+
140
+ `procsi_get_request` accepts comma-separated IDs for batch fetching (e.g. `"id1,id2,id3"`).
141
+
142
+ `procsi_query_json` also takes:
143
+
144
+ | Parameter | Description | Example |
145
+ | --------- | --------------------------------------------------------------------- | ------------ |
146
+ | `target` | Which body to query: `"request"`, `"response"`, or `"both"` (default) | `"response"` |
147
+ | `value` | Exact value match after JSONPath extraction | `"active"` |
148
+
149
+ ### Output Formats
150
+
151
+ All query tools accept a `format` parameter:
152
+
153
+ - `text` (default) — markdown summaries, readable by humans and AI
154
+ - `json` — structured JSON for programmatic use
155
+
156
+ ### Examples
157
+
158
+ ```
159
+ procsi_list_requests({ status_range: "5xx", path: "/api" })
160
+ procsi_search_bodies({ query: "error_code", method: "POST" })
161
+ procsi_query_json({ json_path: "$.user.id", target: "response" })
162
+ procsi_list_requests({ header_name: "authorization", header_target: "request" })
163
+ ```
54
164
 
55
165
  ## Interceptors
56
166
 
@@ -148,21 +258,21 @@ export default {
148
258
 
149
259
  ### Handler Context
150
260
 
151
- | Property | Description |
152
- |----------|-------------|
153
- | `ctx.request` | The incoming request (frozen, read-only) |
261
+ | Property | Description |
262
+ | --------------- | ----------------------------------------- |
263
+ | `ctx.request` | The incoming request (frozen, read-only) |
154
264
  | `ctx.forward()` | Forward to upstream, returns the response |
155
- | `ctx.procsi` | Query captured traffic (see below) |
156
- | `ctx.log(msg)` | Write to `.procsi/procsi.log` |
265
+ | `ctx.procsi` | Query captured traffic (see below) |
266
+ | `ctx.log(msg)` | Write to `.procsi/procsi.log` |
157
267
 
158
268
  #### `ctx.procsi`
159
269
 
160
- | Method | Description |
161
- |--------|-------------|
162
- | `countRequests(filter?)` | Count matching requests |
163
- | `listRequests({ filter?, limit?, offset? })` | List request summaries |
164
- | `getRequest(id)` | Full request details by ID |
165
- | `searchBodies({ query, ...filter? })` | Full-text search through bodies |
270
+ | Method | Description |
271
+ | -------------------------------------------- | -------------------------------------------- |
272
+ | `countRequests(filter?)` | Count matching requests |
273
+ | `listRequests({ filter?, limit?, offset? })` | List request summaries |
274
+ | `getRequest(id)` | Full request details by ID |
275
+ | `searchBodies({ query, ...filter? })` | Full-text search through bodies |
166
276
  | `queryJsonBodies({ json_path, ...filter? })` | Extract values from JSON bodies via JSONPath |
167
277
 
168
278
  ### How Interceptors Work
@@ -176,112 +286,6 @@ export default {
176
286
  - `ctx.log()` writes to `.procsi/procsi.log` since `console.log` goes nowhere in the daemon
177
287
  - Use `satisfies Interceptor` for full intellisense
178
288
 
179
- ## MCP Integration
180
-
181
- 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/`.
182
-
183
- This means you can ask things like:
184
-
185
- - "Find all failing requests to the payments API and write mocks that return valid responses"
186
- - "Make every 5th request to /api/users return a 429 so I can test rate limiting"
187
- - "What's the average response time for requests to the auth service in the last hour?"
188
- - "Write an interceptor that logs all requests with missing auth headers"
189
-
190
- The agent reads your traffic, writes the TypeScript, and procsi hot-reloads it.
191
-
192
- ### Setup
193
-
194
- Add procsi to your MCP client config:
195
-
196
- ```json
197
- {
198
- "mcpServers": {
199
- "procsi": {
200
- "command": "procsi",
201
- "args": ["mcp"]
202
- }
203
- }
204
- }
205
- ```
206
-
207
- The proxy must be running (`eval "$(procsi on)"`) — the MCP server connects to the same daemon as the TUI.
208
-
209
- ### Agent Skill
210
-
211
- 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.
212
-
213
- **Claude Code:**
214
-
215
- ```bash
216
- /plugin marketplace add mtford90/procsi
217
- /plugin install procsi
218
- ```
219
-
220
- **npm-agentskills** (works with Cursor, Copilot, Codex, etc.):
221
-
222
- ```bash
223
- npx agents export --target claude
224
- ```
225
-
226
- ### Available Tools
227
-
228
- | Tool | Description |
229
- |------|-------------|
230
- | `procsi_get_status` | Daemon status, proxy port, request count |
231
- | `procsi_list_requests` | Search and filter captured requests |
232
- | `procsi_get_request` | Full request details by ID (headers, bodies, timing) |
233
- | `procsi_search_bodies` | Full-text search through body content |
234
- | `procsi_query_json` | Extract values from JSON bodies via JSONPath |
235
- | `procsi_count_requests` | Count matching requests |
236
- | `procsi_clear_requests` | Delete all captured requests |
237
- | `procsi_list_sessions` | List active proxy sessions |
238
- | `procsi_list_interceptors` | List loaded interceptors with status and errors |
239
- | `procsi_reload_interceptors` | Reload interceptors from disk |
240
-
241
- ### Filtering
242
-
243
- Most tools accept these filters:
244
-
245
- | Parameter | Description | Example |
246
- |-----------|-------------|---------|
247
- | `method` | HTTP method(s), comma-separated | `"GET,POST"` |
248
- | `status_range` | Status code, Nxx pattern, or range | `"4xx"`, `"401"`, `"500-503"` |
249
- | `search` | Substring match on URL/path | `"api/users"` |
250
- | `host` | Exact or suffix match (prefix with `.`) | `"api.example.com"`, `".example.com"` |
251
- | `path` | Path prefix match | `"/api/v2"` |
252
- | `since` / `before` | Time window (ISO 8601) | `"2024-01-15T10:30:00Z"` |
253
- | `header_name` | Filter by header existence or value | `"content-type"` |
254
- | `header_value` | Exact header value (requires `header_name`) | `"application/json"` |
255
- | `header_target` | Which headers to search | `"request"`, `"response"`, `"both"` |
256
- | `intercepted_by` | Filter by interceptor name | `"mock-users"` |
257
- | `offset` | Pagination offset (0-based) | `0` |
258
- | `limit` | Max results (default 50, max 500) | `100` |
259
-
260
- `procsi_get_request` accepts comma-separated IDs for batch fetching (e.g. `"id1,id2,id3"`).
261
-
262
- `procsi_query_json` also takes:
263
-
264
- | Parameter | Description | Example |
265
- |-----------|-------------|---------|
266
- | `target` | Which body to query: `"request"`, `"response"`, or `"both"` (default) | `"response"` |
267
- | `value` | Exact value match after JSONPath extraction | `"active"` |
268
-
269
- ### Output Formats
270
-
271
- All query tools accept a `format` parameter:
272
-
273
- - `text` (default) — markdown summaries, readable by humans and AI
274
- - `json` — structured JSON for programmatic use
275
-
276
- ### Examples
277
-
278
- ```
279
- procsi_list_requests({ status_range: "5xx", path: "/api" })
280
- procsi_search_bodies({ query: "error_code", method: "POST" })
281
- procsi_query_json({ json_path: "$.user.id", target: "response" })
282
- procsi_list_requests({ header_name: "authorization", header_target: "request" })
283
- ```
284
-
285
289
  ## How It Works
286
290
 
287
291
  ```
@@ -323,15 +327,15 @@ procsi_list_requests({ header_name: "authorization", header_target: "request" })
323
327
 
324
328
  `eval "$(procsi on)"` sets these in your shell (`eval "$(procsi off)"` unsets them):
325
329
 
326
- | Variable | Purpose |
327
- |----------|---------|
328
- | `HTTP_PROXY` | Proxy URL for HTTP clients |
329
- | `HTTPS_PROXY` | Proxy URL for HTTPS clients |
330
- | `SSL_CERT_FILE` | CA cert path (curl, git, etc.) |
331
- | `REQUESTS_CA_BUNDLE` | CA cert path (Python requests) |
332
- | `NODE_EXTRA_CA_CERTS` | CA cert path (Node.js) |
333
- | `PROCSI_SESSION_ID` | UUID identifying the current session |
334
- | `PROCSI_LABEL` | Session label (when `-l` flag used) |
330
+ | Variable | Purpose |
331
+ | --------------------- | ------------------------------------ |
332
+ | `HTTP_PROXY` | Proxy URL for HTTP clients |
333
+ | `HTTPS_PROXY` | Proxy URL for HTTPS clients |
334
+ | `SSL_CERT_FILE` | CA cert path (curl, git, etc.) |
335
+ | `REQUESTS_CA_BUNDLE` | CA cert path (Python requests) |
336
+ | `NODE_EXTRA_CA_CERTS` | CA cert path (Node.js) |
337
+ | `PROCSI_SESSION_ID` | UUID identifying the current session |
338
+ | `PROCSI_LABEL` | Session label (when `-l` flag used) |
335
339
 
336
340
  ## Configuration
337
341
 
@@ -346,12 +350,12 @@ Create `.procsi/config.json` to override defaults. All fields are optional:
346
350
  }
347
351
  ```
348
352
 
349
- | Setting | Default | Description |
350
- |---------|---------|-------------|
351
- | `maxStoredRequests` | `5000` | Max requests in the database. Oldest evicted automatically. |
352
- | `maxBodySize` | `10485760` (10 MB) | Max body size to capture. Larger bodies are proxied but not stored. |
353
- | `maxLogSize` | `10485760` (10 MB) | Max log file size before rotation. |
354
- | `pollInterval` | `2000` | TUI polling interval in ms. Lower = faster updates, more IPC traffic. |
353
+ | Setting | Default | Description |
354
+ | ------------------- | ------------------ | --------------------------------------------------------------------- |
355
+ | `maxStoredRequests` | `5000` | Max requests in the database. Oldest evicted automatically. |
356
+ | `maxBodySize` | `10485760` (10 MB) | Max body size to capture. Larger bodies are proxied but not stored. |
357
+ | `maxLogSize` | `10485760` (10 MB) | Max log file size before rotation. |
358
+ | `pollInterval` | `2000` | TUI polling interval in ms. Lower = faster updates, more IPC traffic. |
355
359
 
356
360
  Missing or invalid values fall back to defaults.
357
361
 
@@ -359,14 +363,14 @@ Missing or invalid values fall back to defaults.
359
363
 
360
364
  Anything that respects `HTTP_PROXY` works:
361
365
 
362
- | Client | Support |
363
- |--------|---------|
364
- | curl | Automatic |
365
- | wget | Automatic |
366
+ | Client | Support |
367
+ | ---------------------------- | -------------------------- |
368
+ | curl | Automatic |
369
+ | wget | Automatic |
366
370
  | Node.js (fetch, axios, etc.) | With `NODE_EXTRA_CA_CERTS` |
367
- | Python (requests, httpx) | With `REQUESTS_CA_BUNDLE` |
368
- | Go | Automatic |
369
- | Rust (reqwest) | Automatic |
371
+ | Python (requests, httpx) | With `REQUESTS_CA_BUNDLE` |
372
+ | Go | Automatic |
373
+ | Rust (reqwest) | Automatic |
370
374
 
371
375
  ## Export
372
376
 
@@ -394,59 +398,59 @@ Mouse support: click to select, scroll to navigate, click panels to focus.
394
398
 
395
399
  ### Main View
396
400
 
397
- | Key | Action |
398
- |-----|--------|
399
- | `j`/`k` or `↑`/`↓` | Navigate up/down |
400
- | `g` / `G` | Jump to first / last item |
401
- | `Ctrl+u` / `Ctrl+d` | Half-page up / down |
402
- | `Ctrl+f` / `Ctrl+b` | Full-page down / up |
403
- | `Tab` / `Shift+Tab` | Next / previous panel |
404
- | `1`-`5` | Jump to section (list / request / request body / response / response body) |
405
- | `Enter` | Open body in full-screen viewer |
406
- | `/` | Open filter bar |
407
- | `u` | Toggle full URL display |
408
- | `c` | Copy request as curl |
409
- | `y` | Copy body to clipboard |
410
- | `s` | Export body (opens export modal) |
411
- | `H` | Export all as HAR |
412
- | `r` | Refresh |
413
- | `?` | Help |
414
- | `i` | Proxy connection info |
415
- | `q` | Quit |
401
+ | Key | Action |
402
+ | ------------------- | -------------------------------------------------------------------------- |
403
+ | `j`/`k` or `↑`/`↓` | Navigate up/down |
404
+ | `g` / `G` | Jump to first / last item |
405
+ | `Ctrl+u` / `Ctrl+d` | Half-page up / down |
406
+ | `Ctrl+f` / `Ctrl+b` | Full-page down / up |
407
+ | `Tab` / `Shift+Tab` | Next / previous panel |
408
+ | `1`-`5` | Jump to section (list / request / request body / response / response body) |
409
+ | `Enter` | Open body in full-screen viewer |
410
+ | `/` | Open filter bar |
411
+ | `u` | Toggle full URL display |
412
+ | `c` | Copy request as curl |
413
+ | `y` | Copy body to clipboard |
414
+ | `s` | Export body (opens export modal) |
415
+ | `H` | Export all as HAR |
416
+ | `r` | Refresh |
417
+ | `?` | Help |
418
+ | `i` | Proxy connection info |
419
+ | `q` | Quit |
416
420
 
417
421
  ### Filter Bar (`/`)
418
422
 
419
- | Key | Action |
420
- |-----|--------|
421
- | `Tab` / `Shift+Tab` | Cycle between search, method, status fields |
422
- | `←` / `→` | Cycle method (ALL/GET/POST/PUT/PATCH/DELETE) or status (ALL/2xx-5xx) |
423
- | `Return` | Apply filter |
424
- | `Esc` | Cancel and revert |
423
+ | Key | Action |
424
+ | ------------------- | -------------------------------------------------------------------- |
425
+ | `Tab` / `Shift+Tab` | Cycle between search, method, status fields |
426
+ | `←` / `→` | Cycle method (ALL/GET/POST/PUT/PATCH/DELETE) or status (ALL/2xx-5xx) |
427
+ | `Return` | Apply filter |
428
+ | `Esc` | Cancel and revert |
425
429
 
426
430
  ### JSON Explorer (Enter on a JSON body)
427
431
 
428
- | Key | Action |
429
- |-----|--------|
430
- | `j`/`k` | Navigate nodes |
431
- | `Enter`/`l` | Expand/collapse node |
432
- | `h` | Collapse node |
433
- | `e` / `c` | Expand / collapse all |
434
- | `/` | Filter by path |
435
- | `n` / `N` | Next / previous match |
436
- | `y` | Copy value |
437
- | `q` / `Esc` | Close |
432
+ | Key | Action |
433
+ | ----------- | --------------------- |
434
+ | `j`/`k` | Navigate nodes |
435
+ | `Enter`/`l` | Expand/collapse node |
436
+ | `h` | Collapse node |
437
+ | `e` / `c` | Expand / collapse all |
438
+ | `/` | Filter by path |
439
+ | `n` / `N` | Next / previous match |
440
+ | `y` | Copy value |
441
+ | `q` / `Esc` | Close |
438
442
 
439
443
  ### Text Viewer (Enter on a non-JSON body)
440
444
 
441
- | Key | Action |
442
- |-----|--------|
443
- | `j`/`k` | Scroll line by line |
444
- | `Space` | Page down |
445
- | `g` / `G` | Top / bottom |
446
- | `/` | Search text |
447
- | `n` / `N` | Next / previous match |
448
- | `y` | Copy to clipboard |
449
- | `q` / `Esc` | Close |
445
+ | Key | Action |
446
+ | ----------- | --------------------- |
447
+ | `j`/`k` | Scroll line by line |
448
+ | `Space` | Page down |
449
+ | `g` / `G` | Top / bottom |
450
+ | `/` | Search text |
451
+ | `n` / `N` | Next / previous match |
452
+ | `y` | Copy to clipboard |
453
+ | `q` / `Esc` | Close |
450
454
 
451
455
  </details>
452
456
 
@@ -454,10 +458,10 @@ Mouse support: click to select, scroll to navigate, click panels to focus.
454
458
 
455
459
  ### Global Options
456
460
 
457
- | Flag | Description |
458
- |------|-------------|
459
- | `-v, --verbose` | Increase log verbosity (stackable: `-vv`, `-vvv`) |
460
- | `-d, --dir <path>` | Override project root directory |
461
+ | Flag | Description |
462
+ | ------------------ | ------------------------------------------------- |
463
+ | `-v, --verbose` | Increase log verbosity (stackable: `-vv`, `-vvv`) |
464
+ | `-d, --dir <path>` | Override project root directory |
461
465
 
462
466
  ### `procsi on`
463
467
 
@@ -469,10 +473,11 @@ eval "$(procsi on)"
469
473
 
470
474
  If run directly in a TTY (without `eval`), shows usage instructions.
471
475
 
472
- | Flag | Description |
473
- |------|-------------|
474
- | `-l, --label <label>` | Label this session (visible in TUI and MCP) |
475
- | `--no-restart` | Don't auto-restart daemon on version mismatch |
476
+ | Flag | Description |
477
+ | --------------------- | --------------------------------------------- |
478
+ | `-l, --label <label>` | Label this session (visible in TUI and MCP) |
479
+ | `-s, --source <name>` | Label the source process (auto-detected from PID if omitted) |
480
+ | `--no-restart` | Don't auto-restart daemon on version mismatch |
476
481
 
477
482
  ### `procsi off`
478
483
 
@@ -486,8 +491,8 @@ eval "$(procsi off)"
486
491
 
487
492
  Open the interactive TUI.
488
493
 
489
- | Flag | Description |
490
- |------|-------------|
494
+ | Flag | Description |
495
+ | ------ | ------------------------------------------- |
491
496
  | `--ci` | CI mode: render once and exit (for testing) |
492
497
 
493
498
  ### `procsi status`
@@ -502,6 +507,95 @@ Stop the daemon.
502
507
 
503
508
  Restart the daemon (or start it if not running).
504
509
 
510
+ ### `procsi requests`
511
+
512
+ List and filter captured requests. Output is a colour-coded table with short IDs — pipe to other tools or use `--json` for structured output.
513
+
514
+ ```bash
515
+ procsi requests # list recent (default limit 50)
516
+ procsi requests --method GET,POST # filter by method
517
+ procsi requests --status 4xx # filter by status range
518
+ procsi requests --host api.example.com # filter by host
519
+ procsi requests --path /api/v2 # filter by path prefix
520
+ procsi requests --search "keyword" # substring match on URL
521
+ procsi requests --since 5m # last 5 minutes
522
+ procsi requests --since yesterday # since midnight yesterday
523
+ procsi requests --since 10am --before 11am # time window
524
+ procsi requests --header "content-type:application/json" # header filter
525
+ procsi requests --intercepted-by mock-users # interceptor filter
526
+ procsi requests --limit 100 --offset 50 # pagination
527
+ procsi requests --json # JSON output
528
+ ```
529
+
530
+ | Flag | Description |
531
+ | -------------------------- | -------------------------------------------------------- |
532
+ | `--method <methods>` | Filter by HTTP method (comma-separated) |
533
+ | `--status <range>` | Status range: `2xx`, `4xx`, exact `401`, etc. |
534
+ | `--host <host>` | Filter by hostname |
535
+ | `--path <prefix>` | Filter by path prefix |
536
+ | `--search <text>` | Substring match on URL |
537
+ | `--since <time>` | Since time (5m, 2h, 10am, yesterday, monday, 2024-01-01) |
538
+ | `--before <time>` | Before time (same formats as --since) |
539
+ | `--header <spec>` | Header name or name:value |
540
+ | `--header-target <target>` | `request`, `response`, or `both` (default) |
541
+ | `--source <name>` | Filter by request source (e.g. node, python) |
542
+ | `--intercepted-by <name>` | Filter by interceptor name |
543
+ | `--limit <n>` | Max results (default 50) |
544
+ | `--offset <n>` | Skip results (default 0) |
545
+ | `--json` | JSON output |
546
+
547
+ #### `procsi requests search <query>`
548
+
549
+ Full-text search through request and response bodies.
550
+
551
+ #### `procsi requests query <jsonpath>`
552
+
553
+ Query JSON bodies using JSONPath expressions (e.g. `$.data.id`). Supports `--value`, `--target` (request/response/both).
554
+
555
+ #### `procsi requests count`
556
+
557
+ Count requests matching the current filters.
558
+
559
+ #### `procsi requests clear`
560
+
561
+ Clear all captured requests. Prompts for confirmation unless `--yes` is passed.
562
+
563
+ ### `procsi request <id>`
564
+
565
+ View a single request in detail. Accepts full UUIDs or abbreviated prefixes (first 7+ characters).
566
+
567
+ ```bash
568
+ procsi request a1b2c3d # full detail view
569
+ procsi request a1b2c3d --json # JSON output
570
+ ```
571
+
572
+ #### `procsi request <id> body`
573
+
574
+ Dump the response body to stdout (raw, pipeable). Use `--request` for the request body instead.
575
+
576
+ ```bash
577
+ procsi request a1b2c3d body # response body
578
+ procsi request a1b2c3d body --request # request body
579
+ procsi request a1b2c3d body | jq . # pipe to jq
580
+ ```
581
+
582
+ #### `procsi request <id> export <format>`
583
+
584
+ Export a request as `curl` or `har`.
585
+
586
+ ```bash
587
+ procsi request a1b2c3d export curl
588
+ procsi request a1b2c3d export har
589
+ ```
590
+
591
+ ### `procsi sessions`
592
+
593
+ List active proxy sessions.
594
+
595
+ | Flag | Description |
596
+ | -------- | ----------- |
597
+ | `--json` | JSON output |
598
+
505
599
  ### `procsi clear`
506
600
 
507
601
  Clear all captured requests.
@@ -530,6 +624,41 @@ Scaffold an example interceptor in `.procsi/interceptors/`.
530
624
 
531
625
  Reload interceptors from disk without restarting the daemon.
532
626
 
627
+ ### `procsi interceptors logs`
628
+
629
+ View the interceptor event log. Events include match results, mock responses, errors, timeouts, and `ctx.log()` output.
630
+
631
+ ```bash
632
+ procsi interceptors logs # recent events
633
+ procsi interceptors logs --name mock-users # filter by interceptor
634
+ procsi interceptors logs --level error # filter by level
635
+ procsi interceptors logs --limit 100 # more results
636
+ procsi interceptors logs --follow # live tail (Ctrl+C to stop)
637
+ procsi interceptors logs --follow --json # live tail as NDJSON
638
+ ```
639
+
640
+ | Flag | Description |
641
+ | ---------------------- | ----------------------------------- |
642
+ | `--name <interceptor>` | Filter by interceptor name |
643
+ | `--level <level>` | Filter by level (info, warn, error) |
644
+ | `--limit <n>` | Max events (default 50) |
645
+ | `--follow` | Live tail — poll for new events |
646
+ | `--json` | JSON output |
647
+
648
+ #### `procsi interceptors logs clear`
649
+
650
+ Clear the interceptor event log.
651
+
652
+ ### `procsi completions <shell>`
653
+
654
+ Generate shell completion scripts. Supports `zsh`, `bash`, and `fish`.
655
+
656
+ ```bash
657
+ eval "$(procsi completions zsh)" # add to .zshrc
658
+ eval "$(procsi completions bash)" # add to .bashrc
659
+ procsi completions fish | source # add to fish config
660
+ ```
661
+
533
662
  ## Development
534
663
 
535
664
  ```bash
@@ -564,13 +693,11 @@ procsi daemon stop
564
693
  eval "$(procsi on)"
565
694
  ```
566
695
 
567
- ### Terminal too small
568
-
569
- The TUI needs at least 60 columns by 10 rows.
570
-
571
696
  ### Requests not appearing
572
697
 
573
- Your HTTP client needs to respect proxy environment variables. Browsers typically don't — use curl, wget, or language-level HTTP clients instead.
698
+ Your HTTP client needs to respect proxy environment variables.
699
+
700
+ There are workarounds implemented for node - e.g. fetch override. Other libraries in different environments may need a similar treatment.
574
701
 
575
702
  ## Licence
576
703