@patchstack/connect 0.5.22 → 0.5.24

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
@@ -160,8 +160,10 @@ Only when the person asks you to publish the site. Two things decide whether Pat
160
160
  ```
161
161
 
162
162
  An app with a server needs this for runtime protection: the guard fetches its rules with the key. Without it the deploy is still recognised as long as the packages have not changed since the last scan, but nothing is protected. Never put the key in a committed file, in a public variable (`NEXT_PUBLIC_*`, `VITE_*`), or in your reply.
163
+ - **A host that builds the site itself but is not named under "How each environment is labelled"** — ChatGPT Sites (`*.chatgpt.site`, published from Codex) is one — gives Patchstack nothing that says "production", so its builds report `local` and the live site is never recognised as deployed. In that host's environment settings for the published site, set two variables: `PATCHSTACK_API_KEY`, read from `.patchstackrc.local.json` as above, and `PATCHSTACK_ENVIRONMENT=production`. Set the label only where the published build reads it, never in a committed file, and not in settings a preview or the local dev server also reads. Then publish again: the deployed site keeps serving the build from before setup until it is rebuilt.
163
164
  - **Check the live site after deploying**, and tell the person what you found:
164
165
  - `curl -s <live url> | grep -ac __PATCHSTACK_PROD__` prints `1` or more. `0` means the build did not know it was production, and the widget will treat the live site as a preview.
166
+ - A site published privately answers `curl` with the host's sign-in page, so the check above prints `0` whatever was deployed — check the status code first (`curl -s -o /dev/null -w "%{http_code}" <live url>`). On a `401`, `403` or a redirect to a sign-in page, ask the person to open the live site while signed in and run `window.__PATCHSTACK_BUILD__` in the browser console: a short build ID means the marker is live, `undefined` means it is not. Patchstack cannot read a private page either, so its dashboard shows the deploy as reported, not confirmed, until a signed-in visit lets the widget report the build. Tell the person that, rather than describing the deploy as confirmed.
165
167
  - `curl -s -o /dev/null -w "%{http_code}" <live url>/.patchstackrc.local.json` is not `200`. A `200` means the API key was published: delete the deploy and tell the person.
166
168
  - The owner reaches their dashboard on the live site by adding `#patchstack` to the address, for example `https://example.com/#patchstack`. Visitors never see the owner panels there.
167
169
 
package/dist/cli.js CHANGED
@@ -7181,6 +7181,17 @@ function npmPackageOf(spec) {
7181
7181
  // src/map/sinks.ts
7182
7182
  import { createHash as createHash4 } from "crypto";
7183
7183
 
7184
+ // src/map/capabilities.ts
7185
+ var PACKAGE_SINK_MODELS = [
7186
+ {
7187
+ package: "node-serialize",
7188
+ api: "unserialize",
7189
+ sinkKind: "eval",
7190
+ argumentRole: "code",
7191
+ candidateFamily: "code-injection"
7192
+ }
7193
+ ];
7194
+
7184
7195
  // src/map/scope.ts
7185
7196
  var scopeCache = /* @__PURE__ */ new WeakMap();
7186
7197
  function declarationOf(id, ts) {
@@ -7300,9 +7311,10 @@ var FS_PACKAGES = ["fs-extra", "graceful-fs", "memfs"];
7300
7311
  var isFsPackage = (pkg) => /^node:fs(\/promises)?$/.test(pkg) || FS_PACKAGES.includes(pkg);
7301
7312
  var EXEC_PACKAGES = ["execa", "cross-spawn", "shelljs", "zx"];
7302
7313
  var isExecPackage = (pkg) => pkg === "node:child_process" || EXEC_PACKAGES.includes(pkg);
7303
- var DESERIALIZE_CALLS = /^unserialize$/;
7304
- var DESERIALIZE_PACKAGES = ["node-serialize"];
7305
- var isDeserializePackage = (pkg) => DESERIALIZE_PACKAGES.includes(pkg);
7314
+ var deserializeModel = (pkg, api) => PACKAGE_SINK_MODELS.find(
7315
+ (model) => model.sinkKind === "eval" && model.package === pkg && (api === void 0 || model.api === api)
7316
+ );
7317
+ var isDeserializePackage = (pkg) => deserializeModel(pkg) !== void 0;
7306
7318
  function recognizedSinkKinds(pkg) {
7307
7319
  const kinds = [];
7308
7320
  if (isDbPackage(pkg)) kinds.push("db");
@@ -7449,7 +7461,7 @@ function directSinks(node, ts, bindings, ctx) {
7449
7461
  if (EXEC_CALLS.test(method) && b.pkg && isExecPackage(b.pkg)) {
7450
7462
  push({ kind: "exec", package: b.pkg, op: method, attribution: "import", ...spanOf(n) });
7451
7463
  }
7452
- if (DESERIALIZE_CALLS.test(method) && b.pkg && isDeserializePackage(b.pkg)) {
7464
+ if (b.pkg && deserializeModel(b.pkg, method)) {
7453
7465
  push({ kind: "eval", provider: b.root, package: b.pkg, op: method, attribution: "import", ...spanOf(n) });
7454
7466
  }
7455
7467
  if (HTTP_MEMBER_METHODS.has(method)) {
@@ -7479,7 +7491,7 @@ function directSinks(node, ts, bindings, ctx) {
7479
7491
  push({ kind: "exec", package: pkg, op: name, attribution: "import", ...spanOf(n) });
7480
7492
  }
7481
7493
  if (name === "eval" && trueGlobal) push({ kind: "eval", op: "eval", attribution: "global", ...spanOf(n) });
7482
- if (DESERIALIZE_CALLS.test(name) && pkg && isDeserializePackage(pkg)) {
7494
+ if (pkg && deserializeModel(pkg, name)) {
7483
7495
  push({ kind: "eval", package: pkg, op: name, attribution: "import", ...spanOf(n) });
7484
7496
  }
7485
7497
  }
@@ -7558,7 +7570,10 @@ var CANDIDATE_FAMILIES = {
7558
7570
  };
7559
7571
  function argumentRoleOf(sinkKind, method, index, total = 0) {
7560
7572
  if (sinkKind === "eval" && method === "Function") return index === total - 1 ? "code" : "args";
7561
- if (sinkKind === "eval" && method === "unserialize") return index === 0 ? "code" : "unknown";
7573
+ const packageModel = PACKAGE_SINK_MODELS.find(
7574
+ (model) => model.sinkKind === sinkKind && model.api === method
7575
+ );
7576
+ if (packageModel) return index === 0 ? packageModel.argumentRole : "unknown";
7562
7577
  const table = method ? ARGUMENT_ROLES[sinkKind]?.[method] : void 0;
7563
7578
  return table?.[index] ?? "unknown";
7564
7579
  }