procsi 0.3.1 → 0.4.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 (107) hide show
  1. package/README.md +77 -498
  2. package/dist/cli/commands/daemon.d.ts.map +1 -1
  3. package/dist/cli/commands/daemon.js +1 -0
  4. package/dist/cli/commands/daemon.js.map +1 -1
  5. package/dist/cli/commands/off.d.ts.map +1 -1
  6. package/dist/cli/commands/off.js +12 -2
  7. package/dist/cli/commands/off.js.map +1 -1
  8. package/dist/cli/commands/on.d.ts +33 -0
  9. package/dist/cli/commands/on.d.ts.map +1 -1
  10. package/dist/cli/commands/on.js +94 -4
  11. package/dist/cli/commands/on.js.map +1 -1
  12. package/dist/cli/commands/request.d.ts.map +1 -1
  13. package/dist/cli/commands/request.js +61 -5
  14. package/dist/cli/commands/request.js.map +1 -1
  15. package/dist/cli/commands/requests.d.ts.map +1 -1
  16. package/dist/cli/commands/requests.js +9 -1
  17. package/dist/cli/commands/requests.js.map +1 -1
  18. package/dist/cli/formatters/detail.d.ts.map +1 -1
  19. package/dist/cli/formatters/detail.js +9 -2
  20. package/dist/cli/formatters/detail.js.map +1 -1
  21. package/dist/cli/formatters/table.d.ts.map +1 -1
  22. package/dist/cli/formatters/table.js +11 -1
  23. package/dist/cli/formatters/table.js.map +1 -1
  24. package/dist/cli/tui/App.d.ts.map +1 -1
  25. package/dist/cli/tui/App.js +43 -1
  26. package/dist/cli/tui/App.js.map +1 -1
  27. package/dist/cli/tui/components/AccordionPanel.d.ts.map +1 -1
  28. package/dist/cli/tui/components/AccordionPanel.js +1 -1
  29. package/dist/cli/tui/components/AccordionPanel.js.map +1 -1
  30. package/dist/cli/tui/components/FilterBar.d.ts.map +1 -1
  31. package/dist/cli/tui/components/FilterBar.js +34 -3
  32. package/dist/cli/tui/components/FilterBar.js.map +1 -1
  33. package/dist/cli/tui/components/HelpModal.d.ts.map +1 -1
  34. package/dist/cli/tui/components/HelpModal.js +2 -0
  35. package/dist/cli/tui/components/HelpModal.js.map +1 -1
  36. package/dist/cli/tui/components/RequestListItem.d.ts.map +1 -1
  37. package/dist/cli/tui/components/RequestListItem.js +3 -2
  38. package/dist/cli/tui/components/RequestListItem.js.map +1 -1
  39. package/dist/cli/tui/components/StatusBar.d.ts.map +1 -1
  40. package/dist/cli/tui/components/StatusBar.js +2 -0
  41. package/dist/cli/tui/components/StatusBar.js.map +1 -1
  42. package/dist/cli/tui/hooks/useRequests.d.ts +4 -0
  43. package/dist/cli/tui/hooks/useRequests.d.ts.map +1 -1
  44. package/dist/cli/tui/hooks/useRequests.js +36 -0
  45. package/dist/cli/tui/hooks/useRequests.js.map +1 -1
  46. package/dist/cli/tui/utils/filters.d.ts.map +1 -1
  47. package/dist/cli/tui/utils/filters.js +3 -1
  48. package/dist/cli/tui/utils/filters.js.map +1 -1
  49. package/dist/daemon/control.d.ts.map +1 -1
  50. package/dist/daemon/control.js +23 -1
  51. package/dist/daemon/control.js.map +1 -1
  52. package/dist/daemon/index.js +35 -3
  53. package/dist/daemon/index.js.map +1 -1
  54. package/dist/daemon/interceptor-loader.d.ts.map +1 -1
  55. package/dist/daemon/interceptor-loader.js +5 -0
  56. package/dist/daemon/interceptor-loader.js.map +1 -1
  57. package/dist/daemon/proxy.d.ts.map +1 -1
  58. package/dist/daemon/proxy.js +99 -4
  59. package/dist/daemon/proxy.js.map +1 -1
  60. package/dist/daemon/storage.d.ts +18 -4
  61. package/dist/daemon/storage.d.ts.map +1 -1
  62. package/dist/daemon/storage.js +111 -25
  63. package/dist/daemon/storage.js.map +1 -1
  64. package/dist/mcp/server.d.ts +3 -0
  65. package/dist/mcp/server.d.ts.map +1 -1
  66. package/dist/mcp/server.js +65 -2
  67. package/dist/mcp/server.js.map +1 -1
  68. package/dist/overrides/node.d.ts.map +1 -1
  69. package/dist/overrides/node.js +62 -0
  70. package/dist/overrides/node.js.map +1 -1
  71. package/dist/overrides/php.d.ts +15 -0
  72. package/dist/overrides/php.d.ts.map +1 -0
  73. package/dist/overrides/php.js +29 -0
  74. package/dist/overrides/php.js.map +1 -0
  75. package/dist/overrides/python.d.ts +19 -0
  76. package/dist/overrides/python.d.ts.map +1 -0
  77. package/dist/overrides/python.js +74 -0
  78. package/dist/overrides/python.js.map +1 -0
  79. package/dist/overrides/ruby.d.ts +17 -0
  80. package/dist/overrides/ruby.d.ts.map +1 -0
  81. package/dist/overrides/ruby.js +55 -0
  82. package/dist/overrides/ruby.js.map +1 -0
  83. package/dist/shared/constants.d.ts +10 -0
  84. package/dist/shared/constants.d.ts.map +1 -0
  85. package/dist/shared/constants.js +10 -0
  86. package/dist/shared/constants.js.map +1 -0
  87. package/dist/shared/control-client.d.ts +15 -3
  88. package/dist/shared/control-client.d.ts.map +1 -1
  89. package/dist/shared/control-client.js +15 -3
  90. package/dist/shared/control-client.js.map +1 -1
  91. package/dist/shared/daemon.js +1 -0
  92. package/dist/shared/daemon.js.map +1 -1
  93. package/dist/shared/process-name.d.ts +10 -0
  94. package/dist/shared/process-name.d.ts.map +1 -0
  95. package/dist/shared/process-name.js +27 -0
  96. package/dist/shared/process-name.js.map +1 -0
  97. package/dist/shared/project.d.ts +4 -0
  98. package/dist/shared/project.d.ts.map +1 -1
  99. package/dist/shared/project.js +4 -0
  100. package/dist/shared/project.js.map +1 -1
  101. package/dist/shared/proxy-info.d.ts.map +1 -1
  102. package/dist/shared/proxy-info.js +5 -0
  103. package/dist/shared/proxy-info.js.map +1 -1
  104. package/dist/shared/types.d.ts +10 -0
  105. package/dist/shared/types.d.ts.map +1 -1
  106. package/package.json +2 -1
  107. package/skills/procsi/SKILL.md +5 -4
