portprism 2.0.2 โ†’ 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # PortPrism
2
+
3
+ **Share your local dev server with anyone, instantly.** Point PortPrism at a local
4
+ port and you get a clean, branded **HTTPS** URL that anyone can open in a browser โ€” no
5
+ account, no config, and nothing for your viewers to install.
6
+
7
+ ```bash
8
+ npx portprism 3000
9
+ ```
10
+
11
+ - ๐Ÿ”— **Instant public URL** for any local HTTP server
12
+ - ๐Ÿ–ฅ๏ธ **Branded viewer** โ€” recipients see your app, not a tunnel warning page
13
+ - ๐Ÿ”’ **TLS end-to-end**; optional password protection (Pro)
14
+ - ๐Ÿ” **Auto-reconnect** โ€” brief network drops recover on the same URL
15
+ - ๐Ÿ“ฑ **QR code** for quick mobile testing (`--qr`)
16
+ - ๐Ÿ”Ž **Request inspector** (`--inspect`) โ€” a local ledger of tunnelled HTTP traffic for webhook/API debugging
17
+ - ๐Ÿค– **MCP server** so AI agents can launch and manage tunnels
18
+ - โš™๏ธ **`--json`** NDJSON output for scripts and CI
19
+
20
+ > Requires **Node.js 18+**. Free links last 2 hours;
21
+ > [PortPrism Pro](https://portprism.io/#pricing) adds persistent links, password
22
+ > protection, custom subdomains, and analytics.
23
+
24
+ ---
25
+
26
+ ## Quick start
27
+
28
+ Start your app (any stack, any port), then in a second terminal:
29
+
30
+ ```bash
31
+ npx portprism 3000
32
+ ```
33
+
34
+ ```
35
+ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
36
+ โ”‚ PortPrism ยท My App โ”‚
37
+ โ”‚ Share URL https://viewer.portprism.io/v/ab3k โ”‚
38
+ โ”‚ Local http://localhost:3000 โ”‚
39
+ โ”‚ Expires 1h 59m โ”‚
40
+ โ”‚ Status โ— Connected โ”‚
41
+ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
42
+ ```
43
+
44
+ Send the `viewer.portprism.io/v/โ€ฆ` URL to anyone. Press `Ctrl+C` to stop.
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ # No install โ€” always the latest (recommended)
50
+ npx portprism <target>
51
+
52
+ # Or install globally
53
+ npm install -g portprism
54
+ portprism <target>
55
+ ```
56
+
57
+ ## Usage
58
+
59
+ ```bash
60
+ npx portprism [options] <target>
61
+ ```
62
+
63
+ `<target>` is a **port** (forwarded to `localhost`) or a **`host:port`** pair:
64
+
65
+ ```bash
66
+ npx portprism 3000 # โ†’ localhost:3000
67
+ npx portprism my-app.local:8080 # โ†’ custom host
68
+ npx portprism 127.0.0.1:5000 # โ†’ specific address
69
+ ```
70
+
71
+ ### Options
72
+
73
+ | Flag | Description |
74
+ | ----------------------- | ------------------------------------------------------------------- |
75
+ | `--name <label>` | App name shown in the viewer and CLI box |
76
+ | `--desc <text>` | One-line description shown in the viewer |
77
+ | `--password <pw>` | Require a password to view the link _(Pro)_ |
78
+ | `--qr` | Print the share URL as a scannable QR code |
79
+ | `--qr-invert` | Swap the QR's black/white cells for light terminals |
80
+ | `--json` | Emit machine-readable NDJSON events instead of the box (scripts/CI) |
81
+ | `--inspect` | Serve a local request inspector at `http://localhost:4040` |
82
+ | `--inspect-port <port>` | Port for the request inspector (default `4040`) |
83
+ | `--no-open` | Don't auto-open the viewer URL in your browser |
84
+ | `--no-screenshot` | Skip the automatic preview screenshot |
85
+ | `--relay <url>` | Override the relay WebSocket URL (self-hosting) |
86
+ | `--help` | Show all options |
87
+
88
+ ### Account commands
89
+
90
+ ```bash
91
+ portprism login # sign in with a magic-link / one-time code
92
+ portprism logout # remove saved credentials
93
+ portprism whoami # show the current account and plan
94
+ portprism upgrade # open the Pro checkout in your browser
95
+ portprism referral # show your referral link for bonus tunnel-time
96
+ portprism config # open ~/.portprism/config.json in $EDITOR
97
+ ```
98
+
99
+ ## Request inspector (`--inspect`)
100
+
101
+ Add `--inspect` to open a live, self-hosted traffic ledger at
102
+ **`http://localhost:4040`** โ€” every HTTP request forwarded through your tunnel is
103
+ listed chronologically with its headers, query parameters, and decoded
104
+ request/response bodies, updating live over Server-Sent Events. Ideal for debugging
105
+ webhooks and API callbacks. It runs on Node's built-in HTTP server (no extra install)
106
+ and keeps the last 200 requests in memory.
107
+
108
+ ## AI agents (MCP)
109
+
110
+ PortPrism speaks the [Model Context Protocol](https://modelcontextprotocol.io):
111
+
112
+ - **Local:** the [`portprism-mcp`](https://www.npmjs.com/package/portprism-mcp) stdio
113
+ server lets an agent `start_tunnel` / `stop_tunnel` / `list_tunnels` /
114
+ `get_tunnel_status`.
115
+ - **Remote:** `https://mcp.portprism.io/mcp` lets web connectors manage your live
116
+ tunnels (Bearer-token auth).
117
+
118
+ ## Privacy & your data
119
+
120
+ PortPrism is designed to move your app's traffic, not to read it.
121
+
122
+ - **Encrypted end-to-end.** All traffic between the viewer's browser, the PortPrism
123
+ relay, and your machine travels over TLS (HTTPS / WSS).
124
+ - **Transparent proxy.** The relay forwards bytes between the viewer and your local
125
+ app. It does **not** read, modify, or store the **content** of the requests and
126
+ responses passing through your tunnel โ€” your application data never lands in our
127
+ database.
128
+ - **What is stored** (for signed-in users): your email and auth token (for login),
129
+ session metadata (app name, token, expiry, view/request counts for Pro analytics),
130
+ and billing records via Stripe (we never see card numbers).
131
+ - **Anonymous use:** free tunnels need no account. A one-way hashed device
132
+ fingerprint is used only to enforce the free-plan time quota.
133
+ - **Links are public by default** โ€” anyone with the URL can view your app. For
134
+ sensitive tools use `--password` (Pro) so only people with the password can open it.
135
+ - **Consent:** on first run the CLI asks you to accept the Privacy Policy once (stored
136
+ in `~/.portprism/consent.json`). In `--json` mode it won't prompt โ€” it exits with an
137
+ `error` event instead.
138
+
139
+ Full policy: **<https://portprism.io/privacy-policy.html>**
140
+
141
+ ---
142
+
143
+ Docs: **<https://portprism.io/install.html>** ยท FAQ:
144
+ **<https://portprism.io/docs/faq.html>** ยท License: **MIT**
package/package.json CHANGED
@@ -1,15 +1,34 @@
1
1
  {
2
2
  "name": "portprism",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
+ "license": "MIT",
4
5
  "description": "Share your local server with anyone, instantly.",
6
+ "keywords": [
7
+ "tunnel",
8
+ "localhost",
9
+ "localhost-tunnel",
10
+ "reverse-proxy",
11
+ "port-forwarding",
12
+ "expose",
13
+ "share",
14
+ "preview",
15
+ "webhook",
16
+ "webhook-testing",
17
+ "https",
18
+ "websocket",
19
+ "developer-tools",
20
+ "cli",
21
+ "mcp"
22
+ ],
5
23
  "type": "module",
6
24
  "bin": {
7
25
  "portprism": "dist/index.js"
8
26
  },
27
+ "author": "Port Prism <info@portprism.io>",
9
28
  "files": [
10
- "dist"
29
+ "dist/index.js"
11
30
  ],
12
- "homepage": "https://www.portprism.io",
31
+ "homepage": "https://portprism.io",
13
32
  "publishConfig": {
14
33
  "access": "public"
15
34
  },
@@ -17,8 +36,7 @@
17
36
  "build": "esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --banner:js=\"#!/usr/bin/env node\nimport { createRequire as _createRequire } from 'module';\nimport { fileURLToPath as _fileURLToPath } from 'url';\nconst require = _createRequire(import.meta.url);\nconst __filename = _fileURLToPath(import.meta.url);\nconst __dirname = _fileURLToPath(new URL('.', import.meta.url));\"",
18
37
  "dev": "tsc --watch",
19
38
  "lint": "eslint src/",
20
- "prepublishOnly": "npm run build",
21
- "test": "echo \"No tests yet\" && exit 0"
39
+ "test": "tsc -p tsconfig.test.json && node --test dist/__tests__/inspector.test.js"
22
40
  },
23
41
  "dependencies": {
24
42
  "chalk": "^4.1.2",
@@ -30,7 +48,6 @@
30
48
  "ws": "^7.5.10"
31
49
  },
32
50
  "devDependencies": {
33
- "@types/node": "^26.1.0",
34
51
  "@types/qrcode": "^1.5.6",
35
52
  "@types/ws": "^8.18.1",
36
53
  "esbuild": "^0.25.12",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=inspector.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"inspector.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/inspector.test.ts"],"names":[],"mappings":""}
@@ -1,80 +0,0 @@
1
- import { describe, it, before, after } from "node:test";
2
- import assert from "node:assert/strict";
3
- import { Inspector } from "../inspector.js";
4
- describe("Inspector", () => {
5
- let insp;
6
- let base;
7
- before(async () => {
8
- insp = new Inspector();
9
- const url = await insp.start(0); // ephemeral port
10
- assert.ok(url, "inspector should bind an ephemeral port");
11
- base = url;
12
- });
13
- after(() => insp.stop());
14
- const b64 = (s) => Buffer.from(s).toString("base64");
15
- it("records a request, splits the query, and merges the response phase", async () => {
16
- insp.record({
17
- phase: "request",
18
- id: "req-1",
19
- ts: Date.now(),
20
- method: "POST",
21
- path: "/api/items?q=hello&limit=5",
22
- headers: { "content-type": "application/json" },
23
- body: b64('{"hello":"world"}'),
24
- });
25
- insp.record({
26
- phase: "response",
27
- id: "req-1",
28
- status: 201,
29
- headers: { "content-type": "application/json" },
30
- body: b64('{"ok":true}'),
31
- durationMs: 42,
32
- });
33
- const detail = (await (await fetch(`${base}/__pp/requests/req-1`)).json());
34
- assert.equal(detail.method, "POST");
35
- assert.equal(detail.path, "/api/items", "query must be split off the path");
36
- assert.deepEqual(detail.query, { q: "hello", limit: "5" });
37
- assert.equal(detail.reqBody.text, '{"hello":"world"}', "text body decoded, not base64");
38
- assert.equal(detail.reqBody.binary, false);
39
- assert.equal(detail.status, 201);
40
- assert.equal(detail.resBody?.text, '{"ok":true}');
41
- assert.equal(detail.durationMs, 42);
42
- assert.equal(detail.pending, false, "record is no longer pending after response");
43
- });
44
- it("flags binary payloads and keeps them base64", async () => {
45
- insp.record({
46
- phase: "request",
47
- id: "req-bin",
48
- method: "PUT",
49
- path: "/upload",
50
- headers: { "content-type": "application/octet-stream" },
51
- body: Buffer.from([0x00, 0x01, 0x02, 0xff]).toString("base64"),
52
- });
53
- const detail = (await (await fetch(`${base}/__pp/requests/req-bin`)).json());
54
- assert.equal(detail.reqBody.binary, true);
55
- assert.equal(detail.reqBody.text, Buffer.from([0x00, 0x01, 0x02, 0xff]).toString("base64"));
56
- });
57
- it("caps the ledger at 200 records (ring buffer)", async () => {
58
- for (let i = 0; i < 250; i++) {
59
- insp.record({
60
- phase: "request",
61
- id: `bulk-${i}`,
62
- method: "GET",
63
- path: `/x/${i}`,
64
- });
65
- }
66
- const list = (await (await fetch(`${base}/__pp/requests`)).json());
67
- assert.ok(list.length <= 200, `expected <=200 records, got ${list.length}`);
68
- // Oldest bulk entry should have been evicted.
69
- const gone = await fetch(`${base}/__pp/requests/bulk-0`);
70
- assert.equal(gone.status, 404, "oldest record should be evicted");
71
- });
72
- it("serves the web UI and returns 404 for unknown ids", async () => {
73
- const html = await fetch(`${base}/`);
74
- assert.equal(html.status, 200);
75
- assert.match(await html.text(), /PortPrism/);
76
- const missing = await fetch(`${base}/__pp/requests/does-not-exist`);
77
- assert.equal(missing.status, 404);
78
- });
79
- });
80
- //# sourceMappingURL=inspector.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"inspector.test.js","sourceRoot":"","sources":["../../src/__tests__/inspector.test.ts"],"names":[],"mappings":"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"}
package/dist/agent.d.ts DELETED
@@ -1,78 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- /**
3
- * Manages exponential-backoff reconnection with jitter.
4
- *
5
- * Usage:
6
- * const mgr = new ReconnectionManager();
7
- * await mgr.scheduleReconnect(() => openSocket(), onWaiting);
8
- */
9
- export declare class ReconnectionManager {
10
- private attempts;
11
- private readonly maxAttempts;
12
- private readonly baseDelay;
13
- private readonly maxDelay;
14
- /**
15
- * Compute the next delay with full-jitter:
16
- * base = min(baseDelay ร— 2^attempts, maxDelay)
17
- * result = base + base ร— 0.2 ร— random()
18
- */
19
- getDelay(): number;
20
- /** Reset the attempt counter after a successful connection. */
21
- reset(): void;
22
- /** Returns true when the max retry budget has been exhausted. */
23
- shouldGiveUp(): boolean;
24
- /**
25
- * Wait for the computed back-off delay, then call `connectFn`.
26
- *
27
- * @param connectFn Function that initiates a new WebSocket connection.
28
- * @param onWaiting Optional callback fired just before sleeping.
29
- * Receives `(delayMs, attempt, maxAttempts)` so callers
30
- * can update the UI without coupling the manager to display code.
31
- */
32
- scheduleReconnect(connectFn: () => void, onWaiting?: (delayMs: number, attempt: number, maxAttempts: number) => void): Promise<void>;
33
- }
34
- export interface AgentOptions {
35
- name: string;
36
- desc: string;
37
- password?: string;
38
- relay: string;
39
- noOpen: boolean;
40
- /** JWT from ~/.portlens/config.json โ€” forwarded to relay for userId resolution */
41
- jwtToken?: string;
42
- /** Skip automatic screenshot capture after connect */
43
- noScreenshot?: boolean;
44
- }
45
- export declare class Agent extends EventEmitter {
46
- private readonly port;
47
- private readonly options;
48
- private ws;
49
- private pingTimer;
50
- private closing;
51
- private screenshotDone;
52
- /** Timestamp of the last agent-initiated ping; null when no ping is in-flight. */
53
- private pingTimestamp;
54
- private readonly reconnectionManager;
55
- readonly token: string;
56
- constructor(port: number, options: AgentOptions);
57
- connect(): void;
58
- close(): void;
59
- private _openSocket;
60
- private _startPing;
61
- private _stopPing;
62
- private _handleMessage;
63
- private _forwardRequest;
64
- /** Convert the relay WebSocket URL to its HTTP equivalent. */
65
- private _relayHttp;
66
- /**
67
- * Try to locate a system Chrome / Chromium executable.
68
- * Returns the first path that exists on disk, or null.
69
- */
70
- private _findChrome;
71
- /**
72
- * Wait 2 s after connect, take a WebP screenshot of localhost:{port},
73
- * and POST the base64 image to the relay for storage.
74
- * All errors are caught and logged as warnings โ€” never aborts the tunnel.
75
- */
76
- private _captureScreenshot;
77
- }
78
- //# sourceMappingURL=agent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqC3C;;;;;;GAMG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAM;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IAEtC;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAMlB,+DAA+D;IAC/D,KAAK,IAAI,IAAI;IAIb,iEAAiE;IACjE,YAAY,IAAI,OAAO;IAIvB;;;;;;;OAOG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,IAAI,EACrB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,GAC1E,OAAO,CAAC,IAAI,CAAC;CAkBjB;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAID,qBAAa,KAAM,SAAQ,YAAY;IAcnC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAd1B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAS;IAE/B,kFAAkF;IAClF,OAAO,CAAC,aAAa,CAAuB;IAE5C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6B;IAEjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAGJ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY;IAMxC,OAAO,IAAI,IAAI;IAKf,KAAK,IAAI,IAAI;IAWb,OAAO,CAAC,WAAW;IAyDnB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,eAAe;IAiEvB,8DAA8D;IAC9D,OAAO,CAAC,UAAU;IAMlB;;;OAGG;IACH,OAAO,CAAC,WAAW;IA2BnB;;;;OAIG;YACW,kBAAkB;CAwEjC"}