@patchstack/connect 0.3.21 → 0.3.22

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 CHANGED
@@ -98,10 +98,19 @@ This versioned reference ships inside `@patchstack/connect` and documents each s
98
98
 
99
99
  ## Verifying the install
100
100
 
101
- - `npx @patchstack/connect status` re-prints the site UUID and dashboard URL.
101
+ - `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`).
102
102
  - `npx @patchstack/connect protect --check` verifies the runtime guard is connected to the request path.
103
103
  - Load the site in a browser — the "Report a vulnerability" button should appear.
104
104
 
105
+ ## Answering "is Patchstack installed?" / "is Patchstack removed?"
106
+
107
+ These are **two independent states** — never conflate them:
108
+
109
+ 1. **The site record on Patchstack** (remote). Deleting the site in the dashboard or through the widget's uninstall flow removes it. Reporting stops and the widget stops rendering, but nothing in the project changes.
110
+ 2. **The local integration** (this repo): the widget `<script>` tag, `.patchstackrc.json`, the `@patchstack/connect` dependency, the runtime guard files, and the build hooks.
111
+
112
+ Local files alone cannot tell you whether the site was removed from Patchstack. Run `npx @patchstack/connect status` and read the `Site status` line, then answer with both states. For example, when the site was removed but the local files remain, say: *"The site itself was removed from Patchstack — reporting has stopped and the widget no longer renders. The local integration code (widget tag, `.patchstackrc.json`, the dependency) is still in the project; want me to remove it?"* — not "Patchstack is still installed."
113
+
105
114
  ## Uninstalling
106
115
 
107
116
  Remove only the pieces that are actually present — check for each first. If none are present, Patchstack isn't installed; report that and stop. If the user asked to remove only one piece (e.g. "just the widget"), remove only that piece.
@@ -115,3 +124,5 @@ Remove only the pieces that are actually present — check for each first. If no
115
124
  7. **Commit** the changes. Reporting stops immediately. The `window.__PATCHSTACK_PROD__` flag that `mark-build` injected lives only in build output, never in source — the next build simply won't contain it (rebuild if build output is committed).
116
125
 
117
126
  Local removal does not delete the site record on Patchstack's side. An unclaimed site is an anonymous record that stops receiving reports; a claimed site is removed by the user in their dashboard at https://app.patchstack.com. There is no CLI command for account-side deletion — do not invent one, and never attempt to authenticate or remove the site on the user's behalf.
127
+
128
+ The reverse also holds: removing the site on Patchstack's side (dashboard delete or the widget's uninstall flow) does not touch these local files — they must still be removed with the steps above. `npx @patchstack/connect status` shows `Site status: removed from Patchstack` in that state.
package/dist/cli.js CHANGED
@@ -946,6 +946,31 @@ function buildClaimUrl(endpoint, siteUuid) {
946
946
  const origin = new URL(endpoint).origin;
947
947
  return `${origin}/monitor/claim?site=${encodeURIComponent(siteUuid)}`;
948
948
  }
949
+ function buildSettingsUrl(endpoint, siteUuid) {
950
+ const origin = new URL(endpoint).origin;
951
+ return `${origin}/monitor/widget/settings/${encodeURIComponent(siteUuid)}`;
952
+ }
953
+ async function fetchSiteStatus(config) {
954
+ if (config.siteUuid === null) return "unknown";
955
+ const url = new URL(buildSettingsUrl(config.endpoint, config.siteUuid));
956
+ url.searchParams.set("t", Date.now().toString());
957
+ try {
958
+ const response = await fetch(url.toString(), {
959
+ method: "GET",
960
+ headers: {
961
+ Accept: "application/json",
962
+ "Cache-Control": "no-cache",
963
+ "User-Agent": "@patchstack/connect"
964
+ },
965
+ signal: AbortSignal.timeout(config.timeoutMs)
966
+ });
967
+ if (response.status === 404) return "removed";
968
+ if (response.ok) return "active";
969
+ return "unknown";
970
+ } catch {
971
+ return "unknown";
972
+ }
973
+ }
949
974
  async function postManifest(config, payload) {
950
975
  const url = buildEndpointUrl(config.endpoint, config.siteUuid);
951
976
  const timeoutMs = config.timeoutMs;
@@ -2858,7 +2883,9 @@ Usage:
2858
2883
  Never runs the project build
2859
2884
  patchstack-connect init <site-uuid> Optional: pre-seed .patchstackrc.json
2860
2885
  with an existing site UUID
2861
- patchstack-connect status [options] Show current configuration
2886
+ patchstack-connect status [options] Show current configuration and whether the
2887
+ site still exists on Patchstack (active /
2888
+ removed)
2862
2889
  patchstack-connect mark-build [options] Stamp built HTML with a production flag +
2863
2890
  build fingerprint, and ensure the widget
2864
2891
  tag in built pages (run as a postbuild step)
@@ -3290,6 +3317,26 @@ async function runStatus(args) {
3290
3317
  console.log(`Environment: ${config.environment}`);
3291
3318
  if (config.siteUuid !== null) {
3292
3319
  console.log(`Dashboard URL: ${buildClaimUrl(config.endpoint, config.siteUuid)}`);
3320
+ switch (await fetchSiteStatus(config)) {
3321
+ case "active":
3322
+ console.log("Site status: active on Patchstack");
3323
+ break;
3324
+ case "removed":
3325
+ console.log("Site status: removed from Patchstack");
3326
+ console.log(
3327
+ " The site record no longer exists (deleted from the dashboard or via the"
3328
+ );
3329
+ console.log(
3330
+ " widget uninstall flow). The local integration files are still in this"
3331
+ );
3332
+ console.log(
3333
+ ' project \u2014 see "Uninstalling" in AGENT-INSTALL.md to remove them.'
3334
+ );
3335
+ break;
3336
+ case "unknown":
3337
+ console.log("Site status: could not be verified (Patchstack unreachable)");
3338
+ break;
3339
+ }
3293
3340
  }
3294
3341
  return 0;
3295
3342
  }