package/README.md CHANGED
@@ -4,13 +4,13 @@
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
- Procsi is a terminal-based HTTP proxy with a powerful MCP server. Quickly intercept, inspect & rewrite HTTP traffic.
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
11
  ## Feature Highlights
12
12
 
13
- - **Project isolation** — each project gets its own `.procsi/` directory with a separate daemon, database, CA cert and interceptors.
13
+ - **Project isolation** — each project gets its own `.procsi/` directory with a separate daemon, database, CA cert and interceptors
14
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
15
  - **Interceptors** — mock, modify or observe traffic with `.ts` files. Match on anything, query past traffic from within handlers, compose complex scenarios.
16
16
 
@@ -56,17 +56,7 @@ Separate daemon, database, certificates etc. You can run procsi in multiple proj
56
56
 
57
57
  ## MCP Integration
58
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.
59
+ procsi has a built-in [MCP](https://modelcontextprotocol.io/) server that gives AI agents full access to your captured traffic and interceptor system.
70
60
 
71
61
  ### Setup
72
62
 
@@ -85,95 +75,27 @@ Add procsi to your MCP client config:
85
75
 
86
76
  The proxy must be running (`eval "$(procsi on)"`) — the MCP server connects to the same daemon as the TUI.
87
77
 
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
78
  ### Available Tools
106
79
 
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
- ```
80
+ | Tool | Description |
81
+ | ---------------------------- | ---------------------------------------------------- |
82
+ | `procsi_get_status` | Daemon status, proxy port, request count |
83
+ | `procsi_list_requests` | Search and filter captured requests |
84
+ | `procsi_get_request` | Full request details by ID (headers, bodies, timing) |
85
+ | `procsi_search_bodies` | Full-text search through body content |
86
+ | `procsi_query_json` | Extract values from JSON bodies via JSONPath |
87
+ | `procsi_count_requests` | Count matching requests |
88
+ | `procsi_clear_requests` | Delete all captured requests |
89
+ | `procsi_list_sessions` | List active proxy sessions |
90
+ | `procsi_list_interceptors` | List loaded interceptors with status and errors |
91
+ | `procsi_reload_interceptors` | Reload interceptors from disk |
92
+
93
+ See [full MCP documentation](docs/mcp.md) for filtering, output formats, and examples.
163
94
 
164
95
  ## Interceptors
165
96
 
166
97
  TypeScript files in `.procsi/interceptors/` that intercept HTTP traffic as it passes through the proxy. They can return mock responses, modify upstream responses, or just observe.
167
98
 
168
- ```bash
169
- procsi interceptors init # scaffold an example
170
- procsi interceptors reload # reload after editing
171
- ```
172
-
173
- ### Mock
174
-
175
- Return a response without hitting upstream:
176
-
177
99
  ```typescript
178
100
  import type { Interceptor } from "procsi/interceptors";
179
101
 
@@ -188,102 +110,7 @@ export default {
188
110
  } satisfies Interceptor;
189
111
  ```
190
112
 
191
- ### Modify
192
-
193
- Forward to upstream, then alter the response:
194
-
195
- ```typescript
196
- import type { Interceptor } from "procsi/interceptors";
197
-
198
- export default {
199
- name: "inject-header",
200
- match: (req) => req.host.includes("example.com"),
201
- handler: async (ctx) => {
202
- const response = await ctx.forward();
203
- return { ...response, headers: { ...response.headers, "x-debug": "procsi" } };
204
- },
205
- } satisfies Interceptor;
206
- ```
207
-
208
- ### Observe
209
-
210
- Log traffic without altering it:
211
-
212
- ```typescript
213
- import type { Interceptor } from "procsi/interceptors";
214
-
215
- export default {
216
- name: "log-api",
217
- match: (req) => req.path.startsWith("/api/"),
218
- handler: async (ctx) => {
219
- ctx.log(`${ctx.request.method} ${ctx.request.url}`);
220
- const response = await ctx.forward();
221
- ctx.log(` -> ${response.status}`);
222
- return response;
223
- },
224
- } satisfies Interceptor;
225
- ```
226
-
227
- ### Query Past Traffic
228
-
229
- Interceptors can query the traffic database via `ctx.procsi`. This lets you build mocks that react to what's already happened — rate limiting, conditional failures, responses based on prior requests:
230
-
231
- ```typescript
232
- import type { Interceptor } from "procsi/interceptors";
233
-
234
- export default {
235
- name: "rate-limit",
236
- match: (req) => req.path.startsWith("/api/"),
237
- handler: async (ctx) => {
238
- // Count how many requests this endpoint has seen in the last minute
239
- const since = new Date(Date.now() - 60_000).toISOString();
240
- const count = await ctx.procsi.countRequests({
241
- path: ctx.request.path,
242
- since,
243
- });
244
-
245
- if (count >= 10) {
246
- return {
247
- status: 429,
248
- headers: { "retry-after": "60" },
249
- body: JSON.stringify({ error: "rate_limited" }),
250
- };
251
- }
252
-
253
- return ctx.forward();
254
- },
255
- } satisfies Interceptor;
256
- ```
257
-
258
- ### Handler Context
259
-
260
- | Property | Description |
261
- |----------|-------------|
262
- | `ctx.request` | The incoming request (frozen, read-only) |
263
- | `ctx.forward()` | Forward to upstream, returns the response |
264
- | `ctx.procsi` | Query captured traffic (see below) |
265
- | `ctx.log(msg)` | Write to `.procsi/procsi.log` |
266
-
267
- #### `ctx.procsi`
268
-
269
- | Method | Description |
270
- |--------|-------------|
271
- | `countRequests(filter?)` | Count matching requests |
272
- | `listRequests({ filter?, limit?, offset? })` | List request summaries |
273
- | `getRequest(id)` | Full request details by ID |
274
- | `searchBodies({ query, ...filter? })` | Full-text search through bodies |
275
- | `queryJsonBodies({ json_path, ...filter? })` | Extract values from JSON bodies via JSONPath |
276
-
277
- ### How Interceptors Work
278
-
279
- - Any `.ts` file in `.procsi/interceptors/` is loaded automatically
280
- - Files load alphabetically; first match wins
281
- - `match` is optional — omit it to match everything
282
- - Hot-reloads on file changes, or run `procsi interceptors reload`
283
- - 30s handler timeout, 5s match timeout
284
- - Errors fall through gracefully (never crashes the proxy)
285
- - `ctx.log()` writes to `.procsi/procsi.log` since `console.log` goes nowhere in the daemon
286
- - Use `satisfies Interceptor` for full intellisense
113
+ See [full interceptors documentation](docs/interceptors.md) for modify, observe, querying past traffic, handler context, and how they work.
287
114
 
288
115
  ## How It Works
289
116
 
@@ -326,19 +153,27 @@ export default {
326
153
 
327
154
  `eval "$(procsi on)"` sets these in your shell (`eval "$(procsi off)"` unsets them):
328
155
 
329
- | Variable | Purpose |
330
- |----------|---------|
331
- | `HTTP_PROXY` | Proxy URL for HTTP clients |
332
- | `HTTPS_PROXY` | Proxy URL for HTTPS clients |
333
- | `SSL_CERT_FILE` | CA cert path (curl, git, etc.) |
334
- | `REQUESTS_CA_BUNDLE` | CA cert path (Python requests) |
335
- | `NODE_EXTRA_CA_CERTS` | CA cert path (Node.js) |
336
- | `PROCSI_SESSION_ID` | UUID identifying the current session |
337
- | `PROCSI_LABEL` | Session label (when `-l` flag used) |
156
+ | Variable | Purpose |
157
+ | --------------------- | ------------------------------------ |
158
+ | `HTTP_PROXY` | Proxy URL for HTTP clients |
159
+ | `HTTPS_PROXY` | Proxy URL for HTTPS clients |
160
+ | `SSL_CERT_FILE` | CA cert path (curl, OpenSSL) |
161
+ | `REQUESTS_CA_BUNDLE` | CA cert path (Python requests) |
162
+ | `CURL_CA_BUNDLE` | CA cert path (curl/Python fallback) |
163
+ | `NODE_EXTRA_CA_CERTS` | CA cert path (Node.js) |
164
+ | `DENO_CERT` | CA cert path (Deno) |
165
+ | `CARGO_HTTP_CAINFO` | CA cert path (Rust Cargo) |
166
+ | `GIT_SSL_CAINFO` | CA cert path (Git) |
167
+ | `AWS_CA_BUNDLE` | CA cert path (AWS CLI) |
168
+ | `CGI_HTTP_PROXY` | Proxy URL (PHP CGI, HTTPoxy-safe) |
169
+ | `PROCSI_SESSION_ID` | UUID identifying the current session |
170
+ | `PROCSI_LABEL` | Session label (when `-l` flag used) |
171
+
172
+ Additionally, `procsi on` sets `PYTHONPATH`, `RUBYOPT`, and `PHP_INI_SCAN_DIR` to load runtime-specific override scripts that ensure edge-case HTTP clients trust the proxy CA.
338
173
 
339
174
  ## Configuration
340
175
 
341
- Create `.procsi/config.json` to override defaults. All fields are optional:
176
+ Create `.procsi/config.json` to override defaults:
342
177
 
343
178
  ```json
344
179
  {
@@ -349,312 +184,58 @@ Create `.procsi/config.json` to override defaults. All fields are optional:
349
184
  }
350
185
  ```
351
186
 
352
- | Setting | Default | Description |
353
- |---------|---------|-------------|
354
- | `maxStoredRequests` | `5000` | Max requests in the database. Oldest evicted automatically. |
355
- | `maxBodySize` | `10485760` (10 MB) | Max body size to capture. Larger bodies are proxied but not stored. |
356
- | `maxLogSize` | `10485760` (10 MB) | Max log file size before rotation. |
357
- | `pollInterval` | `2000` | TUI polling interval in ms. Lower = faster updates, more IPC traffic. |
358
-
359
- Missing or invalid values fall back to defaults.
187
+ See [full configuration documentation](docs/configuration.md) for details on each setting.
360
188
 
361
189
  ## Supported HTTP Clients
362
190
 
363
- Anything that respects `HTTP_PROXY` works:
364
-
365
- | Client | Support |
366
- |--------|---------|
367
- | curl | Automatic |
368
- | wget | Automatic |
369
- | Node.js (fetch, axios, etc.) | With `NODE_EXTRA_CA_CERTS` |
370
- | Python (requests, httpx) | With `REQUESTS_CA_BUNDLE` |
371
- | Go | Automatic |
372
- | Rust (reqwest) | Automatic |
373
-
374
- ## Export
375
-
376
- Press `c` to copy a request as curl:
377
-
378
- ```bash
379
- curl -X POST 'https://api.example.com/users' \
380
- -H 'Content-Type: application/json' \
381
- -H 'Authorization: Bearer token123' \
382
- -d '{"name": "test"}'
383
- ```
384
-
385
- Press `H` to export all requests as a HAR file. Compatible with browser dev tools.
386
-
387
- Press `s` on a body to open the export modal — clipboard, `.procsi/exports/`, `~/Downloads/`, custom path, or open in default application.
388
-
389
- ## TUI Keybindings
390
-
391
- `j`/`k` to navigate, `Tab` to switch panels, `/` to filter, `c` to copy as curl, `Enter` to inspect bodies, `q` to quit.
392
-
393
- Mouse support: click to select, scroll to navigate, click panels to focus.
191
+ Anything that respects `HTTP_PROXY` works. procsi sets the right CA cert env vars for each runtime automatically.
394
192
 
395
- <details>
396
- <summary>Full keybinding reference</summary>
193
+ **Works automatically (env vars only):**
397
194
 
398
- ### Main View
195
+ | Client | Support |
196
+ | ---------------------------- | -------------------------- |
197
+ | curl | Automatic |
198
+ | wget | Automatic |
199
+ | Go (`net/http`) | Automatic |
200
+ | Rust (reqwest) | Automatic |
201
+ | .NET (`HttpClient`) | Automatic |
202
+ | Deno | Automatic (`DENO_CERT`) |
203
+ | Bun | Automatic (`SSL_CERT_FILE`)|
204
+ | Git | Automatic (`GIT_SSL_CAINFO`)|
205
+ | AWS CLI | Automatic (`AWS_CA_BUNDLE`)|
206
+ | Cargo | Automatic (`CARGO_HTTP_CAINFO`)|
399
207
 
400
- | Key | Action |
401
- |-----|--------|
402
- | `j`/`k` or `↑`/`↓` | Navigate up/down |
403
- | `g` / `G` | Jump to first / last item |
404
- | `Ctrl+u` / `Ctrl+d` | Half-page up / down |
405
- | `Ctrl+f` / `Ctrl+b` | Full-page down / up |
406
- | `Tab` / `Shift+Tab` | Next / previous panel |
407
- | `1`-`5` | Jump to section (list / request / request body / response / response body) |
408
- | `Enter` | Open body in full-screen viewer |
409
- | `/` | Open filter bar |
410
- | `u` | Toggle full URL display |
411
- | `c` | Copy request as curl |
412
- | `y` | Copy body to clipboard |
413
- | `s` | Export body (opens export modal) |
414
- | `H` | Export all as HAR |
415
- | `r` | Refresh |
416
- | `?` | Help |
417
- | `i` | Proxy connection info |
418
- | `q` | Quit |
208
+ **Works with procsi overrides (injection scripts):**
419
209
 
420
- ### Filter Bar (`/`)
210
+ | Client | Mechanism |
211
+ | ---------------------------- | ------------------------------------------ |
212
+ | Node.js (fetch, axios, etc.) | `NODE_OPTIONS --require` preload script |
213
+ | Python (requests, httplib2) | `PYTHONPATH` sitecustomize.py |
214
+ | Ruby (Net::HTTP, gems) | `RUBYOPT -r` OpenSSL CA patch |
215
+ | PHP (curl, streams) | `PHP_INI_SCAN_DIR` custom INI |
421
216
 
422
- | Key | Action |
423
- |-----|--------|
424
- | `Tab` / `Shift+Tab` | Cycle between search, method, status fields |
425
- | `←` / `→` | Cycle method (ALL/GET/POST/PUT/PATCH/DELETE) or status (ALL/2xx-5xx) |
426
- | `Return` | Apply filter |
427
- | `Esc` | Cancel and revert |
217
+ **Not currently supported (needs system-level config):**
428
218
 
429
- ### JSON Explorer (Enter on a JSON body)
219
+ | Runtime | Reason |
220
+ | ----------------- | ------------------------------------------------ |
221
+ | Java/JVM | Needs `-javaagent` or JVM trust store config |
222
+ | Swift | Uses macOS Keychain only |
223
+ | Dart/Flutter | Requires code changes for proxy |
224
+ | Elixir/Erlang | Requires code changes for proxy |
430
225
 
431
- | Key | Action |
432
- |-----|--------|
433
- | `j`/`k` | Navigate nodes |
434
- | `Enter`/`l` | Expand/collapse node |
435
- | `h` | Collapse node |
436
- | `e` / `c` | Expand / collapse all |
437
- | `/` | Filter by path |
438
- | `n` / `N` | Next / previous match |
439
- | `y` | Copy value |
440
- | `q` / `Esc` | Close |
226
+ ## TUI
441
227
 
442
- ### Text Viewer (Enter on a non-JSON body)
228
+ `j`/`k` to navigate, `Tab` to switch panels, `/` to filter, `c` to copy as curl, `Enter` to inspect bodies, `q` to quit. Mouse support included.
443
229
 
444
- | Key | Action |
445
- |-----|--------|
446
- | `j`/`k` | Scroll line by line |
447
- | `Space` | Page down |
448
- | `g` / `G` | Top / bottom |
449
- | `/` | Search text |
450
- | `n` / `N` | Next / previous match |
451
- | `y` | Copy to clipboard |
452
- | `q` / `Esc` | Close |
230
+ See [full TUI documentation](docs/tui.md) for all keybindings and export features.
453
231
 
454
- </details>
232
+ ## Documentation
455
233
 
456
- ## CLI Reference
457
-
458
- ### Global Options
459
-
460
- | Flag | Description |
461
- |------|-------------|
462
- | `-v, --verbose` | Increase log verbosity (stackable: `-vv`, `-vvv`) |
463
- | `-d, --dir <path>` | Override project root directory |
464
-
465
- ### `procsi on`
466
-
467
- Output shell `export` statements to start intercepting HTTP traffic. Use with `eval`:
468
-
469
- ```bash
470
- eval "$(procsi on)"
471
- ```
472
-
473
- If run directly in a TTY (without `eval`), shows usage instructions.
474
-
475
- | Flag | Description |
476
- |------|-------------|
477
- | `-l, --label <label>` | Label this session (visible in TUI and MCP) |
478
- | `--no-restart` | Don't auto-restart daemon on version mismatch |
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
- ```
487
-
488
- ### `procsi tui`
489
-
490
- Open the interactive TUI.
491
-
492
- | Flag | Description |
493
- |------|-------------|
494
- | `--ci` | CI mode: render once and exit (for testing) |
495
-
496
- ### `procsi status`
497
-
498
- Show comprehensive status: daemon state, interception state, sessions, request count, loaded interceptors.
499
-
500
- ### `procsi daemon stop`
501
-
502
- Stop the daemon.
503
-
504
- ### `procsi daemon restart`
505
-
506
- Restart the daemon (or start it if not running).
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
-
596
- ### `procsi clear`
597
-
598
- Clear all captured requests.
599
-
600
- ### `procsi debug-dump`
601
-
602
- Collect diagnostics (system info, daemon status, recent logs) into `.procsi/debug-dump-<timestamp>.json`.
603
-
604
- ### `procsi mcp`
605
-
606
- Start the MCP server (stdio transport). See [MCP Integration](#mcp-integration).
607
-
608
- ### `procsi project init`
609
-
610
- Manually initialise a `.procsi` directory in the current location.
611
-
612
- ### `procsi interceptors`
613
-
614
- List loaded interceptors, or manage them with subcommands.
615
-
616
- ### `procsi interceptors init`
617
-
618
- Scaffold an example interceptor in `.procsi/interceptors/`.
619
-
620
- ### `procsi interceptors reload`
621
-
622
- Reload interceptors from disk without restarting the daemon.
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
- ```
234
+ - [CLI Reference](docs/cli-reference.md) — all commands, flags, and examples
235
+ - [Interceptors](docs/interceptors.md) — mock, modify, observe, query traffic, handler context
236
+ - [MCP Integration](docs/mcp.md) — tools, filtering, output formats, examples
237
+ - [TUI](docs/tui.md) — keybindings, export features
238
+ - [Configuration](docs/configuration.md) `.procsi/config.json` options
658
239
 
659
240
  ## Development
660
241
 
@@ -690,13 +271,11 @@ procsi daemon stop
690
271
  eval "$(procsi on)"
691
272
  ```
692
273
 
693
- ### Terminal too small
694
-
695
- The TUI needs at least 60 columns by 10 rows.
696
-
697
274
  ### Requests not appearing
698
275
 
699
- Your HTTP client needs to respect proxy environment variables.
276
+ Your HTTP client needs to respect proxy environment variables.
277
+
278
+ There are workarounds implemented for node - e.g. fetch override. Other libraries in different environments may need a similar treatment.
700
279
 
701
280
  ## Licence
702
281
 
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmEpC,eAAO,MAAM,aAAa,SAGM,CAAC"}
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoEpC,eAAO,MAAM,aAAa,SAGM,CAAC"}
@@ -40,6 +40,7 @@ const restartSubCommand = new Command("restart")
40
40
  console.log(`Restarting daemon${versionInfo}...`);
41
41
  const port = await restartDaemon(projectRoot, logLevel);
42
42
  console.log(`Daemon restarted on port ${port}`);
43
+ console.log('If your shell env vars are stale, run: eval "$(procsi on)"');
43
44
  }
44
45
  else {
45
46
  console.log("Daemon not running, starting...");
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/cli/commands/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,eAAe,EACf,UAAU,EACV,aAAa,EACb,WAAW,EACX,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErF,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KACvC,WAAW,CAAC,iBAAiB,CAAC;KAC9B,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,OAAgB,EAAE,EAAE;IACpC,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAEvD,6BAA6B;IAC7B,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,0BAA0B,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,iBAAiB,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;KAC7C,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,OAAgB,EAAE,EAAE;IACpC,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC;IACrC,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAE3C,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAEvD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;QAEtC,IAAI,MAAM,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;YACvC,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;YAC1D,MAAM,WAAW,GACf,aAAa,IAAI,aAAa,KAAK,UAAU;gBAC3C,CAAC,CAAC,KAAK,aAAa,OAAO,UAAU,GAAG;gBACxC,CAAC,CAAC,EAAE,CAAC;YAET,OAAO,CAAC,GAAG,CAAC,oBAAoB,WAAW,KAAK,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,0BAA0B,CAAC;KACvC,UAAU,CAAC,cAAc,CAAC;KAC1B,UAAU,CAAC,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/cli/commands/daemon.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"off.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/off.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,eAAO,MAAM,UAAU,SAmBnB,CAAC"}
1
+ {"version":3,"file":"off.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/off.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCpC,eAAO,MAAM,UAAU,SAsBnB,CAAC"}