@patchstack/connect 0.5.10 → 0.5.12
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/AGENT-INSTALL.md +57 -6
- package/README.md +20 -41
- package/dist/cli.js +195 -208
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +4 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/protect.cjs +3 -2
- package/dist/protect.cjs.map +1 -1
- package/dist/protect.js +1 -1
- package/dist/{refresh-manifest-PPV22Q2E.js → refresh-manifest-47HJRCDX.js} +3 -2
- package/dist/refresh-manifest-47HJRCDX.js.map +1 -0
- package/package.json +1 -1
- package/dist/refresh-manifest-PPV22Q2E.js.map +0 -1
package/AGENT-INSTALL.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
This versioned reference ships inside `@patchstack/connect` and documents each setup command and its project changes.
|
|
4
4
|
|
|
5
|
+
## Choose the project path first
|
|
6
|
+
|
|
7
|
+
Use the package setup flow below for an existing JS/Node application. Work in its package directory; a missing `package.json` can mean you are in a subdirectory or looking at generated HTML rather than the source project. A page containing HTML can still belong to a server-rendered application. Do not infer that runtime protection is unnecessary from the file extension alone.
|
|
8
|
+
|
|
9
|
+
### Plain HTML sites
|
|
10
|
+
|
|
11
|
+
For a standalone site made of HTML, CSS, and browser JavaScript, with no package-managed application or server request handler, use the disclosure widget directly. Do not create `package.json`, install a framework, invent build hooks, or add a server just to run Connect. `setup` requires an existing `package.json`; it is not a standalone HTML installer.
|
|
12
|
+
|
|
13
|
+
1. Use the public site UUID or widget snippet for the correct site in the Patchstack dashboard. An existing `.patchstackrc.json` can also supply `siteUuid`. If neither is available, ask the user for the site's public UUID or dashboard-provided snippet before editing the page. Never invent a UUID or use a claim token or API key as the widget identifier.
|
|
14
|
+
2. Add one widget tag before `</body>` in the page or shared layout. Preserve an existing correct tag. For a page published directly without a build step, disable the widget's build-mode onboarding with `data-build-mode="false"`:
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<script src="https://cdn.patchstack.com/patchstack-widget.js" data-site-uuid="YOUR_SITE_UUID" data-build-mode="false" defer></script>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Replace `YOUR_SITE_UUID` with the real public site UUID before saving. Keep credentials out of the page. The [public widget reference](https://cdn.patchstack.com/llm.html) documents this embed and its options.
|
|
21
|
+
3. Verify the saved tag uses the correct UUID. If a browser preview is available, reload it and check for the report button; otherwise tell the user that the browser check is pending. Do not submit a vulnerability report as an installation test. Save the HTML change and remind the user to publish it when ready; do not deploy it yourself.
|
|
22
|
+
|
|
23
|
+
Report this as **disclosure widget installed**, with any remaining preview or publishing step. This path does not inventory local JavaScript files or scripts loaded from a CDN, scan npm dependencies, or install runtime exploit protection. External APIs used by the page require their own server-side integration.
|
|
24
|
+
|
|
25
|
+
### JS/Node applications — the usual path
|
|
26
|
+
|
|
27
|
+
1. Check what is already done with `npx @patchstack/connect guide` (read-only). If the project is already provisioned, reuse it — see "Before you start — never install twice".
|
|
28
|
+
2. Install `@patchstack/connect` as a runtime dependency with the project's package manager.
|
|
29
|
+
3. Run `npx @patchstack/connect setup`. In a hosted builder, scope `PATCHSTACK_ENVIRONMENT=sandbox` to that command — see "Automated setup".
|
|
30
|
+
4. Finish any step the checklist at the end of `setup` still lists. "Automated setup" names each one.
|
|
31
|
+
5. Tell the person the dashboard link, which parts are active and which are not, to refresh their preview, and to deploy when they are ready.
|
|
32
|
+
|
|
33
|
+
If your tool will not run the command, see "When your tool will not run this CLI". The sections below describe what each command reads, writes, and sends.
|
|
34
|
+
|
|
5
35
|
## Command reference
|
|
6
36
|
|
|
7
37
|
Every command at a glance — what it does, whether it reads your source, what it writes, and what leaves your machine. Full behavior, flags, and edge cases follow in the sections below.
|
|
@@ -88,9 +118,26 @@ This is a request, not a mechanism: nothing in the install depends on it. Do it
|
|
|
88
118
|
|
|
89
119
|
**If the request you were given includes a claim token**, pass it exactly as given: `npx @patchstack/connect setup --claim-token <token>`. The site is then created in the person's own Patchstack account and `setup` prints their dashboard link for it — there is no sign-in step to relay. The token comes only from the person's Patchstack dashboard; never invent one, never write it to a file, never print it back. If `setup` reports that the token had expired or was not recognised, the site is not connected: hand over the dashboard link it prints instead, and tell the person they can copy a fresh prompt from the dashboard.
|
|
90
120
|
|
|
91
|
-
In a hosted builder
|
|
121
|
+
**In a hosted builder:**
|
|
122
|
+
|
|
123
|
+
- Run setup with `PATCHSTACK_ENVIRONMENT=sandbox` scoped to the workspace process/command.
|
|
124
|
+
- Ensure the CLI's on-disk edits are adopted into the platform's persisted project state.
|
|
125
|
+
- Restart any already-running preview/server process so it loads the guard.
|
|
126
|
+
- Do not persist `"environment": "sandbox"` in `.patchstackrc.json`: deployed builds use the same committed files and report `production` only when the build platform's own variables say so.
|
|
127
|
+
|
|
128
|
+
**How each environment is labelled:**
|
|
92
129
|
|
|
93
|
-
|
|
130
|
+
- A build platform's tier (Vercel, Netlify, Render, Railway, GitLab CI) or a branch named `main`, `master`, `production`, `prod`, `release` or `live` (Cloudflare Pages and Workers Builds, AWS Amplify, GitHub Actions, GitLab CI without a tier) reports `production`; a preview, pull request or other branch there reports `sandbox`, as does the Replit workspace, while a Replit Deployment reports `production`.
|
|
131
|
+
- A build in a project the builder generated and builds for itself (Lovable, Replit) reports `production` without an override, because the edit preview is a dev server and a build is the publish step — which is exactly why the sandbox label belongs in the workspace process and not in a file.
|
|
132
|
+
- A scan on a developer's machine, in a CI runner this does not know (`CI=true` alone), or on a platform with no such signal reports `local` on its own, and the dashboard shows that app as configured, not deployed.
|
|
133
|
+
|
|
134
|
+
**What runtime protection can report:** a positively identified static build reports runtime protection as not applicable. A bundler-only project, including plain Vite, can remain runtime unknown and receive a generic scaffold with incomplete wiring. Report that limitation; do not add an artificial server merely to make the check pass, and never describe a widget or an unwired scaffold as runtime protection.
|
|
135
|
+
|
|
136
|
+
**A step the checklist still lists is yours to finish, not a result to report.** `setup` applies what it can apply safely and prints the exact edit for anything it would have had to overwrite user code to do. They are: moving `@patchstack/connect` out of `devDependencies`, the widget tag in a root layout `setup` could not edit, the production marker on a server-rendered root, and wiring a generic guard into the server entry. The last three are steps 3 and 4 of "Manual setup" below; after the guard one, `npx @patchstack/connect protect --check` must exit 0.
|
|
137
|
+
|
|
138
|
+
**A tick is "nothing owed here", not "this part is on".** The checklist marks steps this project still owes, so a part it cannot carry — or one that is switched off — is green with nothing outstanding. `No build script to integrate`, `Disclosure widget disabled by config` and `Runtime protection: not applicable` all read that way. So report what the project ended up with by name — dependency scans, the disclosure widget, the build hooks, runtime protection — and say which of them are not active and why, rather than reporting an empty checklist as a finished install. Of those, the widget is the one that can be off by setting rather than by the shape of the project: if `.patchstackrc.json` carries `"widget": false` and the person did not ask for that, tell them it is off and ask whether they want it on.
|
|
139
|
+
|
|
140
|
+
**Finish by telling the user to refresh their preview.** The widget loads with the page, so a preview that was already open still shows the HTML from before setup — the widget is missing there until it reloads. Tell them what to expect after the refresh: a site that is not yet connected to an account shows the "Connect this website" panel, and the "Report a vulnerability" button takes its place once the site is claimed. A freshly set up site is unclaimed unless setup ran with a claim token. Nothing in the CLI can reach the user's browser, so relaying this is your job. Phrase it as a check rather than a required step: a builder that hot reloads, or a preview server you restarted, may have refreshed it already.
|
|
94
141
|
|
|
95
142
|
**Then tell them to deploy.** Setup changes source files, and the deployed site keeps serving its previous build until the next deploy — so visitors get no widget, and on a server-rendered root no production marker, until the user deploys (or hits Publish) again. Say it as a reminder; do not deploy anything yourself.
|
|
96
143
|
|
|
@@ -162,7 +209,7 @@ Handle it in this order:
|
|
|
162
209
|
npx @patchstack/connect scan
|
|
163
210
|
```
|
|
164
211
|
|
|
165
|
-
It prints a dashboard link but never opens it. Open that link in a browser to view reports. It also prints what it did about the widget — if it added the tag, reload the preview and confirm the "Report a vulnerability" button
|
|
212
|
+
It prints a dashboard link but never opens it. Open that link in a browser to view reports. It also prints what it did about the widget — if it added the tag, reload the preview and confirm the widget appears: the "Connect this website" panel while the site is unclaimed, the "Report a vulnerability" button once it is claimed.
|
|
166
213
|
|
|
167
214
|
2. **Wire builds** in `package.json`:
|
|
168
215
|
|
|
@@ -180,7 +227,7 @@ Handle it in this order:
|
|
|
180
227
|
|
|
181
228
|
**Bun-managed projects:** `bun run` does not execute npm-style `pre`/`post` scripts, so wire the build script directly instead: `"build": "patchstack-connect scan && <existing build command> && patchstack-connect mark-build"`.
|
|
182
229
|
|
|
183
|
-
3. **Verify the disclosure widget** — a floating "Report a vulnerability" button. `scan` installs it automatically into a plain HTML shell **or a JSX root** (Next, Remix, React Router, TanStack Start, Gatsby), and `mark-build` carries it into built HTML. Only when `scan` reported that it found no editable shell at all — a root whose head mechanism is not a plain script tag, e.g. Nuxt's `useHead` or an Astro layout — add the one-liner it printed to the root layout yourself, just before `</body>` (never a JS entry point), reading `siteUuid` from `.patchstackrc.json`. On those same roots the widget also needs the production marker above the tag — `scan` adds it automatically to a JSX root, and prints it to paste when it finds no anchor. A server-rendered site without the marker serves the build-mode claim flow to its visitors:
|
|
230
|
+
3. **Verify the disclosure widget** — a floating control whose form follows the site's claim state: while the site is unclaimed it is a one-time "Connect this website" panel, and it becomes the public "Report a vulnerability" button once the site is claimed. Do not tell the user the report button will appear on a site that has not been connected to an account yet. `scan` installs it automatically into a plain HTML shell **or a JSX root** (Next, Remix, React Router, TanStack Start, Gatsby), and `mark-build` carries it into built HTML. Only when `scan` reported that it found no editable shell at all — a root whose head mechanism is not a plain script tag, e.g. Nuxt's `useHead` or an Astro layout — add the one-liner it printed to the root layout yourself, just before `</body>` (never a JS entry point), reading `siteUuid` from `.patchstackrc.json`. On those same roots the widget also needs the production marker above the tag — `scan` adds it automatically to a JSX root, and prints it to paste when it finds no anchor. A server-rendered site without the marker serves the build-mode claim flow to its visitors:
|
|
184
231
|
|
|
185
232
|
```html
|
|
186
233
|
<script src="https://cdn.patchstack.com/patchstack-widget.js" data-site-uuid="<SITE_UUID>" defer></script>
|
|
@@ -248,7 +295,11 @@ It is server-only. Never put it in the widget tag, client bundles, or public env
|
|
|
248
295
|
|
|
249
296
|
**Do not commit `.patchstackrc.local.json`.** That file holds the API key issued at provision; the scan writes it and adds it to `.gitignore`, and tells you if it could not. `.patchstackrc.json` holds only the site UUID and settings, and the UUID is public by design — it ships in the widget tag in served HTML.
|
|
250
297
|
|
|
251
|
-
6. **
|
|
298
|
+
6. **Connect the site to a Patchstack account.** The site is monitored either way, but its vulnerability reports are only visible once it is attached to an account, and an unattached site stays claimable by anyone who loads the page — the site UUID ships in the HTML and claiming is first-come. Three routes reach the same place; tell the user all three and lead with the first, which needs no terminal and no copied URL:
|
|
299
|
+
|
|
300
|
+
1. **The widget's "Connect this website" panel**, already on the preview. While the site is unclaimed the widget serves this panel *instead of* the report button, and signing in there attaches the site. On a published build it is hidden from visitors; the owner reveals it by appending `#patchstack` (or `?patchstack`) to the live URL.
|
|
301
|
+
2. **The dashboard link** the scan printed — open it in a browser and sign in.
|
|
302
|
+
3. **`npx @patchstack/connect claim`** from the terminal, which prints a link to sign in with and then attaches the site.
|
|
252
303
|
|
|
253
304
|
## Rules
|
|
254
305
|
|
|
@@ -540,7 +591,7 @@ Two more endpoints the package can call, for completeness:
|
|
|
540
591
|
- `npx @patchstack/connect status` re-prints the site UUID and dashboard URL, and checks whether the site still exists on Patchstack (`Site status: active / removed / could not be verified`).
|
|
541
592
|
- `npx @patchstack/connect protect --check` verifies from the source that the runtime guard is connected to the request path. It does not run the app.
|
|
542
593
|
- `npx @patchstack/connect protect --check --runtime` additionally **starts the app** on a loopback port and sends it one request, to establish that a request reaches the guard seam. Opt-in, and the only command that runs the application; exit `0`/`1`/`2` as described in step 4.
|
|
543
|
-
- Load the site in a browser — the "Report a vulnerability" button
|
|
594
|
+
- Load the site in a browser — the widget should appear: the "Connect this website" panel while the site is unclaimed, the "Report a vulnerability" button once it is claimed. Refresh a page that was already open before the tag was added: the widget only loads with the page.
|
|
544
595
|
- On the deployed site, the button appears only after a deploy that includes these source changes.
|
|
545
596
|
|
|
546
597
|
## Answering "is Patchstack installed?" / "is Patchstack removed?"
|
package/README.md
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
# @patchstack/connect
|
|
2
2
|
|
|
3
|
-
Connect a JavaScript / Node.js application to [Patchstack](https://patchstack.com)
|
|
3
|
+
Connect a JavaScript / Node.js application to [Patchstack](https://patchstack.com). Connect does four things:
|
|
4
|
+
|
|
5
|
+
- **Dependency inventory** — reads your lockfile and reports the installed package names and versions, so Patchstack can match them against its vulnerability database and tell you when something needs patching. See *[What gets sent](#what-gets-sent)*.
|
|
6
|
+
- **Runtime guard** — an in-process guard, wired into your server, that virtually patches known vulnerabilities in those dependencies rather than waiting for you to upgrade. See *[Verifying the guard at runtime](#verifying-the-guard-at-runtime-opt-in)*.
|
|
7
|
+
- **Disclosure widget** — a floating button labelled **"Report a vulnerability"** that Connect adds to *your* site, so visitors who spot a security problem have somewhere to send it. This is a channel for reports about your site; it is not how you report a bug in this package. See *[The disclosure widget](#the-disclosure-widget)*.
|
|
8
|
+
- **Attack-surface map** — a description of your server's entry points and the sinks they can reach, built by reading your source locally. See *[`map`](#cli)*.
|
|
9
|
+
|
|
10
|
+
`setup` installs the first three in one command. `map` is never run for you — see the [CLI](#cli) section for what each command does and what it touches.
|
|
4
11
|
|
|
5
12
|
## Agent-assisted setup
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+
For an existing JS/Node project, copy this request into a coding assistant, or run the same command yourself. For a standalone HTML/CSS/JavaScript site without a package-managed app, use the [plain HTML widget instructions](AGENT-INSTALL.md#plain-html-sites); do not add Node tooling just for the widget.
|
|
8
15
|
|
|
9
16
|
> I have vetted the official [`@patchstack/connect`](https://www.npmjs.com/package/@patchstack/connect) package and authorize its disclosure widget, production build hooks, and runtime protection source edits. Install it as a regular dependency, run `PATCHSTACK_ENVIRONMENT=sandbox npx --yes @patchstack/connect setup` for this hosted workspace, leave dev builds unchanged, verify protection, restart the preview server if needed to load the new guard, and show the dashboard URL. Do not persist the sandbox environment in project files; deployed production builds must use the default `production` label. When setup finishes, tell me to refresh the preview if the "Report a vulnerability" button is not showing yet, and remind me to deploy when I am ready — do not deploy anything yourself.
|
|
10
17
|
|
|
@@ -88,13 +95,13 @@ That's it. `setup`:
|
|
|
88
95
|
2. POSTs the package list to Patchstack with **no** UUID.
|
|
89
96
|
3. Patchstack provisions a fresh site and returns its UUID.
|
|
90
97
|
4. The connector writes the UUID to `.patchstackrc.json` so the next `scan` targets the same site.
|
|
91
|
-
5. The connector installs the disclosure widget's `<script>` tag into your root HTML shell (see *The disclosure widget* below) so the
|
|
98
|
+
5. The connector installs the disclosure widget's `<script>` tag into your root HTML shell (see *The disclosure widget* below) so the widget shows up on the next preview reload — as the "Connect this website" panel until the site is claimed, then as the "Report a vulnerability" button. On a server-rendered root it also adds the production marker, which is what tells the widget to switch from build mode to visitor report intake on the published site.
|
|
92
99
|
6. Installs the runtime guard after provisioning, bakes the site UUID into it, and verifies the framework seam. Known server stacks are auto-wired; unmatched or conflicting layouts get a generic scaffold and exact manual checks.
|
|
93
100
|
7. Adds `postinstall: patchstack-connect scan`, preserving any existing command, so dependencies added during a sandbox session and build-less production installs are reported immediately.
|
|
94
101
|
8. Wires `scan` before builds and `mark-build` after builds, preserving existing commands and using direct build chaining for Bun.
|
|
95
102
|
9. Prints a dashboard link — open it in a browser to attach the new site to your Patchstack account. You can re-display it any time with `npx @patchstack/connect status`.
|
|
96
103
|
|
|
97
|
-
Then **refresh your preview**. The widget
|
|
104
|
+
Then **refresh your preview**. The widget loads with the page, so a preview that was already open still shows the HTML from before setup. Builders that hot reload will have refreshed it for you; if the widget is missing, refresh it once. Until the site is claimed it shows the "Connect this website" panel; the "Report a vulnerability" button takes its place once it is. `setup` prints the same reminder, and the CLI has no way to reload a browser itself.
|
|
98
105
|
|
|
99
106
|
Then **deploy**. These are source changes, so your live site keeps serving its previous build — visitors get the widget, and a server-rendered root gets the production marker, only after the next deploy.
|
|
100
107
|
|
|
@@ -446,55 +453,27 @@ Every scanned source is validated against `package.json`: if the chosen lockfile
|
|
|
446
453
|
## Development
|
|
447
454
|
|
|
448
455
|
```bash
|
|
449
|
-
npm
|
|
456
|
+
npm ci
|
|
450
457
|
npm run typecheck
|
|
458
|
+
npm run build # before the tests: several only run once dist/ exists, and skip silently without it
|
|
451
459
|
npm test
|
|
452
|
-
npm run build
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
### Manifest endpoint testing
|
|
456
|
-
|
|
457
|
-
To post the current lockfile manifest to a local Patchstack API endpoint and provision a new site:
|
|
458
|
-
|
|
459
|
-
```bash
|
|
460
|
-
bun run test:manifest -- --endpoint http://localhost:8000/monitor/pulse/manifest
|
|
461
460
|
```
|
|
462
461
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
```bash
|
|
466
|
-
bun run test:manifest -- --endpoint http://localhost:8000/monitor/pulse/manifest --site-uuid YOUR_REAL_UUID
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
Use `--dry-run` to preview the payload without posting.
|
|
462
|
+
`CONTRIBUTING.md` covers the rest — the Node versions this needs, the packaging checks, and what to run before opening a pull request. Changing onboarding, the install prompt or the setup guide? Read `MAINTAINING.md` first.
|
|
470
463
|
|
|
471
464
|
## Release process
|
|
472
465
|
|
|
473
466
|
Pull requests run typecheck, tests, build, package verification, and a production dependency audit in GitHub Actions.
|
|
474
467
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
To publish a release:
|
|
468
|
+
Releases are cut by the `Release` workflow, which works out the next version, tags it, and hands off to `Publish`:
|
|
478
469
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
4. Create and publish a GitHub Release tagged `v0.2.0`.
|
|
483
|
-
5. The `Publish` workflow verifies the package, then runs `npm publish --provenance --access public`.
|
|
484
|
-
|
|
485
|
-
Before the first release, configure npm trusted publishing for this package:
|
|
470
|
+
```bash
|
|
471
|
+
gh workflow run Release -f bump=patch # or: minor, major
|
|
472
|
+
```
|
|
486
473
|
|
|
487
|
-
|
|
488
|
-
2. Open the `@patchstack/connect` package settings on npmjs.com.
|
|
489
|
-
3. In **Trusted publishing**, choose **GitHub Actions**.
|
|
490
|
-
4. Configure:
|
|
491
|
-
- Organization/user: `patchstack`
|
|
492
|
-
- Repository: `connect`
|
|
493
|
-
- Workflow filename: `publish.yml`
|
|
494
|
-
- Environment name: `npm`
|
|
495
|
-
5. In GitHub repository settings, create an `npm` environment. Optional but recommended: require reviewer approval for that environment.
|
|
474
|
+
The git tag is the source of truth for the published version. `Publish` reads the version out of the tag, writes it into `package.json` in CI, then builds and publishes to npm with provenance — so you do **not** bump `package.json` before releasing. After publishing it opens a pull request bringing the committed manifest up to the version that just went out; merge that.
|
|
496
475
|
|
|
497
|
-
|
|
476
|
+
`RELEASING.md` has the details: how to pick the bump (a compatibility break on a `0.x` version needs at least a minor), the manual fallback, and the npm trusted-publishing configuration.
|
|
498
477
|
|
|
499
478
|
## License
|
|
500
479
|
|