@patchstack/connect 0.3.28 → 0.3.29
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/dist/cli.js +215 -45
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/parsers/index.ts","../src/types.ts","../src/parsers/consistency.ts","../src/parsers/npm.ts","../src/parsers/node_modules.ts","../src/parsers/pnpm.ts","../src/parsers/yarn.ts","../src/normalize.ts","../src/checksum.ts","../src/pulse-token.ts","../src/client.ts","../src/demo.ts","../src/config.ts","../src/mark-build.ts","../src/stack.ts","../src/guide.ts","../src/protect/install/util.ts","../src/protect/install/adapters/tanstack-supabase.ts","../src/protect/install/adapters/next.ts","../src/protect/install/adapters/sveltekit.ts","../src/protect/install/seam.ts","../src/protect/install/adapters/astro.ts","../src/protect/install/adapters/nuxt.ts","../src/protect/install/find-app.ts","../src/protect/install/register.ts","../src/protect/install/generic.ts","../src/protect/install/adapters/nestjs.ts","../src/protect/install/adapters/fastify.ts","../src/protect/install/adapters/express.ts","../src/protect/install/index.ts","../src/widget.ts","../src/login.ts","../src/map/ts-loader.ts","../src/map/extract.ts","../src/map/ast.ts","../src/map/bindings.ts","../src/map/sources.ts","../src/map/routes.ts","../src/map/surface.ts","../src/map/sinks.ts","../src/map/module-graph.ts","../src/map/coordinates.ts","../src/map/inputs.ts","../src/map/flows.ts","../src/map/entries.ts","../src/map/imports.ts","../src/map/invocations.ts","../src/map/index.ts","../src/setup.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\n\nimport { scanLockfile } from './parsers/index.js';\nimport { buildWirePayload } from './normalize.js';\nimport { computeManifestChecksum } from './checksum.js';\nimport {\n postInputMap,\n DEFAULT_ENDPOINT,\n buildClaimUrl,\n fetchSiteStatus,\n postManifest,\n postPackageRemoved,\n} from './client.js';\nimport {\n assertDemoDependency,\n assertPersistedSiteUuid,\n DemoError,\n inspectDemoDependency,\n readPersistedSiteUuid,\n renderDemoGuide,\n renderDemoTestCommands,\n resolveDemoScenario,\n waitForDemoRule,\n} from './demo.js';\nimport { persistApiKey, persistSiteUuid, resolveConfig, writeConfigFile } from './config.js';\nimport {\n buildInjectionSnippet,\n findHtmlFiles,\n injectMarker,\n resolveBuildDir,\n} from './mark-build.js';\nimport {\n collectGuideState,\n countRemainingSteps,\n detectPackageManager,\n installCommand,\n renderGuideChecklist,\n} from './guide.js';\nimport { login, readPendingLogin, redeemIfApproved, startLogin, waitForApproval } from './login.js';\nimport { runProtect, runVerify } from './protect/install/index.js';\nimport { buildInputMap } from './map/index.js';\nimport { isProvenFlow } from './map/coordinates.js';\nimport { setupProtection, wireBuildScripts } from './setup.js';\nimport { detectStack, type StackDescriptor } from './stack.js';\nimport { PatchstackError } from './types.js';\nimport { buildWidgetTag, ensureSourceWidget, ensureWidgetInHtml } from './widget.js';\n\nconst HELP = `@patchstack/connect — scan your lockfile and report packages to Patchstack.\n\nUsage:\n patchstack-connect scan [options] Scan lockfile and POST to Patchstack.\n If no UUID is configured, the server\n provisions one and we persist it. After a\n successful post it also adds/updates the\n disclosure-widget <script> tag in the root\n HTML shell (index.html, public/index.html,\n or src/app.html) — opt out with\n \"widget\": false in .patchstackrc.json\n patchstack-connect setup [options] Finish the bounded project setup: run scan,\n manage the widget, install + verify runtime\n protection, and wire dependency/build scans.\n Never runs the project build\n patchstack-connect map [--dir <p>] [--out <f>] [--upload]\n Map the app's attack surface: entry points, the\n inputs each reads, the sinks it can reach, and\n evidence-backed input→sink flows (each labelled\n with how the link was established). Best-effort static\n analysis — reports the DETECTED surface, with\n coverage counters. Prints JSON (--out writes a\n file; --follow-symlinks leaves the project dir).\n Uses the app's own TypeScript\n patchstack-connect init <site-uuid> Optional: pre-seed .patchstackrc.json\n with an existing site UUID\n patchstack-connect status [options] Show current configuration and whether the\n site still exists on Patchstack (active /\n removed)\n patchstack-connect uninstall [options] Signal Patchstack that this package is being\n removed from the project. An unclaimed site\n record is deleted; a claimed site is flagged\n for its owner to remove in the dashboard.\n Does NOT touch local files — see the\n \"Uninstalling\" steps in AGENT-INSTALL.md\n patchstack-connect mark-build [options] Stamp built HTML with a production flag +\n build fingerprint, and ensure the widget\n tag in built pages (run as a postbuild step)\n patchstack-connect protect [--demo|--check] Install always-on runtime protection (the\n guard). Auto-wires supported server stacks;\n for others it scaffolds a\n generic guard + prints a wiring plan.\n --demo seeds a broad sample rule set (for\n demonstrations, not production).\n --check verifies the guard is wired (exit 1\n if not) — for the wire-then-verify loop.\n patchstack-connect demo node-serialize [--url URL] Run the production-backed node-serialize\n walkthrough: verify the vulnerable package,\n scan it, wait for live rule 18843, install +\n verify the guard, and print test requests.\n Does not install vulnerable dependencies.\n patchstack-connect demo-guide node-serialize Show a read-only, state-aware walkthrough for\n preparing, running, proving, and cleaning up\n the production-backed local demo.\n patchstack-connect guide [--full] Show this project's setup status (what's done,\n what's missing, with tailored commands), then\n print the full setup guide. --full prints the\n guide even when setup is complete\n patchstack-connect login [--wait] Recover this site's credential when\n .patchstackrc.json has been lost. Prints a link\n for the site's OWNER to approve in the dashboard.\n In a terminal it then waits. When the output is\n piped or captured — an assistant running it — it\n prints the link and EXITS, so the link is visible\n immediately. Run it AGAIN once the user confirms\n they approved: it resumes the same request rather\n than starting a new one, and finishes the flow.\n --wait blocks instead of returning. Use this\n instead of deleting\n .patchstackrc.json and re-scanning, which would\n provision a second site. Approving ROTATES the\n credential: CI, deploys and other machines using\n the old one must be updated. Not usable in CI\n patchstack-connect help Print this message\n\nOptions (for scan, setup, status, and uninstall):\n --site-uuid <uuid> Override the configured site UUID\n --endpoint <url> Override the API endpoint\n --dry-run (scan only) Show the payload without posting\n\nOptions (for mark-build):\n --dir <path> Build output directory (default: auto-detect\n dist/ build/ out/ .output/public)\n\nOptions (for demo and demo-guide):\n --url <url> Test endpoint printed at the end\n (default: http://localhost:3000/api/tasks)\n\nEnvironment:\n PATCHSTACK_SITE_UUID Site UUID\n PATCHSTACK_API_KEY WP-format site API key for block-log reporting (never put in the widget)\n PATCHSTACK_PULSE_AUTH Only if Pulse ingest uses a different credential from block-logs\n PATCHSTACK_TELEMETRY Set to off to disable block-log reporting\n PATCHSTACK_API_BASE API origin for /oauth/token and /api/logs/log (default: https://api.patchstack.com)\n PATCHSTACK_ENDPOINT API endpoint (default: https://api.patchstack.com/monitor/pulse/manifest)\n PATCHSTACK_TIMEOUT_MS Request timeout in ms (default: 30000)\n PATCHSTACK_ENVIRONMENT Manifest environment: production | sandbox (default: production)\n PATCHSTACK_MODE (protect) Runtime guard mode: block (default) | dry-run\n PATCHSTACK_ROUTE_WAF (protect) Set to 1 to also screen every request at the route level (opt-in)\n\nPrecedence: CLI flag > environment variable > .patchstackrc.json.\n\nExamples:\n npx @patchstack/connect setup\n npx @patchstack/connect scan\n npx @patchstack/connect scan --dry-run\n npx @patchstack/connect init 550e8400-e29b-41d4-a716-446655440000\n npx @patchstack/connect scan --site-uuid 550e8400-...-446655440000\n npx @patchstack/connect demo node-serialize\n npx @patchstack/connect demo-guide node-serialize\n`;\n\nconst VALUE_FLAGS = new Set(['site-uuid', 'endpoint', 'dir', 'url', 'out']);\n\ninterface ParsedArgs {\n command: string | null;\n positional: string[];\n flags: Map<string, string | true>;\n}\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const args = argv.slice(2);\n const positional: string[] = [];\n const flags = new Map<string, string | true>();\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!;\n if (!arg.startsWith('--')) {\n positional.push(arg);\n continue;\n }\n const stripped = arg.slice(2);\n const eqIdx = stripped.indexOf('=');\n if (eqIdx !== -1) {\n flags.set(stripped.slice(0, eqIdx), stripped.slice(eqIdx + 1));\n continue;\n }\n const next = args[i + 1];\n if (VALUE_FLAGS.has(stripped) && next !== undefined && !next.startsWith('--')) {\n flags.set(stripped, next);\n i++;\n } else {\n flags.set(stripped, true);\n }\n }\n\n return {\n command: positional.shift() ?? null,\n positional,\n flags,\n };\n}\n\nfunction getStringFlag(flags: Map<string, string | true>, name: string): string | undefined {\n const value = flags.get(name);\n return typeof value === 'string' ? value : undefined;\n}\n\nasync function runInit(args: ParsedArgs): Promise<number> {\n const uuid = args.positional[0];\n if (!uuid) {\n console.error('Error: site UUID is required.\\n');\n console.error('Usage: patchstack-connect init <site-uuid>');\n return 1;\n }\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(uuid)) {\n console.error(`Error: \"${uuid}\" does not look like a valid UUID.`);\n return 1;\n }\n\n const target = await writeConfigFile(process.cwd(), { siteUuid: uuid });\n console.log(`Wrote ${target}`);\n console.log('');\n console.log('Next: run `npx @patchstack/connect scan` to send your first manifest.');\n return 0;\n}\n\nasync function runLogin(args: ParsedArgs): Promise<number> {\n // CI has no browser and no human; build agents must not print credentials\n // into logs. Deploys use PATCHSTACK_PULSE_AUTH from the platform's secrets.\n if (process.env.CI !== undefined && process.env.CI !== '' && process.env.CI !== 'false') {\n console.error('`login` is interactive and cannot run in CI. Set PATCHSTACK_PULSE_AUTH instead.');\n return 1;\n }\n\n const config = await resolveConfig({\n cwd: process.cwd(),\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n\n const approved = () => {\n // The value itself is never printed — only that it landed.\n console.log('\\n ✓ Credential restored and saved to .patchstackrc.json.');\n console.log(' The previous credential no longer works. Update it anywhere else it was set:');\n console.log(' CI secrets, hosting env vars, preview environments, other checkouts.\\n');\n return 0;\n };\n\n // Resuming a request whose link has already been handed to the user.\n if (args.flags.has('wait')) {\n const pending = config.siteUuid === null ? null : readPendingLogin(config.siteUuid);\n\n if (pending === null) {\n console.error('\\n No login is waiting for approval. Run `patchstack-connect login` first.\\n');\n return 1;\n }\n\n const resumed = await waitForApproval(config, pending);\n if (resumed.status === 'approved') return approved();\n\n console.error(`\\n ${resumed.message ?? 'Login failed.'}\\n`);\n return 1;\n }\n\n const prompt = (userCode: string, verificationUri: string) => {\n console.log(`\\n Your code: ${userCode}`);\n console.log(` Approve at: ${verificationUri}\\n`);\n // Said before approval, not after: the person deciding needs to know it is\n // a rotation, and an assistant relaying this has to pass the warning on.\n console.log(\" Open that link and approve it as the site's owner. Approving issues a new\");\n console.log(' credential and stops the current one working — CI, deploys and any other');\n console.log(' machine using it will need the new value.\\n');\n };\n\n // Nobody is watching this stream. Blocking here would hide the link until the\n // command exits — by which time the code has expired — so hand it over and\n // let the caller decide when to wait.\n if (process.stdout.isTTY !== true) {\n // Running it again resumes rather than restarts. An assistant that comes\n // back after the user approves finishes the flow whether or not it\n // remembered --wait, and re-running never invalidates a link the user is\n // still looking at.\n const existing = config.siteUuid === null ? null : readPendingLogin(config.siteUuid);\n\n if (existing !== null && Date.now() < existing.expiresAt) {\n const outcome = await redeemIfApproved(config, existing);\n\n if (outcome === 'approved') return approved();\n\n if (outcome === 'pending') {\n const secondsLeft = Math.round((existing.expiresAt - Date.now()) / 1000);\n console.log(`\\n Still waiting for approval of code ${existing.userCode}.`);\n console.log(` Approve at: ${existing.verificationUri}`);\n console.log(` (valid for another ${secondsLeft}s — run this again once the user confirms)\\n`);\n return 0;\n }\n // 'expired' falls through and starts a fresh request below.\n }\n\n const started = await startLogin(config);\n\n if (started.status !== 'started' || started.pending === undefined) {\n console.error(`\\n ${started.message ?? 'Login failed.'}\\n`);\n return 1;\n }\n\n prompt(started.pending.userCode, started.pending.verificationUri);\n console.log(' Give that link to the user. When they confirm they have approved it, run');\n console.log(' this same command again (or `login --wait` to block until they do).\\n');\n\n return 0;\n }\n\n const result = await login(config, (userCode, verificationUri) => {\n prompt(userCode, verificationUri);\n console.log(' Waiting for approval (the code expires in 10 minutes)…');\n });\n\n if (result.status === 'approved') return approved();\n\n console.error(`\\n ${result.message ?? 'Login failed.'}\\n`);\n\n return 1;\n}\n\nasync function runMap(args: ParsedArgs): Promise<number> {\n const cwd = getStringFlag(args.flags, 'dir') ?? process.cwd();\n const { map, error } = await buildInputMap(cwd, {\n followSymlinks: args.flags.get('follow-symlinks') === true,\n });\n if (!map) {\n console.error(`patchstack: ${error}`);\n return 1;\n }\n // Human summary → stderr; the JSON → stdout (so it can be piped / written). Report PROVEN flows\n // separately from the inventories: only a proven tier is evidence that an input reaches a sink.\n const inputs = map.endpoints.reduce((n, e) => n + e.inputs.length, 0);\n const sinks = map.endpoints.reduce((n, e) => n + e.sinks.length, 0);\n const proven = map.endpoints.reduce((n, e) => n + e.flows.filter((f) => isProvenFlow(f.confidence)).length, 0);\n const c = map.coverage;\n console.error(\n `patchstack: ${map.endpoints.length} entry point(s), ${inputs} input(s), ${sinks} sink(s), ` +\n `${proven} proven input→sink flow(s) [${map.framework}].`,\n );\n console.error(\n // All three buckets, explicitly: \"6/66 parsed\" reads as \"91% unanalysed\" when the other 60 files\n // simply contain no server entry point (most of a project is client code). Only `skipped` is a\n // failure to analyse.\n `patchstack: ${c.filesDiscovered} file(s) found — ${c.filesParsed} analysed, ` +\n `${c.filesPreFiltered} skipped (no server entry point)` +\n (c.filesSkipped ? `, ${c.filesSkipped} could not be analysed` : '') +\n `. DETECTED surface only — static analysis is best-effort; every flow carries the tier it was ` +\n `established at (\"exact-local\" and \"transformed-local\" are proven; \"imported\", \"heuristic\" and ` +\n `\"unknown\" are not).`,\n );\n const invoked = map.apiInvocations ?? [];\n if (invoked.length > 0) {\n const c = map.coverage as unknown as Record<string, number>;\n const dependency = c.callsDependency ?? 0;\n const ambiguous = c.callsAmbiguous ?? 0;\n // Resolver quality, NOT \"share of all calls\": local helpers are excluded from both terms, because\n // declining to attribute `res.json()` to a package is a correct answer rather than a miss.\n const denominator = dependency + ambiguous;\n const quality = denominator > 0 ? Math.round((100 * dependency) / denominator) : 100;\n console.error(\n `patchstack: ${invoked.length} dependency API call(s) resolved across ${new Set(invoked.map((i) => i.package)).size} package(s) ` +\n `from ${c.callsTotal ?? 0} call site(s) — ${quality}% of dependency-candidate receivers resolved ` +\n `(${c.callsLocal ?? 0} local, ${ambiguous} ambiguous). Positive evidence only: absence here never ` +\n `means an API is not called.`,\n );\n }\n const imported = map.imports ?? [];\n if (imported.length > 0) {\n // The unmodelled count is the honest headline: it is how much of the dependency surface this map\n // cannot speak to at all, and a reader who only sees flows would never learn it.\n const unmodelled = imported.filter((d) => d.recognizedSinkKinds.length === 0).length;\n console.error(\n `patchstack: ${imported.length} package(s) imported — ${unmodelled} with no recognized sink family, ` +\n `so a vulnerability in those cannot be judged reachable or unreachable from this map.`,\n );\n }\n const json = JSON.stringify(map, null, 2);\n const out = getStringFlag(args.flags, 'out');\n if (out) {\n writeFileSync(out, json);\n console.error(`patchstack: wrote ${out}`);\n } else if (args.flags.get('upload') !== true) {\n // With --upload the map goes to Patchstack instead of stdout: printing a full structural document\n // AND sending it is noise, and the interesting output becomes what the server did with it.\n console.log(json);\n }\n\n // Opt-in, never implied. This is the only path that sends anything derived from source code, so it\n // takes an explicit flag rather than happening because a site UUID exists.\n if (args.flags.get('upload') === true) {\n if (map.endpoints.length === 0) {\n console.error('patchstack: nothing to upload — no server entry points were detected.');\n return 0;\n }\n // Same resolution order as every other network path: CLI flags, then env, then `.patchstackrc.json`.\n const config = await resolveConfig({\n cwd,\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n const outcome = await postInputMap(config, map);\n if (outcome.result === 'stored') {\n console.error(`patchstack: uploaded the attack surface (revision ${outcome.revision}).`);\n } else if (outcome.result === 'unchanged') {\n console.error(`patchstack: attack surface unchanged since revision ${outcome.revision} — nothing to store.`);\n } else if (outcome.result === 'skipped') {\n console.error(`patchstack: did not upload the attack surface — ${outcome.message}`);\n } else {\n // Fail-open: this runs inside someone's build, so a Patchstack problem must not fail it.\n console.error(`patchstack: could not upload the attack surface — ${outcome.message}`);\n }\n }\n return 0;\n}\n\nasync function runScan(\n args: ParsedArgs,\n options: { showRemainingSetup?: boolean } = {},\n): Promise<number> {\n const dryRun = args.flags.get('dry-run') === true;\n const config = await resolveConfig({\n cwd: process.cwd(),\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n const manifest = await scanLockfile(process.cwd());\n for (const warning of manifest.warnings ?? []) {\n console.warn(`patchstack: ${warning}`);\n }\n const { payload, stats } = buildWirePayload(manifest);\n\n console.log(\n `Found ${payload.packages.length} unique package versions across ${stats.uniqueNames} package names (${manifest.ecosystem} ecosystem).`,\n );\n console.log(\n `Reporting under the ${config.environment} environment (override with PATCHSTACK_ENVIRONMENT).`,\n );\n if (config.endpoint !== DEFAULT_ENDPOINT) {\n console.log(\n `Using endpoint override: ${config.endpoint} (set via --endpoint, PATCHSTACK_ENDPOINT, or .patchstackrc.json).`,\n );\n }\n if (stats.duplicateNames.length > 0) {\n const sample = stats.duplicateNames.slice(0, 10).join(', ');\n const more =\n stats.duplicateNames.length > 10 ? `, +${stats.duplicateNames.length - 10} more` : '';\n console.log(\n `${stats.duplicateNames.length} package(s) appear at multiple versions: ${sample}${more}`,\n );\n }\n\n if (dryRun) {\n console.log('');\n if (config.siteUuid === null) {\n console.log('--dry-run: no site UUID configured. A real run would provision one.');\n } else {\n console.log(`--dry-run: not posting to Patchstack (site UUID ${config.siteUuid}).`);\n }\n console.log('Payload preview:');\n const preview = JSON.stringify(payload, null, 2).split('\\n');\n console.log(preview.slice(0, Math.min(preview.length, 30)).join('\\n'));\n if (preview.length > 30) {\n console.log(` ... (${preview.length - 30} more lines)`);\n }\n return 0;\n }\n\n const provisioning = config.siteUuid === null;\n if (provisioning) {\n console.log('No site UUID configured — provisioning a new Patchstack site from this manifest…');\n }\n\n const response = await postManifest(config, payload);\n\n // The server always returns the UUID. If we didn't have one, persist it so\n // every subsequent scan targets the same site.\n if (provisioning && response.uuid !== undefined && response.uuid.length > 0) {\n const target = await persistSiteUuid(process.cwd(), response.uuid);\n console.log(`Provisioned site ${response.uuid}. Saved UUID to ${target}.`);\n }\n if (typeof response.api_key === 'string' && response.api_key.length > 0) {\n // One credential for both paths: Pulse resolution falls back to apiKey, so\n // a second copy under pulseAuth bought nothing except an obligation to keep\n // the two in step. Never printed — only the path it landed in.\n const target = await persistApiKey(process.cwd(), response.api_key);\n console.log(`Saved API key to ${target} (authenticates Pulse ingest and block-log reporting; keep out of the public widget).`);\n }\n\n if (response.stored) {\n console.log(`Stored manifest #${response.manifest_id} (checksum ${response.checksum}).`);\n } else if (response.reason === 'duplicate') {\n console.log('Manifest unchanged since last scan — nothing to store.');\n } else {\n console.log(`Server response: ${response.message ?? JSON.stringify(response)}`);\n }\n\n // With a UUID in hand (existing or freshly provisioned), ensure the\n // disclosure widget's managed tag in the source HTML shell so the very next\n // preview reload shows the \"Report a vulnerability\" button. Best-effort and\n // opt-out-able; a failed post never reaches this point, and --dry-run\n // returned above.\n const effectiveUuid = config.siteUuid ?? response.uuid ?? null;\n if (config.widget && effectiveUuid !== null && effectiveUuid.length > 0) {\n reportSourceWidget(effectiveUuid);\n }\n\n // On the first scan (provisioning), surface the dashboard URL so the user can\n // attach this site to their Patchstack account. `npx @patchstack/connect status`\n // re-displays it any time.\n if (provisioning && response.uuid !== undefined && response.uuid.length > 0) {\n console.log('');\n console.log('Open this dashboard link to view vulnerability reports:');\n console.log(` ${buildClaimUrl(config.endpoint, response.uuid)}`);\n if (config.endpoint !== DEFAULT_ENDPOINT) {\n console.log(' (this URL inherits the endpoint override above)');\n }\n }\n\n // A scan can't wire the build hooks itself — an agent that runs `scan` but not\n // `guide` (a common shortcut) otherwise sees the widget + claim URL and assumes\n // setup is finished. Surface whatever is still missing so the loop actually closes.\n if (options.showRemainingSetup !== false) {\n try {\n const state = await collectGuideState(process.cwd());\n const remaining = countRemainingSteps(state);\n if (remaining > 0) {\n const hooksMissing = !(state.prebuildWired && state.postbuildWired);\n console.log('');\n console.log(\n `Setup not complete — ${remaining} step(s) remaining${hooksMissing ? \", including the package.json build hooks (which scan can't wire)\" : ''}.`,\n );\n console.log('Run `npx @patchstack/connect guide` for the exact steps to finish for this project.');\n }\n } catch {\n // Best-effort: never turn a successful scan into a failure over this nudge.\n }\n }\n\n return 0;\n}\n\n/**\n * Run the source-widget pass for `scan` and narrate the outcome. Never throws:\n * widget management is a convenience layered on top of a successful scan and\n * must not turn one into a failure.\n */\nfunction reportSourceWidget(siteUuid: string): void {\n try {\n const result = ensureSourceWidget(process.cwd(), siteUuid);\n switch (result.action) {\n case 'added':\n console.log(`Widget: added the \"Report a vulnerability\" tag to ${result.shell}. Reload your preview to see it.`);\n break;\n case 'updated':\n console.log(`Widget: updated the managed tag in ${result.shell} to site ${siteUuid}.`);\n break;\n case 'unchanged':\n console.log(`Widget: already installed in ${result.shell}.`);\n break;\n case 'manual':\n console.log(`Widget: found an existing (manual) install in ${result.shell} — left untouched.`);\n break;\n case 'no-body':\n console.log(`Widget: ${result.shell} has no </body> tag to anchor on. Add this tag to your root layout manually:`);\n console.log(` ${buildWidgetTag(siteUuid)}`);\n break;\n case 'no-shell':\n console.log('Widget: no plain HTML shell found (index.html / public/index.html / src/app.html).');\n console.log('Add this tag to your root layout before </body> (run `guide` for framework-specific placement):');\n console.log(` ${buildWidgetTag(siteUuid)}`);\n break;\n }\n if (result.action === 'added' || result.action === 'updated') {\n console.log(' (opt out any time with \"widget\": false in .patchstackrc.json)');\n }\n } catch (err) {\n console.warn(`Widget: skipped (${(err as Error).message}).`);\n }\n}\n\nasync function runProtectCommand(args: ParsedArgs): Promise<number> {\n // `--check`: verify the guard is wired (for the agent/CI loop). Non-zero exit if not.\n if (args.flags.get('check') === true) {\n const report = runVerify(process.cwd());\n console.log(`patchstack protect --check (${report.stack}):`);\n for (const c of report.checks) {\n console.log(` ${c.ok ? '✓' : '✗'} ${c.label}${!c.ok && c.hint ? ` — ${c.hint}` : ''}`);\n }\n console.log(report.wired ? 'guard is wired ✓' : 'guard is NOT fully wired ✗');\n return report.wired ? 0 : 1;\n }\n // Best-effort: like mark-build, this runs during builds and must never fail one.\n const demo = args.flags.get('demo') === true;\n try {\n runProtect(process.cwd(), { demo });\n } catch (err) {\n console.warn(`patchstack protect: skipped (${(err as Error).message}).`);\n }\n return 0;\n}\n\nasync function runDemoCommand(args: ParsedArgs): Promise<number> {\n try {\n const scenario = resolveDemoScenario(args.positional[0]);\n const cwd = process.cwd();\n const config = await resolveConfig({\n cwd,\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n requireSiteUuid: true,\n });\n if (config.environment !== 'production') {\n throw new DemoError(\n 'The production-backed demo requires PATCHSTACK_ENVIRONMENT=production. Unset the sandbox override and try again.',\n );\n }\n\n await assertPersistedSiteUuid(cwd, config.siteUuid!);\n await assertDemoDependency(cwd, scenario);\n console.log(`Patchstack production demo — ${scenario.packageName}@${scenario.packageVersion}`);\n console.log(` Site: ${config.siteUuid}`);\n console.log('');\n console.log('1. Report the current npm manifest');\n const scanCode = await runScan(args, { showRemainingSetup: false });\n if (scanCode !== 0) return scanCode;\n\n console.log('');\n console.log(`2. Wait for live virtual-patch rule ${scenario.ruleId}`);\n const rule = await waitForDemoRule(config.endpoint, config.siteUuid!, scenario, {\n requestTimeoutMs: config.timeoutMs,\n });\n console.log(`Rule ready: ${rule.id}${rule.title ? ` — ${rule.title}` : ''}`);\n\n console.log('');\n console.log('3. Install and verify the runtime guard');\n const result = runProtect(cwd);\n if (result.status === 'unsupported') {\n throw new DemoError(\n `Runtime protection is not supported for this stack. Supported: ${result.supported.join(', ')}.`,\n );\n }\n console.log(`Guard installer: ${result.adapter} (${result.status})`);\n const report = runVerify(cwd);\n for (const check of report.checks) {\n console.log(` ${check.ok ? '✓' : '✗'} ${check.label}${!check.ok && check.hint ? ` — ${check.hint}` : ''}`);\n }\n if (!report.wired) {\n throw new DemoError(\n `The ${report.stack} guard is not fully wired. Complete the failed check above, then run this command again.`,\n );\n }\n\n console.log('');\n console.log('Production virtual patch is ready.');\n console.log('');\n console.log(\n renderDemoTestCommands(\n getStringFlag(args.flags, 'url') ?? 'http://localhost:3000/api/tasks',\n scenario,\n ),\n );\n return 0;\n } catch (error) {\n if (error instanceof DemoError) {\n console.error(`Demo error: ${error.message}`);\n return 1;\n }\n throw error;\n }\n}\n\nasync function runDemoGuideCommand(args: ParsedArgs): Promise<number> {\n try {\n const scenario = resolveDemoScenario(args.positional[0]);\n const cwd = process.cwd();\n const config = await resolveConfig({ cwd });\n const [siteUuid, dependency] = await Promise.all([\n readPersistedSiteUuid(cwd),\n inspectDemoDependency(cwd, scenario),\n ]);\n console.log(\n renderDemoGuide({\n scenario,\n packageManager: detectPackageManager(cwd),\n siteUuid,\n dependency,\n environment: config.environment,\n url: getStringFlag(args.flags, 'url') ?? 'http://localhost:3000/api/tasks',\n }),\n );\n return 0;\n } catch (error) {\n if (error instanceof DemoError) {\n console.error(`Demo guide error: ${error.message}`);\n return 1;\n }\n throw error;\n }\n}\n\nasync function runGuide(args: ParsedArgs): Promise<number> {\n // The live checklist first: what this project already has and what's missing,\n // with commands tailored to it. Best-effort — a project we can't inspect\n // still gets the reference doc.\n let allDone = false;\n try {\n const state = await collectGuideState(process.cwd());\n const useColor = process.stdout.isTTY === true && process.env.NO_COLOR === undefined;\n console.log(renderGuideChecklist(state, useColor));\n allDone = countRemainingSteps(state) === 0;\n } catch {\n // fall through to the static guide\n }\n\n // A fully green project doesn't need the ~90-line manual again on every\n // re-run — point at it instead. `--full` always prints it.\n if (allDone && args.flags.get('full') !== true) {\n console.log('');\n console.log(\n 'Full reference guide: `npx @patchstack/connect guide --full` (or read node_modules/@patchstack/connect/AGENT-INSTALL.md).',\n );\n return 0;\n }\n\n console.log('');\n console.log('———— Full reference guide (ships as AGENT-INSTALL.md) ————');\n console.log('');\n\n // AGENT-INSTALL.md ships at the package root, one level above dist/ (and\n // above src/ when running unbundled), so the same relative path works in both.\n const guidePath = new URL('../AGENT-INSTALL.md', import.meta.url);\n console.log(readFileSync(guidePath, 'utf8'));\n return 0;\n}\n\nasync function runSetup(args: ParsedArgs): Promise<number> {\n if (args.flags.get('dry-run') === true) {\n console.error('Error: setup does not support --dry-run. Use `scan --dry-run` to preview the manifest.');\n return 1;\n }\n\n const before = await collectGuideState(process.cwd());\n if (!before.hasPackageJson) {\n console.error('Error: no package.json found. Run setup from the project root.');\n return 1;\n }\n if (before.installed === null) {\n console.error(\n `Error: @patchstack/connect is not declared in package.json.\\nRun: ${installCommand(before.packageManager)}`,\n );\n return 1;\n }\n\n console.log('Patchstack setup — applying bounded project changes');\n console.log(' 1. Scan dependencies, provision/reuse the site, and manage the source widget');\n const scanCode = await runScan(args, { showRemainingSetup: false });\n if (scanCode !== 0) {\n return scanCode;\n }\n\n console.log('');\n console.log(' 2. Install and verify runtime protection');\n const protection = setupProtection(process.cwd());\n if (protection.verification.wired) {\n console.log(`Runtime protection: wired (${protection.verification.stack}).`);\n } else {\n console.log(`Runtime protection: manual wiring remains (${protection.verification.stack}):`);\n for (const check of protection.verification.checks) {\n console.log(` ${check.ok ? '✓' : '✗'} ${check.label}${!check.ok && check.hint ? ` — ${check.hint}` : ''}`);\n }\n console.log('Run `npx @patchstack/connect protect --check` after completing the failed checks.');\n }\n\n console.log('');\n console.log(' 3. Wire dependency-install and production-build scans into package.json');\n const wired = wireBuildScripts(process.cwd(), before.packageManager);\n console.log(`Build integration: ${wired.detail}`);\n\n console.log('');\n console.log(' 4. Verify setup status');\n const after = await collectGuideState(process.cwd());\n const useColor = process.stdout.isTTY === true && process.env.NO_COLOR === undefined;\n console.log(renderGuideChecklist(after, useColor));\n\n const remaining = countRemainingSteps(after);\n if (remaining > 0) {\n console.log('');\n console.log(`Setup applied its bounded changes; ${remaining} manual step(s) remain above.`);\n }\n return 0;\n}\n\nasync function runStatus(args: ParsedArgs): Promise<number> {\n const config = await resolveConfig({\n cwd: process.cwd(),\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n console.log(`Site UUID: ${config.siteUuid ?? '(none yet — the next `scan` will provision one)'}`);\n console.log(\n `Endpoint: ${config.endpoint}${config.endpoint === DEFAULT_ENDPOINT ? '' : ' (override)'}`,\n );\n console.log(`Timeout: ${config.timeoutMs}ms`);\n console.log(`Environment: ${config.environment}`);\n if (config.siteUuid !== null) {\n console.log(`Dashboard URL: ${buildClaimUrl(config.endpoint, config.siteUuid)}`);\n\n switch (await fetchSiteStatus(config)) {\n case 'active':\n console.log('Site status: active on Patchstack');\n break;\n case 'removed':\n console.log('Site status: removed from Patchstack');\n console.log(\n ' The site record no longer exists (deleted from the dashboard or via the',\n );\n console.log(\n ' widget uninstall flow). The local integration files are still in this',\n );\n console.log(\n ' project — see \"Uninstalling\" in AGENT-INSTALL.md to remove them.',\n );\n break;\n case 'unknown':\n console.log('Site status: could not be verified (Patchstack unreachable)');\n break;\n }\n }\n return 0;\n}\n\nasync function runUninstall(args: ParsedArgs): Promise<number> {\n const config = await resolveConfig({\n cwd: process.cwd(),\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n\n if (config.siteUuid === null) {\n console.log('No site UUID configured — there is no site record to signal about.');\n console.log('Continue with the local removal steps in AGENT-INSTALL.md (\"Uninstalling\").');\n return 0;\n }\n\n console.log(`Signalling Patchstack that @patchstack/connect is being removed (site ${config.siteUuid})…`);\n const outcome = await postPackageRemoved(config);\n\n switch (outcome.result) {\n case 'deleted':\n console.log('Site record removed from Patchstack (the site was unclaimed).');\n break;\n case 'flagged':\n console.log('This site is claimed by a Patchstack account, so its record was kept and flagged.');\n console.log('Its owner can remove it at https://app.patchstack.com to free the site slot.');\n break;\n case 'gone':\n console.log('The site record no longer exists on Patchstack — nothing to signal.');\n break;\n case 'failed':\n console.warn(`Could not signal Patchstack${outcome.message !== null ? ` (${outcome.message})` : ''}.`);\n console.warn('The site record may remain — it can always be removed from the dashboard at https://app.patchstack.com.');\n break;\n }\n\n console.log('');\n console.log('This command only signals Patchstack. The local integration files must still be');\n console.log('removed — follow the \"Uninstalling\" steps in AGENT-INSTALL.md.');\n // Never fail the uninstall flow over the signal: local removal must proceed.\n return 0;\n}\n\n/** One-line, human-readable summary of a detected stack for CLI output. */\nfunction describeStack(stack: StackDescriptor): string | null {\n const parts = [stack.builder, stack.framework, stack.ui, stack.runtime].filter(\n (part): part is string => part !== null,\n );\n if (stack.hostingEnvKeys.length > 0) {\n parts.push(`${stack.hostingEnvKeys.length} hosting env key(s)`);\n }\n return parts.length > 0 ? parts.join(' · ') : null;\n}\n\nasync function runMarkBuild(args: ParsedArgs): Promise<number> {\n const cwd = process.cwd();\n\n // Compute the build fingerprint and stack descriptor from the lockfile.\n // Best-effort: mark-build is a postbuild step and must never fail the build, so\n // a missing/unreadable lockfile just means we stamp the production flag without\n // a fingerprint or stack.\n let checksum: string | null = null;\n let stack: StackDescriptor | null = null;\n try {\n const manifest = await scanLockfile(cwd);\n for (const warning of manifest.warnings ?? []) {\n console.warn(`mark-build: ${warning}`);\n }\n const { payload } = buildWirePayload(manifest);\n checksum = computeManifestChecksum(payload.packages);\n stack = detectStack(payload.packages);\n } catch (err) {\n console.warn(\n `mark-build: could not compute the build fingerprint (${(err as Error).message}). Stamping the production flag only.`,\n );\n }\n\n // The widget pass needs the configured UUID; best-effort for the same reason.\n let widgetUuid: string | null = null;\n try {\n const config = await resolveConfig({\n cwd,\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n });\n if (config.widget) {\n widgetUuid = config.siteUuid;\n }\n } catch (err) {\n console.warn(\n `mark-build: could not resolve the site UUID (${(err as Error).message}). Skipping the widget pass.`,\n );\n }\n\n const dir = resolveBuildDir(cwd, getStringFlag(args.flags, 'dir'));\n if (dir === null) {\n console.warn(\n 'mark-build: no build output directory found (looked for dist/, build/, out/, .output/public). Pass --dir <path> if it is elsewhere. Nothing to mark.',\n );\n return 0;\n }\n\n const files = findHtmlFiles(dir);\n if (files.length === 0) {\n console.warn(`mark-build: no HTML files found under ${dir}. Nothing to mark.`);\n return 0;\n }\n\n const snippet = buildInjectionSnippet(checksum, stack);\n let marked = 0;\n let widgetTouched = 0;\n for (const file of files) {\n const before = readFileSync(file, 'utf8');\n let after = injectMarker(before, snippet);\n // Built HTML that came through a shell scan already edited carries the\n // managed tag; this covers output whose source shell we couldn't edit.\n // Manual installs are adopted (left untouched), same as in scan.\n if (widgetUuid !== null) {\n const ensured = ensureWidgetInHtml(after, widgetUuid);\n if (ensured.action === 'added' || ensured.action === 'updated') {\n widgetTouched += 1;\n }\n after = ensured.html;\n }\n if (after !== before) {\n writeFileSync(file, after);\n marked += 1;\n }\n }\n\n const stackSummary = stack !== null ? describeStack(stack) : null;\n console.log(\n `mark-build: marked ${marked} HTML file(s) in ${dir}` +\n `${checksum !== null ? ` (build ${checksum})` : ''}` +\n `${widgetTouched > 0 ? `, widget tag ensured in ${widgetTouched}` : ''}` +\n `${stackSummary !== null ? ` [${stackSummary}]` : ''}.`,\n );\n return 0;\n}\n\nasync function main(): Promise<number> {\n const args = parseArgs(process.argv);\n\n if (args.flags.has('help') || args.command === 'help' || args.command === null) {\n console.log(HELP);\n return 0;\n }\n\n switch (args.command) {\n case 'init':\n return runInit(args);\n case 'scan':\n return runScan(args);\n case 'status':\n return runStatus(args);\n case 'uninstall':\n return runUninstall(args);\n case 'mark-build':\n return runMarkBuild(args);\n case 'protect':\n return runProtectCommand(args);\n case 'demo':\n return runDemoCommand(args);\n case 'demo-guide':\n return runDemoGuideCommand(args);\n case 'guide':\n return runGuide(args);\n case 'setup':\n return runSetup(args);\n case 'map':\n return runMap(args);\n case 'login':\n return runLogin(args);\n default:\n console.error(`Unknown command: ${args.command}\\n`);\n console.error(HELP);\n return 1;\n }\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err: unknown) => {\n if (err instanceof PatchstackError) {\n console.error(`Error (${err.code}): ${err.message}`);\n process.exit(1);\n }\n console.error('Unexpected error:', err);\n process.exit(2);\n });\n","import { access } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type Manifest, type PackageEntry } from '../types.js';\nimport { missingDependencies, readDeclaredDependencyNames } from './consistency.js';\nimport { parseNpmLockfile } from './npm.js';\nimport { walkNodeModules } from './node_modules.js';\nimport { parsePnpmLockfile } from './pnpm.js';\nimport { parseYarnLockfile } from './yarn.js';\n\ntype LockfileFilename =\n | 'package-lock.json'\n | 'bun.lock'\n | 'bun.lockb'\n | 'yarn.lock'\n | 'pnpm-lock.yaml';\n\ntype DetectionStrategy =\n | 'npm-lockfile'\n | 'node-modules-walk'\n | 'pnpm-lockfile'\n | 'yarn-lockfile';\n\ninterface DetectedLockfile {\n ecosystem: 'npm';\n filePath: string;\n filename: LockfileFilename;\n strategy: DetectionStrategy;\n}\n\ninterface LockfileCandidate {\n filename: LockfileFilename;\n strategy: DetectionStrategy;\n}\n\n// Checked in priority order: the first candidate present in `cwd` wins.\nconst LOCKFILE_CANDIDATES: readonly LockfileCandidate[] = [\n { filename: 'package-lock.json', strategy: 'npm-lockfile' },\n { filename: 'bun.lock', strategy: 'node-modules-walk' },\n { filename: 'bun.lockb', strategy: 'node-modules-walk' },\n { filename: 'pnpm-lock.yaml', strategy: 'pnpm-lockfile' },\n { filename: 'yarn.lock', strategy: 'yarn-lockfile' },\n];\n\nexport async function detectLockfile(cwd: string): Promise<DetectedLockfile> {\n // Probe every candidate concurrently, then resolve by declaration order so\n // the result is identical to a sequential first-match scan — but bounded by a\n // single I/O round-trip instead of up to one `stat` per candidate.\n const probed = await Promise.all(\n LOCKFILE_CANDIDATES.map(async (candidate) => {\n const filePath = path.join(cwd, candidate.filename);\n return { ...candidate, filePath, present: await exists(filePath) };\n }),\n );\n\n const match = probed.find((candidate) => candidate.present);\n if (match) {\n return {\n ecosystem: 'npm',\n filePath: match.filePath,\n filename: match.filename,\n strategy: match.strategy,\n };\n }\n\n const expected = LOCKFILE_CANDIDATES.map((candidate) => candidate.filename).join(', ');\n throw new PatchstackError(\n `No lockfile found in ${cwd}. Expected one of: ${expected}.`,\n 'LOCKFILE_NOT_FOUND',\n );\n}\n\nexport async function scanLockfile(cwd: string): Promise<Manifest> {\n const candidates = await presentLockfiles(cwd);\n if (candidates.length === 0) {\n // Preserve the exact historical error for the no-lockfile case.\n await detectLockfile(cwd);\n }\n\n // Validate each source against package.json before trusting it. A lockfile\n // missing declared dependencies is a fossil — e.g. `npm install` planted a\n // package-lock.json once on a bun-managed platform (Lovable), and the native\n // dependency flow never updates it again. Trusting it would freeze the\n // manifest and the build fingerprint while the real dependency set drifts.\n const declared = await readDeclaredDependencyNames(cwd);\n const warnings: string[] = [];\n let firstParsed: { packages: PackageEntry[]; filename: string } | null = null;\n let walkTried = false;\n\n for (const candidate of candidates) {\n let packages: PackageEntry[];\n try {\n packages = await runStrategy(candidate, cwd);\n } catch {\n continue;\n }\n walkTried ||= candidate.strategy === 'node-modules-walk';\n firstParsed ??= { packages, filename: candidate.filename };\n\n const missing = missingDependencies(declared, packages);\n if (missing.length === 0) {\n return manifestWith(packages, warnings);\n }\n warnings.push(staleWarning(candidate.filename, missing));\n }\n\n // Last resort: the installed truth. node_modules reflects what the build\n // actually compiles against, whichever package manager wrote it.\n if (!walkTried) {\n try {\n const packages = await walkNodeModules(cwd);\n const missing = missingDependencies(declared, packages);\n if (missing.length > 0) {\n warnings.push(staleWarning('node_modules/', missing));\n }\n warnings.push('Scanned node_modules/ instead. Delete the stale lockfile to silence this warning.');\n return manifestWith(packages, warnings);\n } catch {\n // fall through to the best lockfile we managed to parse\n }\n }\n\n if (firstParsed === null) {\n const expected = LOCKFILE_CANDIDATES.map((candidate) => candidate.filename).join(', ');\n throw new PatchstackError(\n `No readable lockfile found in ${cwd}. Expected one of: ${expected}.`,\n 'LOCKFILE_NOT_FOUND',\n );\n }\n\n warnings.push(\n `No fully-consistent source found; reporting ${firstParsed.filename}. The manifest may understate the real dependency set.`,\n );\n\n return manifestWith(firstParsed.packages, warnings);\n}\n\nfunction manifestWith(packages: PackageEntry[], warnings: string[]): Manifest {\n return warnings.length > 0\n ? { ecosystem: 'npm', packages, warnings }\n : { ecosystem: 'npm', packages };\n}\n\nfunction staleWarning(source: string, missing: string[]): string {\n const sample = missing.slice(0, 3).join(', ');\n const suffix = missing.length > 3 ? `, +${missing.length - 3} more` : '';\n return `${source} looks stale: package.json declares ${missing.length} dependenc${missing.length === 1 ? 'y' : 'ies'} it does not contain (${sample}${suffix}).`;\n}\n\nasync function presentLockfiles(cwd: string): Promise<DetectedLockfile[]> {\n const probed = await Promise.all(\n LOCKFILE_CANDIDATES.map(async (candidate) => {\n const filePath = path.join(cwd, candidate.filename);\n return { ...candidate, filePath, present: await exists(filePath) };\n }),\n );\n\n return probed\n .filter((candidate) => candidate.present)\n .map(({ filename, strategy, filePath }) => ({ ecosystem: 'npm' as const, filename, strategy, filePath }));\n}\n\nasync function runStrategy(\n detected: DetectedLockfile,\n cwd: string,\n): Promise<PackageEntry[]> {\n switch (detected.strategy) {\n case 'npm-lockfile':\n return parseNpmLockfile(detected.filePath);\n case 'pnpm-lockfile':\n return parsePnpmLockfile(detected.filePath);\n case 'yarn-lockfile':\n return parseYarnLockfile(detected.filePath);\n case 'node-modules-walk':\n return walkNodeModules(cwd);\n }\n}\n\nasync function exists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","export type Ecosystem = 'npm' | 'composer';\n\n/**\n * Which environment a manifest was captured in. The connector reports from real\n * builds (prebuild scan / build hooks), so it defaults to 'production'. Override\n * with PATCHSTACK_ENVIRONMENT=sandbox (or \"environment\" in .patchstackrc.json)\n * for test manifests.\n */\nexport type Environment = 'production' | 'sandbox';\n\nexport interface PackageEntry {\n name: string;\n version: string;\n path?: string;\n direct?: boolean;\n}\n\nexport interface Manifest {\n ecosystem: Ecosystem;\n packages: PackageEntry[];\n /**\n * Human-readable scan diagnostics — set when the preferred lockfile looked\n * stale (missing dependencies declared in package.json) and another source\n * was used, or when no fully-consistent source existed. Never fatal.\n */\n warnings?: string[];\n}\n\nexport interface Config {\n /**\n * The site UUID. `null` means we don't have one yet — `postManifest` will then\n * post to the bare endpoint, the server will provision a fresh site, and the\n * UUID it returns should be persisted via `persistSiteUuid()`.\n */\n siteUuid: string | null;\n /**\n * WP-format site API key (`{oauth.secret}-{oauth.id}`) for authenticated\n * block-log reporting via connector `/api/logs/log`. Issued once as `api_key`\n * on first provision. Prefer `PATCHSTACK_API_KEY` in production deploys.\n */\n apiKey: string | null;\n /**\n * Credential for the authenticated Pulse endpoints (ADR-0018). Exchanged for\n * a short-lived bearer token at `monitor/pulse/token`; never sent directly.\n * Falls back to `apiKey` when unset. Prefer `PATCHSTACK_PULSE_AUTH`.\n */\n pulseAuth: string | null;\n endpoint: string;\n timeoutMs: number;\n /** Environment to report the manifest under. Defaults to 'production'. */\n environment: Environment;\n /**\n * Whether the connector manages the disclosure-widget tag (source shell on\n * `scan`, built HTML on `mark-build`). Defaults to true; persist\n * `\"widget\": false` in .patchstackrc.json for dependency-scanning only.\n */\n widget: boolean;\n}\n\nexport interface StoreManifestResponse {\n /** The UUID of the site the manifest was stored against. Always returned. */\n uuid?: string;\n /**\n * WP-format API key for connector log ingest. Present only when oauth\n * credentials are created in this request (first provision / backfill).\n */\n api_key?: string;\n stored: boolean;\n manifest_id?: number;\n checksum?: string;\n reason?: string;\n message?: string;\n error?: string;\n}\n\nexport class PatchstackError extends Error {\n constructor(\n message: string,\n public readonly code:\n | 'CONFIG_MISSING'\n | 'CONFIG_INVALID'\n | 'LOCKFILE_NOT_FOUND'\n | 'LOCKFILE_UNSUPPORTED'\n | 'LOCKFILE_PARSE_ERROR'\n | 'NETWORK_ERROR'\n | 'NETWORK_TIMEOUT'\n | 'SITE_NOT_FOUND'\n | 'UNAUTHORIZED'\n | 'VALIDATION_ERROR'\n | 'SERVER_ERROR',\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = 'PatchstackError';\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { PackageEntry } from '../types.js';\n\n/**\n * Registry-installable dependency names declared in package.json\n * (dependencies + devDependencies). Non-registry specifiers (file:, link:,\n * workspace:, portal:) are excluded — lockfile parsers skip those too, so\n * their absence from a parsed set says nothing about staleness. Returns []\n * when package.json is missing or unreadable (nothing to validate against).\n */\nexport async function readDeclaredDependencyNames(cwd: string): Promise<string[]> {\n let raw: string;\n try {\n raw = await readFile(path.join(cwd, 'package.json'), 'utf8');\n } catch {\n return [];\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return [];\n }\n if (typeof parsed !== 'object' || parsed === null) {\n return [];\n }\n\n const names = new Set<string>();\n for (const group of ['dependencies', 'devDependencies'] as const) {\n const deps = (parsed as Record<string, unknown>)[group];\n if (typeof deps !== 'object' || deps === null) {\n continue;\n }\n for (const [name, spec] of Object.entries(deps as Record<string, unknown>)) {\n if (typeof spec === 'string' && /^(file|link|workspace|portal):/.test(spec)) {\n continue;\n }\n names.add(name);\n }\n }\n\n return [...names];\n}\n\n/**\n * Declared names absent from a parsed package set. A non-empty result means\n * the source predates package.json — the fossil-lockfile failure mode where\n * e.g. `npm install` planted a package-lock.json once and the platform's\n * native package manager (bun on Lovable) never updates it again.\n */\nexport function missingDependencies(declared: string[], packages: PackageEntry[]): string[] {\n const present = new Set(packages.map((entry) => entry.name));\n return declared.filter((name) => !present.has(name));\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type PackageEntry } from '../types.js';\n\ninterface LockfileV2Package {\n name?: string;\n version?: string;\n link?: boolean;\n resolved?: string;\n}\n\ninterface LockfileV2 {\n lockfileVersion: number;\n packages?: Record<string, LockfileV2Package>;\n dependencies?: Record<string, LockfileV1Dependency>;\n}\n\ninterface LockfileV1Dependency {\n version: string;\n dependencies?: Record<string, LockfileV1Dependency>;\n}\n\nexport async function parseNpmLockfile(lockfilePath: string): Promise<PackageEntry[]> {\n let raw: string;\n try {\n raw = await readFile(lockfilePath, 'utf8');\n } catch (cause) {\n throw new PatchstackError(`Could not read lockfile at ${lockfilePath}`, 'LOCKFILE_NOT_FOUND', cause);\n }\n\n let parsed: LockfileV2;\n try {\n parsed = JSON.parse(raw) as LockfileV2;\n } catch (cause) {\n throw new PatchstackError(`Lockfile at ${lockfilePath} is not valid JSON`, 'LOCKFILE_PARSE_ERROR', cause);\n }\n\n if (parsed.packages) {\n return extractFromV2(parsed.packages);\n }\n\n if (parsed.dependencies) {\n return extractFromV1(parsed.dependencies);\n }\n\n throw new PatchstackError(\n `Lockfile at ${lockfilePath} has no \"packages\" or \"dependencies\" key`,\n 'LOCKFILE_PARSE_ERROR',\n );\n}\n\nfunction extractFromV2(packages: Record<string, LockfileV2Package>): PackageEntry[] {\n const entries: PackageEntry[] = [];\n\n for (const [pkgPath, pkg] of Object.entries(packages)) {\n if (pkgPath === '') {\n continue;\n }\n if (pkg.link === true) {\n continue;\n }\n if (typeof pkg.version !== 'string' || pkg.version.length === 0) {\n continue;\n }\n\n const name = pkg.name ?? extractNameFromPath(pkgPath);\n if (name === null) {\n continue;\n }\n\n entries.push({\n name,\n version: pkg.version,\n path: pkgPath,\n direct: isDirectV2(pkgPath),\n });\n }\n\n return entries;\n}\n\nfunction extractFromV1(\n deps: Record<string, LockfileV1Dependency>,\n acc: PackageEntry[] = [],\n depth = 0,\n): PackageEntry[] {\n for (const [name, dep] of Object.entries(deps)) {\n if (typeof dep.version === 'string' && dep.version.length > 0) {\n acc.push({ name, version: dep.version, direct: depth === 0 });\n }\n if (dep.dependencies) {\n extractFromV1(dep.dependencies, acc, depth + 1);\n }\n }\n return acc;\n}\n\nfunction extractNameFromPath(pkgPath: string): string | null {\n const segments = pkgPath.split('node_modules' + path.sep === pkgPath ? path.sep : '/');\n const parts = pkgPath.split('/');\n const nmIndex = parts.lastIndexOf('node_modules');\n if (nmIndex === -1 || nmIndex >= parts.length - 1) {\n return segments[segments.length - 1] ?? null;\n }\n const tail = parts.slice(nmIndex + 1);\n if (tail.length === 0) {\n return null;\n }\n const first = tail[0];\n if (first !== undefined && first.startsWith('@') && tail.length >= 2) {\n return `${first}/${tail[1]}`;\n }\n return first ?? null;\n}\n\nfunction isDirectV2(pkgPath: string): boolean {\n const parts = pkgPath.split('/');\n const nmCount = parts.filter((p) => p === 'node_modules').length;\n return nmCount === 1;\n}\n","import { lstat, readFile, readdir, stat } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type PackageEntry } from '../types.js';\n\nexport async function walkNodeModules(cwd: string): Promise<PackageEntry[]> {\n const root = path.join(cwd, 'node_modules');\n\n try {\n const info = await stat(root);\n if (!info.isDirectory()) {\n throw new PatchstackError(\n `${root} exists but is not a directory.`,\n 'LOCKFILE_NOT_FOUND',\n );\n }\n } catch (cause) {\n if (cause instanceof PatchstackError) {\n throw cause;\n }\n throw new PatchstackError(\n `node_modules/ not found at ${cwd}. Install dependencies first (e.g. \\`bun install\\` or \\`npm install\\`).`,\n 'LOCKFILE_NOT_FOUND',\n cause,\n );\n }\n\n const entries: PackageEntry[] = [];\n await walk(root, entries, 0);\n return entries;\n}\n\nasync function walk(dir: string, acc: PackageEntry[], depth: number): Promise<void> {\n let names: string[];\n try {\n names = await readdir(dir);\n } catch {\n return;\n }\n\n for (const name of names) {\n if (name.startsWith('.')) {\n continue;\n }\n\n const fullPath = path.join(dir, name);\n if (!(await isPlainDirectory(fullPath))) {\n continue;\n }\n\n if (name.startsWith('@')) {\n let subNames: string[];\n try {\n subNames = await readdir(fullPath);\n } catch {\n continue;\n }\n for (const sub of subNames) {\n if (sub.startsWith('.')) {\n continue;\n }\n const scopedDir = path.join(fullPath, sub);\n if (!(await isPlainDirectory(scopedDir))) {\n continue;\n }\n await readPackage(scopedDir, depth, acc);\n await walkNested(scopedDir, acc, depth);\n }\n continue;\n }\n\n await readPackage(fullPath, depth, acc);\n await walkNested(fullPath, acc, depth);\n }\n}\n\nasync function readPackage(\n pkgDir: string,\n depth: number,\n acc: PackageEntry[],\n): Promise<void> {\n let raw: string;\n try {\n raw = await readFile(path.join(pkgDir, 'package.json'), 'utf8');\n } catch {\n return;\n }\n\n let parsed: { name?: unknown; version?: unknown };\n try {\n parsed = JSON.parse(raw) as { name?: unknown; version?: unknown };\n } catch {\n return;\n }\n\n if (typeof parsed.name !== 'string' || parsed.name.length === 0) {\n return;\n }\n if (typeof parsed.version !== 'string' || parsed.version.length === 0) {\n return;\n }\n\n acc.push({\n name: parsed.name,\n version: parsed.version,\n direct: depth === 0,\n });\n}\n\nasync function walkNested(\n pkgDir: string,\n acc: PackageEntry[],\n depth: number,\n): Promise<void> {\n const nested = path.join(pkgDir, 'node_modules');\n if (!(await isPlainDirectory(nested))) {\n return;\n }\n await walk(nested, acc, depth + 1);\n}\n\nasync function isPlainDirectory(dir: string): Promise<boolean> {\n try {\n const info = await lstat(dir);\n return info.isDirectory() && !info.isSymbolicLink();\n } catch {\n return false;\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { PatchstackError, type PackageEntry } from '../types.js';\n\n/**\n * Parses pnpm-lock.yaml without pulling in a YAML library. We don't need full\n * YAML semantics — only the `packages:` block (the canonical list of every\n * installed package) and, for direct-dep marking, the dependency sections under\n * `importers:` (v9+) or at the top level (v6-v8 single-project).\n *\n * Supported pnpm-lock key formats:\n * v5: /pkg/1.0.0 /@scope/pkg/1.0.0\n * v6-v8: /pkg@1.0.0 /@scope/pkg@1.0.0 (optional `(peer@x)` suffix)\n * v9: pkg@1.0.0 @scope/pkg@1.0.0 (optional `(peer@x)` suffix, may be quoted)\n */\nexport async function parsePnpmLockfile(lockfilePath: string): Promise<PackageEntry[]> {\n let raw: string;\n try {\n raw = await readFile(lockfilePath, 'utf8');\n } catch (cause) {\n throw new PatchstackError(\n `Could not read lockfile at ${lockfilePath}`,\n 'LOCKFILE_NOT_FOUND',\n cause,\n );\n }\n\n const lines = raw.split(/\\r?\\n/);\n const directNames = collectDirectDepNames(lines);\n const packageKeys = collectPackagesBlockKeys(lines);\n\n if (packageKeys.length === 0) {\n throw new PatchstackError(\n `Lockfile at ${lockfilePath} has no \"packages\" entries`,\n 'LOCKFILE_PARSE_ERROR',\n );\n }\n\n const entries: PackageEntry[] = [];\n for (const key of packageKeys) {\n const parsed = parsePackageKey(key);\n if (parsed === null) {\n continue;\n }\n entries.push({\n name: parsed.name,\n version: parsed.version,\n direct: directNames.has(parsed.name),\n });\n }\n\n return entries;\n}\n\ninterface ParsedKey {\n name: string;\n version: string;\n}\n\nexport function parsePackageKey(rawKey: string): ParsedKey | null {\n let k = rawKey.trim();\n if (k.length === 0) {\n return null;\n }\n\n if (\n (k.startsWith(\"'\") && k.endsWith(\"'\")) ||\n (k.startsWith('\"') && k.endsWith('\"'))\n ) {\n k = k.slice(1, -1);\n }\n\n if (k.startsWith('/')) {\n k = k.slice(1);\n }\n\n // Strip peer-dependency suffix used by v6+: `pkg@1.0.0(peer@1.0.0)(other@2)`.\n const parenIdx = k.indexOf('(');\n if (parenIdx >= 0) {\n k = k.slice(0, parenIdx);\n }\n\n // Split off the optional `@scope/` prefix so the remaining \"body\" contains\n // exactly one separator between the bare name and the version. npm forbids\n // both `@` and `/` inside the bare-name portion, so the first occurrence of\n // either character in the body is unambiguously the name/version separator.\n let scopePrefix = '';\n let body = k;\n if (k.startsWith('@')) {\n const firstSlash = k.indexOf('/');\n if (firstSlash <= 0) {\n return null;\n }\n scopePrefix = k.slice(0, firstSlash + 1);\n body = k.slice(firstSlash + 1);\n }\n\n const slashIdx = body.indexOf('/');\n const atIdx = body.indexOf('@');\n\n let sepIdx: number;\n if (slashIdx < 0 && atIdx < 0) {\n return null;\n } else if (slashIdx < 0) {\n sepIdx = atIdx;\n } else if (atIdx < 0) {\n sepIdx = slashIdx;\n } else {\n sepIdx = Math.min(slashIdx, atIdx);\n }\n\n const name = scopePrefix + body.slice(0, sepIdx);\n let version = body.slice(sepIdx + 1);\n\n // v5 peer suffix uses `_`: `1.0.0_react@18.2.0`.\n const underscoreIdx = version.indexOf('_');\n if (underscoreIdx >= 0) {\n version = version.slice(0, underscoreIdx);\n }\n\n if (name.length === 0 || version.length === 0) {\n return null;\n }\n\n return { name, version };\n}\n\nfunction indentOf(line: string): number {\n let i = 0;\n while (i < line.length && line[i] === ' ') {\n i++;\n }\n return i;\n}\n\nfunction isBlankOrComment(line: string): boolean {\n const trimmed = line.trim();\n return trimmed.length === 0 || trimmed.startsWith('#');\n}\n\n/**\n * Collects keys directly nested under the top-level `packages:` block. Stops\n * when another top-level key (e.g. `snapshots:`) appears.\n */\nfunction collectPackagesBlockKeys(lines: string[]): string[] {\n const keys: string[] = [];\n let inBlock = false;\n let childIndent: number | null = null;\n\n for (const line of lines) {\n if (isBlankOrComment(line)) {\n continue;\n }\n\n const indent = indentOf(line);\n\n if (!inBlock) {\n if (indent === 0 && line.trim() === 'packages:') {\n inBlock = true;\n }\n continue;\n }\n\n if (indent === 0) {\n break;\n }\n\n if (childIndent === null) {\n childIndent = indent;\n }\n\n if (indent !== childIndent) {\n continue;\n }\n\n const content = line.slice(indent);\n if (!content.endsWith(':')) {\n continue;\n }\n\n keys.push(content.slice(0, -1));\n }\n\n return keys;\n}\n\n/**\n * Collects direct dependency names. Looks in two places, since the format\n * differs across lockfile versions and workspaces:\n *\n * 1. `importers:` > `<importer>:` > `{dependencies,devDependencies,optionalDependencies}:`\n * (v9 always, v6-v8 in workspaces)\n * 2. Top-level `{dependencies,devDependencies,optionalDependencies}:`\n * (v6-v8 single-project lockfiles)\n *\n * Direct-dep marking is best-effort: a name absent from both is simply left as\n * not-direct, matching the npm parser's behaviour for transitive packages.\n */\nfunction collectDirectDepNames(lines: string[]): Set<string> {\n const names = new Set<string>();\n collectFromImporters(lines, names);\n for (const section of ['dependencies', 'devDependencies', 'optionalDependencies']) {\n collectFromTopLevelSection(lines, section, names);\n }\n return names;\n}\n\nconst DEP_SECTIONS = new Set([\n 'dependencies',\n 'devDependencies',\n 'optionalDependencies',\n]);\n\nfunction collectFromImporters(lines: string[], out: Set<string>): void {\n let inImporters = false;\n let importerIndent: number | null = null;\n let inDepSection = false;\n let depSectionIndent: number | null = null;\n let leafIndent: number | null = null;\n\n for (const line of lines) {\n if (isBlankOrComment(line)) {\n continue;\n }\n const indent = indentOf(line);\n const trimmed = line.trim();\n\n if (!inImporters) {\n if (indent === 0 && trimmed === 'importers:') {\n inImporters = true;\n }\n continue;\n }\n\n if (indent === 0) {\n break;\n }\n\n // Track the indent at which importer entries (e.g. `.:`, `packages/foo:`) sit.\n if (importerIndent === null) {\n importerIndent = indent;\n }\n\n if (indent === importerIndent) {\n inDepSection = false;\n depSectionIndent = null;\n leafIndent = null;\n continue;\n }\n\n if (!inDepSection) {\n const key = stripTrailingColon(trimmed);\n if (key !== null && DEP_SECTIONS.has(key)) {\n inDepSection = true;\n depSectionIndent = indent;\n }\n continue;\n }\n\n if (depSectionIndent !== null && indent <= depSectionIndent) {\n // Reset — we've exited the dep section. Reconsider this line.\n inDepSection = false;\n depSectionIndent = null;\n leafIndent = null;\n const key = stripTrailingColon(trimmed);\n if (key !== null && DEP_SECTIONS.has(key)) {\n inDepSection = true;\n depSectionIndent = indent;\n }\n continue;\n }\n\n if (leafIndent === null) {\n leafIndent = indent;\n }\n\n if (indent !== leafIndent) {\n continue;\n }\n\n const name = extractLeafName(trimmed);\n if (name !== null) {\n out.add(name);\n }\n }\n}\n\nfunction collectFromTopLevelSection(\n lines: string[],\n section: string,\n out: Set<string>,\n): void {\n let inSection = false;\n let leafIndent: number | null = null;\n\n for (const line of lines) {\n if (isBlankOrComment(line)) {\n continue;\n }\n const indent = indentOf(line);\n const trimmed = line.trim();\n\n if (!inSection) {\n if (indent === 0 && trimmed === `${section}:`) {\n inSection = true;\n }\n continue;\n }\n\n if (indent === 0) {\n break;\n }\n\n if (leafIndent === null) {\n leafIndent = indent;\n }\n\n if (indent !== leafIndent) {\n continue;\n }\n\n const name = extractLeafName(trimmed);\n if (name !== null) {\n out.add(name);\n }\n }\n}\n\nfunction stripTrailingColon(s: string): string | null {\n if (!s.endsWith(':')) {\n return null;\n }\n return s.slice(0, -1).trim();\n}\n\n/**\n * Extracts the package name from a dependency-section leaf, handling both the\n * short form (`pkg: 1.0.0`) and the v9 expanded form (`pkg:` followed by\n * `specifier:` / `version:` children). Quoted scoped names like `'@scope/pkg':`\n * are unquoted.\n */\nfunction extractLeafName(trimmed: string): string | null {\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx < 0) {\n return null;\n }\n let name = trimmed.slice(0, colonIdx).trim();\n if (name.length === 0) {\n return null;\n }\n if (\n (name.startsWith(\"'\") && name.endsWith(\"'\")) ||\n (name.startsWith('\"') && name.endsWith('\"'))\n ) {\n name = name.slice(1, -1);\n }\n return name.length > 0 ? name : null;\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type PackageEntry } from '../types.js';\n\n/**\n * Parses yarn.lock (yarn classic v1 and yarn berry v2+) without a YAML\n * dependency. Both generations share the same block structure — a top-level\n * mapping of comma-separated descriptor lists to a block containing a\n * `version` field — so we walk them with the same scanner and only branch on\n * the `version` syntax (`version \"x\"` for v1, `version: x` for berry).\n *\n * Direct vs transitive can't be derived from yarn.lock alone (yarn does not\n * record an importer manifest the way pnpm v9 does), so we cross-reference\n * the sibling `package.json` when present.\n */\nexport async function parseYarnLockfile(lockfilePath: string): Promise<PackageEntry[]> {\n let raw: string;\n try {\n raw = await readFile(lockfilePath, 'utf8');\n } catch (cause) {\n throw new PatchstackError(\n `Could not read lockfile at ${lockfilePath}`,\n 'LOCKFILE_NOT_FOUND',\n cause,\n );\n }\n\n const blocks = parseBlocks(raw);\n if (blocks.length === 0) {\n throw new PatchstackError(\n `Lockfile at ${lockfilePath} contains no package entries`,\n 'LOCKFILE_PARSE_ERROR',\n );\n }\n\n const directNames = await readDirectDepNames(path.dirname(lockfilePath));\n\n const entries: PackageEntry[] = [];\n const seen = new Set<string>();\n for (const block of blocks) {\n if (block.version.length === 0 || block.names.size === 0) {\n continue;\n }\n for (const name of block.names) {\n const dedupKey = `${name}@${block.version}`;\n if (seen.has(dedupKey)) {\n continue;\n }\n seen.add(dedupKey);\n entries.push({\n name,\n version: block.version,\n direct: directNames.has(name),\n });\n }\n }\n\n return entries;\n}\n\ninterface Block {\n names: Set<string>;\n version: string;\n}\n\nfunction parseBlocks(raw: string): Block[] {\n const lines = raw.split(/\\r?\\n/);\n const blocks: Block[] = [];\n let current: Block | null = null;\n\n const finalize = () => {\n if (current !== null && current.version.length > 0 && current.names.size > 0) {\n blocks.push(current);\n }\n current = null;\n };\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.length === 0 || trimmed.startsWith('#')) {\n continue;\n }\n\n const indent = countLeadingSpaces(line);\n\n if (indent === 0) {\n finalize();\n if (!trimmed.endsWith(':')) {\n continue;\n }\n // `__metadata:` (yarn berry header) has no `@` in any descriptor and\n // produces an empty names set, so it's naturally skipped on finalize.\n const keyLine = trimmed.slice(0, -1);\n const names = new Set<string>();\n for (const spec of splitDescriptors(keyLine)) {\n const name = extractName(spec);\n if (name !== null) {\n names.add(name);\n }\n }\n current = { names, version: '' };\n continue;\n }\n\n if (current === null) {\n continue;\n }\n\n const version = parseVersionField(trimmed);\n if (version !== null) {\n current.version = version;\n }\n }\n\n finalize();\n return blocks;\n}\n\nfunction countLeadingSpaces(line: string): number {\n let i = 0;\n while (i < line.length && line[i] === ' ') {\n i++;\n }\n return i;\n}\n\n/**\n * Splits a yarn descriptor key list on top-level commas. yarn quotes any\n * descriptor that contains characters needing escaping, so we respect quotes\n * while splitting to avoid breaking on commas inside (rare in practice but\n * cheap to handle).\n */\nexport function splitDescriptors(keyLine: string): string[] {\n const parts: string[] = [];\n let current = '';\n let quote: '\"' | \"'\" | null = null;\n\n for (let i = 0; i < keyLine.length; i++) {\n const c = keyLine[i];\n if (quote !== null) {\n current += c;\n if (c === quote) {\n quote = null;\n }\n continue;\n }\n if (c === '\"' || c === \"'\") {\n quote = c;\n current += c;\n continue;\n }\n if (c === ',') {\n const piece = current.trim();\n if (piece.length > 0) {\n parts.push(piece);\n }\n current = '';\n continue;\n }\n current += c;\n }\n const tail = current.trim();\n if (tail.length > 0) {\n parts.push(tail);\n }\n return parts;\n}\n\n/**\n * Extracts the package name from a yarn descriptor like `axios@^1.6.0`,\n * `\"@scope/pkg@^2.1.0\"`, or `\"@scope/pkg@npm:2.1.0\"`. The descriptor's\n * range portion is discarded — we only need the name, since the resolved\n * version comes from the `version` field of the block.\n */\nexport function extractName(rawSpec: string): string | null {\n let s = rawSpec.trim();\n if (s.length === 0) {\n return null;\n }\n if (\n (s.startsWith('\"') && s.endsWith('\"')) ||\n (s.startsWith(\"'\") && s.endsWith(\"'\"))\n ) {\n s = s.slice(1, -1);\n }\n // Position-0 `@` belongs to a scope, so we want the last `@` after it.\n const atIdx = s.lastIndexOf('@');\n if (atIdx <= 0) {\n return null;\n }\n const name = s.slice(0, atIdx);\n return name.length > 0 ? name : null;\n}\n\nfunction parseVersionField(content: string): string | null {\n if (!content.startsWith('version')) {\n return null;\n }\n const after = content.slice('version'.length);\n // yarn v1: `version \"1.2.3\"` (whitespace then quoted)\n // yarn berry: `version: 1.2.3` or `version: \"1.2.3\"`\n const firstChar = after.charAt(0);\n if (firstChar !== ' ' && firstChar !== '\\t' && firstChar !== ':') {\n return null;\n }\n let rest = firstChar === ':' ? after.slice(1) : after;\n rest = rest.trim();\n if (rest.length === 0) {\n return null;\n }\n if (\n (rest.startsWith('\"') && rest.endsWith('\"')) ||\n (rest.startsWith(\"'\") && rest.endsWith(\"'\"))\n ) {\n rest = rest.slice(1, -1);\n }\n return rest.length > 0 ? rest : null;\n}\n\nasync function readDirectDepNames(cwd: string): Promise<Set<string>> {\n const names = new Set<string>();\n let raw: string;\n try {\n raw = await readFile(path.join(cwd, 'package.json'), 'utf8');\n } catch {\n return names;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return names;\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n return names;\n }\n const obj = parsed as Record<string, unknown>;\n\n for (const field of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) {\n const section = obj[field];\n if (typeof section !== 'object' || section === null) {\n continue;\n }\n for (const name of Object.keys(section)) {\n names.add(name);\n }\n }\n\n return names;\n}\n","import type { Manifest, PackageEntry } from './types.js';\n\nexport interface WirePackage {\n name: string;\n version: string;\n}\n\nexport interface WirePayload {\n ecosystem: Manifest['ecosystem'];\n packages: WirePackage[];\n}\n\nexport interface NormalizeStats {\n uniqueNames: number;\n duplicateNames: string[];\n totalEntries: number;\n}\n\nexport interface NormalizeResult {\n payload: WirePayload;\n stats: NormalizeStats;\n}\n\nexport function buildWirePayload(manifest: Manifest): NormalizeResult {\n const seen = new Map<string, Set<string>>();\n const wirePackages: WirePackage[] = [];\n\n for (const entry of manifest.packages) {\n const versions = seen.get(entry.name);\n if (versions) {\n if (versions.has(entry.version)) {\n continue;\n }\n versions.add(entry.version);\n } else {\n seen.set(entry.name, new Set([entry.version]));\n }\n wirePackages.push({ name: entry.name, version: entry.version });\n }\n\n wirePackages.sort((a, b) => {\n if (a.name === b.name) {\n return compareVersions(a.version, b.version);\n }\n return a.name < b.name ? -1 : 1;\n });\n\n const duplicateNames: string[] = [];\n for (const [name, versions] of seen) {\n if (versions.size > 1) {\n duplicateNames.push(name);\n }\n }\n\n return {\n payload: { ecosystem: manifest.ecosystem, packages: wirePackages },\n stats: {\n uniqueNames: seen.size,\n duplicateNames,\n totalEntries: manifest.packages.length,\n },\n };\n}\n\nexport function compareVersions(a: string, b: string): number {\n if (a === b) {\n return 0;\n }\n\n const [aBase, aPre] = splitPrerelease(a);\n const [bBase, bPre] = splitPrerelease(b);\n\n const baseCmp = compareSegments(aBase.split('.'), bBase.split('.'));\n if (baseCmp !== 0) {\n return baseCmp;\n }\n\n if (aPre === null && bPre === null) {\n return 0;\n }\n if (aPre === null) {\n return 1;\n }\n if (bPre === null) {\n return -1;\n }\n return compareSegments(aPre.split('.'), bPre.split('.'));\n}\n\nfunction splitPrerelease(version: string): [string, string | null] {\n const cleaned = version.replace(/^[v=]+/, '').split('+')[0]!;\n const dashIndex = cleaned.indexOf('-');\n if (dashIndex === -1) {\n return [cleaned, null];\n }\n return [cleaned.slice(0, dashIndex), cleaned.slice(dashIndex + 1)];\n}\n\nfunction compareSegments(a: string[], b: string[]): number {\n const max = Math.max(a.length, b.length);\n for (let i = 0; i < max; i++) {\n const aPart = a[i];\n const bPart = b[i];\n if (aPart === undefined) {\n return -1;\n }\n if (bPart === undefined) {\n return 1;\n }\n const aNum = /^\\d+$/.test(aPart);\n const bNum = /^\\d+$/.test(bPart);\n if (aNum && bNum) {\n const diff = Number(aPart) - Number(bPart);\n if (diff !== 0) {\n return diff < 0 ? -1 : 1;\n }\n continue;\n }\n if (aNum) {\n return -1;\n }\n if (bNum) {\n return 1;\n }\n if (aPart < bPart) {\n return -1;\n }\n if (aPart > bPart) {\n return 1;\n }\n }\n return 0;\n}\n\nexport function findPackageInManifest(\n manifest: Manifest,\n name: string,\n): PackageEntry[] {\n return manifest.packages.filter((p) => p.name === name);\n}\n","import { createHash } from 'node:crypto';\n\nimport type { WirePackage } from './normalize.js';\n\n/**\n * Fingerprint of a manifest's package set, byte-for-byte identical to the\n * checksum Patchstack stores server-side (PulseController::storeManifest): the\n * first 12 hex chars of sha256 over the JSON of the packages sorted by\n * `[name, version]` with plain lexicographic (byte) ordering.\n *\n * This mirrors PHP's `usort(..., fn($a,$b) => [$a['name'],$a['version']] <=> ...)`\n * followed by `json_encode(..., JSON_UNESCAPED_SLASHES)`. Two deliberate details:\n *\n * - The sort is lexicographic, NOT the semver-aware ordering `buildWirePayload`\n * uses for display. The server re-sorts lexicographically before hashing, so\n * the fingerprint must too (e.g. `1.10.0` sorts before `1.9.0`).\n * - npm/composer package names and versions are ASCII, so JS `JSON.stringify`\n * and PHP `json_encode` produce identical bytes (no unicode escaping, and\n * neither escapes `/`, so scoped names like `@babel/core` match).\n *\n * Injected into built HTML by `mark-build` and reported by the disclosure widget\n * so Patchstack can compare the live build against the last reported manifest.\n */\nexport function computeManifestChecksum(packages: WirePackage[]): string {\n const canonical = packages\n .map((pkg) => ({ name: pkg.name, version: pkg.version }))\n .sort((a, b) => {\n if (a.name !== b.name) {\n return a.name < b.name ? -1 : 1;\n }\n if (a.version !== b.version) {\n return a.version < b.version ? -1 : 1;\n }\n return 0;\n });\n\n return createHash('sha256').update(JSON.stringify(canonical)).digest('hex').slice(0, 12);\n}\n","import type { Config } from './types.js';\n\n/**\n * Bearer tokens for the authenticated Pulse endpoints (ADR-0018).\n *\n * Deliberately separate from the block-log token flow in\n * `src/protect/firewall-log.js`: that path talks to the auth/ Lambda's\n * /oauth/token and must keep working exactly as it does today.\n */\n\nconst TOKEN_SKEW_MS = 60_000;\n\n/** Build the Pulse token URL corresponding to a manifest endpoint override. */\nexport function buildTokenUrl(manifestEndpoint: string): string {\n const url = new URL(manifestEndpoint);\n const path = url.pathname.replace(/\\/$/, '');\n url.pathname = path.endsWith('/manifest')\n ? `${path.slice(0, -'/manifest'.length)}/token`\n : '/monitor/pulse/token';\n url.search = '';\n url.hash = '';\n return url.toString();\n}\n\n/** Split the WP-format `{secret}-{oauth.id}` credential on its last hyphen. */\nexport function parsePulseAuth(credential: string): { clientId: string; clientSecret: string } | null {\n const index = credential.lastIndexOf('-');\n if (index <= 0 || index === credential.length - 1) return null;\n\n const clientId = credential.slice(index + 1);\n if (!/^\\d+$/.test(clientId)) return null;\n\n return { clientId, clientSecret: credential.slice(0, index) };\n}\n\nlet cached: { token: string; expiresAt: number } | null = null;\nlet inflight: Promise<string | null> | null = null;\n\n/** Drops the cached token. Exported for tests and for 401 handling. */\nexport function clearPulseToken(): void {\n cached = null;\n}\n\n/**\n * Resolve a bearer token for `config.pulseAuth`, exchanging one if needed.\n *\n * Returns null whenever a token cannot be obtained — no credential, a rejected\n * exchange, a network failure. Callers then send the request unauthenticated,\n * which the server still accepts while it runs dual-accept.\n */\nexport async function getPulseToken(\n config: Config,\n fetchImpl: typeof fetch = fetch,\n): Promise<string | null> {\n // Not `=== null`: Config is public, so callers can hand us an object that\n // predates this field, and an unusable credential must never throw here.\n if (typeof config.pulseAuth !== 'string' || config.pulseAuth.length === 0) return null;\n\n if (cached !== null && Date.now() < cached.expiresAt - TOKEN_SKEW_MS) {\n return cached.token;\n }\n if (inflight !== null) return inflight;\n\n const credentials = parsePulseAuth(config.pulseAuth);\n if (credentials === null) return null;\n\n inflight = (async () => {\n try {\n const response = await fetchImpl(buildTokenUrl(config.endpoint), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'User-Agent': '@patchstack/connect',\n },\n body: JSON.stringify({\n grant_type: 'client_credentials',\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n }),\n signal: AbortSignal.timeout(config.timeoutMs),\n });\n\n if (!response.ok) return null;\n\n const body = (await response.json()) as { access_token?: unknown; expires_in?: unknown };\n if (typeof body.access_token !== 'string' || body.access_token.length === 0) return null;\n\n const expiresIn = Number(body.expires_in);\n const ttlMs = Number.isFinite(expiresIn) && expiresIn > 0 ? expiresIn * 1000 : 3600_000;\n cached = { token: body.access_token, expiresAt: Date.now() + ttlMs };\n\n return body.access_token;\n } catch {\n return null;\n } finally {\n inflight = null;\n }\n })();\n\n return inflight;\n}\n\n/**\n * `Authorization` header for a Pulse request, or `{}` when unauthenticated.\n * Spread into an existing header object so call sites stay one line.\n */\nexport async function pulseAuthHeader(\n config: Config,\n fetchImpl: typeof fetch = fetch,\n): Promise<Record<string, string>> {\n const token = await getPulseToken(config, fetchImpl);\n return token === null ? {} : { Authorization: `Bearer ${token}` };\n}\n\n/**\n * Send a Pulse request, attaching the bearer token and retrying once if the\n * server rejects it.\n *\n * A cached token can stop being valid before it expires — the credential may\n * have been rotated or revoked meanwhile — so the server's 401 is authoritative\n * over our own clock. Without this a long-running process would keep presenting\n * a dead token until its local expiry.\n *\n * Only 401 retries: a 403 is a scope or site mismatch, which a fresh token\n * would not fix.\n */\nexport async function pulseFetch(\n config: Config,\n url: string,\n init: RequestInit,\n fetchImpl: typeof fetch = fetch,\n): Promise<Response> {\n const send = async () => {\n const auth = await pulseAuthHeader(config, fetchImpl);\n const response = await fetchImpl(url, {\n ...init,\n headers: { ...(init.headers as Record<string, string> | undefined), ...auth },\n });\n\n return { response, authenticated: auth.Authorization !== undefined };\n };\n\n const first = await send();\n\n // Retrying an unauthenticated request would just repeat it: the 401 was\n // about something other than our token.\n if (first.response.status === 401 && first.authenticated) {\n clearPulseToken();\n\n return (await send()).response;\n }\n\n return first.response;\n}\n","import { PatchstackError, type Config, type StoreManifestResponse } from './types.js';\nimport type { WirePayload } from './normalize.js';\nimport { pulseFetch } from './pulse-token.js';\n\nexport const DEFAULT_ENDPOINT = 'https://api.patchstack.com/monitor/pulse/manifest';\nexport const DEFAULT_TIMEOUT_MS = 30_000;\n\nexport function buildEndpointUrl(base: string, siteUuid?: string | null): string {\n const trimmed = base.replace(/\\/$/, '');\n return siteUuid !== undefined && siteUuid !== null && siteUuid.length > 0\n ? `${trimmed}/${encodeURIComponent(siteUuid)}`\n : trimmed;\n}\n\n/**\n * What a refusal means, in terms someone can act on.\n *\n * Every Pulse route that addresses an existing site requires a credential, so a rejection is now the\n * most likely failure a misconfigured project hits — and the three causes have three different fixes.\n * Reporting them as `Patchstack returned 401` names none of them, and this output is frequently read by\n * an AI agent that has no other way to find out what to do next.\n *\n * The distinction 401 cannot make on its own is whether we HELD a credential. Having none is a setup\n * step that was never run; having one rejected is a credential that has expired, been revoked, or whose\n * site no longer exists. A 403 is different again: the credential is valid and simply is not for this\n * site, which usually means a `.patchstackrc.json` carrying someone else's UUID.\n *\n * @returns the message, or null when the status is not an authentication failure\n */\nexport function authFailureMessage(status: number, config: Config): string | null {\n const hasCredential = typeof config.pulseAuth === 'string' && config.pulseAuth.length > 0;\n\n if (status === 401 && !hasCredential) {\n return 'Patchstack requires an API credential for this site and none is configured. Run `npx patchstack-connect login`, or set PATCHSTACK_API_KEY.';\n }\n if (status === 401) {\n return 'Patchstack rejected this API credential. It may have expired, been revoked, or the site may no longer exist. Run `npx patchstack-connect login` to issue a new one.';\n }\n if (status === 403) {\n return 'This API credential is not permitted to act on this site. Check that siteUuid in .patchstackrc.json matches the credential (a credential is issued for one site).';\n }\n\n return null;\n}\n\n/** Build the live Pulse rules URL corresponding to a manifest endpoint override. */\nexport function buildRulesUrl(manifestEndpoint: string, siteUuid: string): string {\n const url = new URL(manifestEndpoint);\n const path = url.pathname.replace(/\\/$/, '');\n url.pathname = path.endsWith('/manifest')\n ? `${path.slice(0, -'/manifest'.length)}/rules/${encodeURIComponent(siteUuid)}`\n : `/monitor/pulse/rules/${encodeURIComponent(siteUuid)}`;\n url.search = '';\n url.hash = '';\n return url.toString();\n}\n\n/**\n * Build the claim URL for a site. The claim page lives on the same origin as\n * the API endpoint, at `/monitor/claim?site=<uuid>`. Using the API endpoint's\n * origin (rather than a hard-coded https://api.patchstack.com) means staging,\n * ngrok tunnels and local dev environments all produce a claim URL on the same\n * host the connector is already talking to.\n */\nexport function buildClaimUrl(endpoint: string, siteUuid: string): string {\n const origin = new URL(endpoint).origin;\n return `${origin}/monitor/claim?site=${encodeURIComponent(siteUuid)}`;\n}\n\n/**\n * Build the public widget-settings URL for a site. Like the claim URL, it\n * lives on the API endpoint's origin, at `/monitor/widget/settings/<uuid>`.\n */\nexport function buildSettingsUrl(endpoint: string, siteUuid: string): string {\n const origin = new URL(endpoint).origin;\n return `${origin}/monitor/widget/settings/${encodeURIComponent(siteUuid)}`;\n}\n\n/** Build the package-removed signal URL corresponding to a manifest endpoint override. */\nexport function buildPackageRemovedUrl(manifestEndpoint: string, siteUuid: string): string {\n const url = new URL(manifestEndpoint);\n const path = url.pathname.replace(/\\/$/, '');\n url.pathname = path.endsWith('/manifest')\n ? `${path.slice(0, -'/manifest'.length)}/package-removed/${encodeURIComponent(siteUuid)}`\n : `/monitor/pulse/package-removed/${encodeURIComponent(siteUuid)}`;\n url.search = '';\n url.hash = '';\n return url.toString();\n}\n\n/** Build the input-map ingest URL corresponding to a manifest endpoint override. */\nexport function buildInputMapUrl(manifestEndpoint: string, siteUuid: string): string {\n const url = new URL(manifestEndpoint);\n const path = url.pathname.replace(/\\/$/, '');\n url.pathname = path.endsWith('/manifest')\n ? `${path.slice(0, -'/manifest'.length)}/input-map/${encodeURIComponent(siteUuid)}`\n : `/monitor/pulse/input-map/${encodeURIComponent(siteUuid)}`;\n url.search = '';\n url.hash = '';\n return url.toString();\n}\n\n/**\n * Outcome of uploading an attack-surface map. `unchanged` is a first-class result, not a failure: most\n * builds do not change the surface, and the server keeps one revision per distinct surface rather than\n * one per deploy. `skipped` covers the cases where there is nothing to send or nowhere to send it.\n */\nexport type InputMapUploadOutcome =\n | { result: 'stored'; revision: number }\n | { result: 'unchanged'; revision: number }\n | { result: 'skipped'; message: string }\n | { result: 'failed'; message: string };\n\n/**\n * Upload an attack-surface map for this site.\n *\n * Fail-open by construction: every failure path returns a result rather than throwing, because this runs\n * during someone's build and a Patchstack outage must never break it. The caller decides what to print.\n */\nexport async function postInputMap(\n config: Config,\n map: { version: number; endpoints: unknown[] },\n): Promise<InputMapUploadOutcome> {\n if (config.siteUuid === null) {\n return { result: 'skipped', message: 'No site UUID configured — run `patchstack-connect scan` first.' };\n }\n\n const url = buildInputMapUrl(config.endpoint, config.siteUuid);\n try {\n const response = await pulseFetch(config, url, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'User-Agent': '@patchstack/connect',\n },\n body: JSON.stringify(map),\n signal: AbortSignal.timeout(config.timeoutMs),\n });\n if (response.status === 404) {\n return { result: 'failed', message: 'Site not found — the configured site UUID is unknown to Patchstack.' };\n }\n if (response.status === 422) {\n // The server implements a different map schema than this client emits. Say so plainly: it means\n // one side is out of date, and guessing at compatibility is how a consumer misreads a document.\n return { result: 'failed', message: `Patchstack does not accept this map schema (version ${map.version}). Update @patchstack/connect.` };\n }\n const refused = authFailureMessage(response.status, config);\n if (refused !== null) {\n return { result: 'failed', message: refused };\n }\n if (!response.ok) {\n return { result: 'failed', message: `Patchstack returned ${response.status}.` };\n }\n const body = (await response.json()) as { result?: string; revision?: number };\n // The revision is part of the contract, not decoration: \"stored, revision 0\" is not a state the server\n // can be in, so accepting it would report a successful upload that cannot be pointed at afterwards.\n const revision = Number(body.revision);\n if ((body.result === 'stored' || body.result === 'unchanged') && Number.isInteger(revision) && revision > 0) {\n return { result: body.result, revision };\n }\n return { result: 'failed', message: 'Patchstack returned an unexpected response.' };\n } catch {\n return { result: 'failed', message: `Could not reach Patchstack at ${url}.` };\n }\n}\n\n/**\n * Outcome of the package-removed signal. 'deleted' — the site was unclaimed\n * and its record was removed; 'flagged' — the site is claimed, so it was only\n * marked for its owner to confirm removal in the dashboard; 'gone' — the\n * record no longer existed; 'failed' — Patchstack could not be reached or\n * returned an unexpected response.\n */\nexport interface PackageRemovedOutcome {\n result: 'deleted' | 'flagged' | 'gone' | 'failed';\n message: string | null;\n}\n\n/**\n * Tell Patchstack the @patchstack/connect package is being uninstalled from\n * this project. The site UUID is the only credential, so the server deletes\n * only unclaimed (anonymous) sites; claimed sites are merely flagged for\n * their owner. Never throws — an unreachable server must not block the local\n * uninstall.\n */\nexport async function postPackageRemoved(config: Config): Promise<PackageRemovedOutcome> {\n if (config.siteUuid === null) {\n return { result: 'failed', message: 'No site UUID configured.' };\n }\n\n const url = buildPackageRemovedUrl(config.endpoint, config.siteUuid);\n try {\n const response = await pulseFetch(config, url, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'User-Agent': '@patchstack/connect',\n },\n signal: AbortSignal.timeout(config.timeoutMs),\n });\n if (response.status === 404) {\n return { result: 'gone', message: null };\n }\n // A site that has been deleted answers 401 here, not 404: this route resolves the site FROM the\n // credential, so once the site record is gone the credential resolves to nothing. Reporting that as\n // an auth failure would tell someone to re-run `login` over a site that no longer exists, so the\n // question is put to the endpoint that can still answer it — widget settings, which needs no\n // credential and 404s for a removed site.\n if (response.status === 401 && (await fetchSiteStatus(config)) === 'removed') {\n return { result: 'gone', message: null };\n }\n const refused = authFailureMessage(response.status, config);\n if (refused !== null) {\n return { result: 'failed', message: refused };\n }\n if (!response.ok) {\n return { result: 'failed', message: `Patchstack returned ${response.status}.` };\n }\n const body = (await response.json()) as { status?: string; message?: string };\n if (body.status === 'deleted' || body.status === 'flagged') {\n return { result: body.status, message: body.message ?? null };\n }\n return { result: 'failed', message: 'Patchstack returned an unexpected response.' };\n } catch {\n return { result: 'failed', message: `Could not reach Patchstack at ${url}.` };\n }\n}\n\n/**\n * Whether the site record still exists on Patchstack's side. Removing a site\n * (dashboard delete or the widget's uninstall flow) only deletes the remote\n * record — the local integration files stay in the project — so this is the\n * signal that distinguishes \"removed from Patchstack\" from \"still active\".\n */\nexport type SiteStatus = 'active' | 'removed' | 'unknown';\n\n/**\n * Check the remote site status via the public widget-settings endpoint:\n * 200 means the site record exists, 404 means it was removed. Any other\n * response or a network failure is 'unknown' — never throws. The endpoint's\n * 200 responses are cacheable for an hour, so a cache-busting query param\n * keeps intermediaries from reporting a just-removed site as active.\n */\nexport async function fetchSiteStatus(config: Config): Promise<SiteStatus> {\n if (config.siteUuid === null) return 'unknown';\n\n const url = new URL(buildSettingsUrl(config.endpoint, config.siteUuid));\n url.searchParams.set('t', Date.now().toString());\n\n try {\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'Cache-Control': 'no-cache',\n 'User-Agent': '@patchstack/connect',\n },\n signal: AbortSignal.timeout(config.timeoutMs),\n });\n if (response.status === 404) return 'removed';\n if (response.ok) return 'active';\n return 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nexport async function postManifest(\n config: Config,\n payload: WirePayload,\n): Promise<StoreManifestResponse> {\n const url = buildEndpointUrl(config.endpoint, config.siteUuid);\n const timeoutMs = config.timeoutMs;\n\n let response: Response;\n try {\n // Unauthenticated on the bootstrap POST: there is no credential until this\n // request issues one.\n response = await pulseFetch(config, url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'User-Agent': '@patchstack/connect',\n },\n body: JSON.stringify({ ...payload, environment: config.environment }),\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (cause) {\n if (isTimeoutError(cause)) {\n throw new PatchstackError(\n `Patchstack request to ${url} timed out after ${timeoutMs}ms. Override with PATCHSTACK_TIMEOUT_MS.`,\n 'NETWORK_TIMEOUT',\n cause,\n );\n }\n throw new PatchstackError(\n `Could not reach Patchstack at ${url}. Check your network connection.`,\n 'NETWORK_ERROR',\n cause,\n );\n }\n\n const text = await response.text();\n let body: StoreManifestResponse | null = null;\n try {\n body = text.length > 0 ? (JSON.parse(text) as StoreManifestResponse) : null;\n } catch {\n body = null;\n }\n\n if (response.status === 404) {\n throw new PatchstackError(\n body?.error ?? 'Site not found. Check that your site UUID is correct and that the app is registered as a Pulse app in your Patchstack dashboard.',\n 'SITE_NOT_FOUND',\n );\n }\n\n if (response.status === 422) {\n throw new PatchstackError(\n body?.message ?? 'Patchstack rejected the manifest payload (validation failed).',\n 'VALIDATION_ERROR',\n );\n }\n\n const refused = authFailureMessage(response.status, config);\n if (refused !== null) {\n throw new PatchstackError(refused, 'UNAUTHORIZED');\n }\n\n if (response.status < 200 || response.status >= 300) {\n throw new PatchstackError(\n `Patchstack returned ${response.status}: ${text.slice(0, 200)}`,\n 'SERVER_ERROR',\n );\n }\n\n if (body === null) {\n throw new PatchstackError('Patchstack returned an empty response.', 'SERVER_ERROR');\n }\n\n return body;\n}\n\nfunction isTimeoutError(cause: unknown): boolean {\n if (cause instanceof Error) {\n return cause.name === 'TimeoutError' || cause.name === 'AbortError';\n }\n return false;\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { scanLockfile } from './parsers/index.js';\nimport { buildRulesUrl } from './client.js';\nimport type { PackageManager } from './guide.js';\n\nexport interface DemoScenario {\n name: string;\n packageName: string;\n packageVersion: string;\n ruleId: number;\n maliciousBody: Record<string, string>;\n benignBody: Record<string, string>;\n}\n\nexport interface PulseRule {\n id?: string | number;\n title?: string;\n rule_v2?: unknown[];\n}\n\nexport const NODE_SERIALIZE_DEMO: DemoScenario = {\n name: 'node-serialize',\n packageName: 'node-serialize',\n packageVersion: '0.0.4',\n ruleId: 18843,\n maliciousBody: {\n text: \"_$$ND_FUNC$$_function(){require('child_process').exec('id')}()\",\n },\n benignBody: { text: 'buy milk' },\n};\n\nconst SCENARIOS = new Map([[NODE_SERIALIZE_DEMO.name, NODE_SERIALIZE_DEMO]]);\n\nexport class DemoError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DemoError';\n }\n}\n\nexport interface DemoDependencyState {\n ready: boolean;\n versions: string[];\n}\n\nexport interface DemoGuideState {\n scenario: DemoScenario;\n packageManager: PackageManager;\n siteUuid: string | null;\n dependency: DemoDependencyState;\n environment: 'production' | 'sandbox';\n url: string;\n}\n\nconst DEMO_INSTALL_COMMANDS: Record<PackageManager, string> = {\n npm: 'npm install --save-exact node-serialize@0.0.4',\n pnpm: 'pnpm add --save-exact node-serialize@0.0.4',\n yarn: 'yarn add --exact node-serialize@0.0.4',\n bun: 'bun add --exact node-serialize@0.0.4',\n};\n\nconst DEMO_REMOVE_COMMANDS: Record<PackageManager, string> = {\n npm: 'npm uninstall node-serialize',\n pnpm: 'pnpm remove node-serialize',\n yarn: 'yarn remove node-serialize',\n bun: 'bun remove node-serialize',\n};\n\nexport function resolveDemoScenario(name: string | undefined): DemoScenario {\n if (!name) {\n throw new DemoError(\n 'A demo scenario is required. Available scenario: node-serialize.\\n' +\n 'Usage: patchstack-connect demo node-serialize',\n );\n }\n const scenario = SCENARIOS.get(name);\n if (!scenario) {\n throw new DemoError(`Unknown demo scenario \"${name}\". Available scenario: node-serialize.`);\n }\n return scenario;\n}\n\nasync function collectDemoDependency(\n cwd: string,\n scenario: DemoScenario,\n): Promise<DemoDependencyState> {\n const manifest = await scanLockfile(cwd);\n const versions = [\n ...new Set(\n manifest.packages\n .filter((entry) => entry.name === scenario.packageName)\n .map((entry) => entry.version),\n ),\n ].sort();\n return { ready: versions.includes(scenario.packageVersion), versions };\n}\n\nexport async function inspectDemoDependency(\n cwd: string,\n scenario: DemoScenario,\n): Promise<DemoDependencyState> {\n try {\n return await collectDemoDependency(cwd, scenario);\n } catch {\n return { ready: false, versions: [] };\n }\n}\n\nexport async function assertDemoDependency(cwd: string, scenario: DemoScenario): Promise<void> {\n const { ready, versions } = await collectDemoDependency(cwd, scenario);\n if (ready) return;\n\n const found = versions.length > 0 ? ` Found: ${versions.join(', ')}.` : '';\n throw new DemoError(\n `${scenario.packageName}@${scenario.packageVersion} is not installed in the lockfile.${found}\\n` +\n `Add this deliberately vulnerable package first: npm install --save-exact ${scenario.packageName}@${scenario.packageVersion}`,\n );\n}\n\nexport async function readPersistedSiteUuid(cwd: string): Promise<string | null> {\n try {\n const value = JSON.parse(await readFile(join(cwd, '.patchstackrc.json'), 'utf8')).siteUuid;\n return typeof value === 'string' && value.length > 0 ? value : null;\n } catch {\n return null;\n }\n}\n\nexport async function assertPersistedSiteUuid(cwd: string, expectedUuid: string): Promise<void> {\n const persisted = await readPersistedSiteUuid(cwd);\n if (persisted === null) {\n throw new DemoError(\n 'The demo requires the Host-connected .patchstackrc.json. Connect Patchstack in Bolt first, then try again.',\n );\n }\n if (persisted !== expectedUuid) {\n throw new DemoError(\n `The active site UUID (${expectedUuid}) does not match .patchstackrc.json (${String(persisted)}). ` +\n 'Remove the UUID override or reconnect this Bolt project before running the demo.',\n );\n }\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nexport function renderDemoGuide(state: DemoGuideState): string {\n const { scenario } = state;\n const install = DEMO_INSTALL_COMMANDS[state.packageManager].replace(\n 'node-serialize@0.0.4',\n `${scenario.packageName}@${scenario.packageVersion}`,\n );\n const remove = DEMO_REMOVE_COMMANDS[state.packageManager].replace(\n 'node-serialize',\n scenario.packageName,\n );\n const demo =\n state.url === 'http://localhost:3000/api/tasks'\n ? `npx @patchstack/connect demo ${scenario.name}`\n : `npx @patchstack/connect demo ${scenario.name} --url ${shellQuote(state.url)}`;\n const siteReady = state.siteUuid !== null;\n const envReady = state.environment === 'production';\n const dependencyDetail = state.dependency.ready\n ? `${scenario.packageName}@${scenario.packageVersion} is in the lockfile`\n : state.dependency.versions.length > 0\n ? `found ${scenario.packageName}@${state.dependency.versions.join(', ')}; ${scenario.packageVersion} is required`\n : `${scenario.packageName}@${scenario.packageVersion} is not in the lockfile`;\n\n let next: string;\n if (!siteReady) {\n next = 'Click “Connect Patchstack” in Bolt, then run this guide again.';\n } else if (!envReady) {\n next = 'Unset PATCHSTACK_ENVIRONMENT (or set it to production), then run this guide again.';\n } else if (!state.dependency.ready) {\n next = install;\n } else {\n next = demo;\n }\n\n return [\n `Patchstack demo guide — ${scenario.name}`,\n '',\n 'Goal: prove that a live Patchstack virtual patch blocks the vulnerable payload while normal traffic still succeeds.',\n 'Deployment required: no. Keep the app running locally; the connector and generated guard contact Patchstack’s production API.',\n '',\n `1. ${siteReady ? '✓' : '○'} Connect this project from Bolt’s Host account dropdown`,\n siteReady\n ? ` Ready — .patchstackrc.json contains site ${state.siteUuid}.`\n : ' Click “Connect Patchstack” in Bolt. This creates .patchstackrc.json; no separate CLI login is needed.',\n '',\n `2. ${state.dependency.ready ? '✓' : '○'} Add the deliberately vulnerable demo dependency`,\n ` ${dependencyDetail}.`,\n ` ${install}`,\n ' Do not import or execute this package; its lockfile entry is enough for detection.',\n '',\n '3. ○ Run the production-backed demo setup',\n ` ${demo}`,\n ...(envReady\n ? []\n : [' Blocked for now: this walkthrough needs PATCHSTACK_ENVIRONMENT=production.']),\n ` This scans the npm manifest, waits for live rule ${scenario.ruleId}, installs the server guard, verifies its wiring, and prints two test requests.`,\n ' It does not start the server or send the requests.',\n '',\n '4. ○ Restart the local dev server',\n ' Restart after the demo command so the application loads the generated guard.',\n '',\n '5. ○ Run both requests printed by the demo command',\n ` Exploit: expect HTTP 403 with Patchstack rule ${scenario.ruleId}.`,\n ' Control (“buy milk”): expect HTTP 201. This proves normal traffic is not blocked.',\n '',\n '6. ○ Clean up the throwaway vulnerability after the demonstration',\n ` ${remove}`,\n ' Re-run `npx @patchstack/connect scan` so the clean manifest is reported.',\n '',\n `Next: ${next}`,\n ].join('\\n');\n}\n\ninterface WaitForRuleOptions {\n timeoutMs?: number;\n pollIntervalMs?: number;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n sleep?: (ms: number) => Promise<void>;\n now?: () => number;\n}\n\nexport async function waitForDemoRule(\n manifestEndpoint: string,\n siteUuid: string,\n scenario: DemoScenario,\n options: WaitForRuleOptions = {},\n): Promise<PulseRule> {\n const timeoutMs = options.timeoutMs ?? 30_000;\n const pollIntervalMs = options.pollIntervalMs ?? 1_000;\n const requestTimeoutMs = options.requestTimeoutMs ?? 10_000;\n const fetchFn = options.fetchFn ?? fetch;\n const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));\n const now = options.now ?? Date.now;\n const started = now();\n const rulesUrl = buildRulesUrl(manifestEndpoint, siteUuid);\n let lastDetail = 'the rule list was empty';\n\n do {\n try {\n const response = await fetchFn(rulesUrl, {\n headers: { Accept: 'application/json', 'User-Agent': '@patchstack/connect' },\n signal: AbortSignal.timeout(requestTimeoutMs),\n });\n if (response.ok) {\n const data = (await response.json()) as { firewall?: PulseRule[] };\n const rules = Array.isArray(data.firewall) ? data.firewall : [];\n const matched = rules.find((rule) => String(rule.id) === String(scenario.ruleId));\n if (matched) return matched;\n lastDetail = `${rules.length} firewall rule(s) returned without rule ${scenario.ruleId}`;\n } else {\n lastDetail = `the rules API returned HTTP ${response.status}`;\n }\n } catch (error) {\n lastDetail = `the rules request failed: ${(error as Error).message}`;\n }\n\n const remaining = timeoutMs - (now() - started);\n if (remaining <= 0) break;\n await sleep(Math.min(pollIntervalMs, remaining));\n } while (now() - started <= timeoutMs);\n\n throw new DemoError(\n `Timed out waiting for Patchstack rule ${scenario.ruleId} for site ${siteUuid}; ${lastDetail}.`,\n );\n}\n\nexport function renderDemoTestCommands(url: string, scenario: DemoScenario): string {\n const shellUrl = shellQuote(url);\n const command = (body: Record<string, string>) => {\n const encoded = Buffer.from(JSON.stringify(body)).toString('base64');\n return `node -e \"process.stdout.write(Buffer.from('${encoded}','base64'))\" | curl -i -X POST --url ${shellUrl} -H \"Content-Type: application/json\" --data-binary @-`;\n };\n return [\n 'Restart the dev server so it loads the generated guard, then run:',\n '',\n `Blocked exploit (expect HTTP 403 and rule ${scenario.ruleId}):`,\n command(scenario.maliciousBody),\n '',\n 'Benign request (expect HTTP 201):',\n command(scenario.benignBody),\n ].join('\\n');\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type Config, type Environment } from './types.js';\nimport { DEFAULT_ENDPOINT, DEFAULT_TIMEOUT_MS } from './client.js';\n\nconst CONFIG_FILENAME = '.patchstackrc.json';\n\nexport const DEFAULT_ENVIRONMENT: Environment = 'production';\n\ninterface ConfigFile {\n siteUuid?: string;\n /** WP-format `{secret}-{oauth.id}` for connector /api/logs/log. Server-only. */\n apiKey?: string;\n /**\n * Credential for the authenticated Pulse endpoints (ADR-0018). Same format as\n * `apiKey` and today the same value, but kept as its own field so the Pulse\n * and block-log paths can diverge without disturbing each other. Server-only.\n */\n pulseAuth?: string;\n endpoint?: string;\n timeoutMs?: number;\n environment?: string;\n widget?: boolean;\n}\n\nexport interface ResolveConfigOptions {\n cwd: string;\n cliSiteUuid?: string;\n cliEndpoint?: string;\n /**\n * When true, resolveConfig throws CONFIG_MISSING if no site UUID is configured.\n * Defaults to false: callers that can run without a UUID (the first `scan` after\n * `npm install`) just get `siteUuid: null` back and learn the UUID from the\n * server response.\n */\n requireSiteUuid?: boolean;\n}\n\nexport async function resolveConfig(options: ResolveConfigOptions): Promise<Config> {\n const fromFile = await readConfigFile(options.cwd);\n const fromEnv = readEnv();\n\n const siteUuid =\n options.cliSiteUuid ??\n fromEnv.siteUuid ??\n fromFile.siteUuid ??\n null;\n\n const endpoint =\n options.cliEndpoint ??\n fromEnv.endpoint ??\n fromFile.endpoint ??\n DEFAULT_ENDPOINT;\n\n const timeoutMs = fromEnv.timeoutMs ?? fromFile.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n const environmentRaw = fromEnv.environment ?? fromFile.environment;\n if (environmentRaw !== undefined && !isEnvironment(environmentRaw)) {\n throw new PatchstackError(\n `Environment must be \"production\" or \"sandbox\"; got \"${environmentRaw}\".`,\n 'CONFIG_INVALID',\n );\n }\n const environment: Environment = environmentRaw ?? DEFAULT_ENVIRONMENT;\n\n if (siteUuid !== null && siteUuid.length > 0 && !isUuid(siteUuid)) {\n throw new PatchstackError(\n `Site UUID \"${siteUuid}\" does not look like a valid UUID.`,\n 'CONFIG_INVALID',\n );\n }\n\n if (options.requireSiteUuid && (siteUuid === null || siteUuid.length === 0)) {\n throw new PatchstackError(\n 'No site UUID configured. Run `patchstack-connect scan` to provision one, or set PATCHSTACK_SITE_UUID.',\n 'CONFIG_MISSING',\n );\n }\n\n const apiKeyRaw = fromEnv.apiKey ?? fromFile.apiKey ?? null;\n // Falls back to apiKey so sites provisioned before ADR-0018 authenticate\n // without re-provisioning: today both hold the same credential.\n const pulseAuthRaw = fromEnv.pulseAuth ?? fromFile.pulseAuth ?? apiKeyRaw;\n\n return {\n siteUuid: siteUuid === null || siteUuid.length === 0 ? null : siteUuid,\n apiKey: apiKeyRaw === null || apiKeyRaw.length === 0 ? null : apiKeyRaw,\n pulseAuth: pulseAuthRaw === null || pulseAuthRaw.length === 0 ? null : pulseAuthRaw,\n endpoint,\n timeoutMs,\n environment,\n widget: fromFile.widget !== false,\n };\n}\n\nexport async function writeConfigFile(cwd: string, config: ConfigFile): Promise<string> {\n const target = path.join(cwd, CONFIG_FILENAME);\n const content = JSON.stringify(config, null, 2) + '\\n';\n await writeFile(target, content, 'utf8');\n return target;\n}\n\n/**\n * Merge a new siteUuid into the existing `.patchstackrc.json` (or create it).\n * Preserves any `endpoint` / `timeoutMs` / `apiKey` the user already wrote.\n */\nexport async function persistSiteUuid(cwd: string, siteUuid: string): Promise<string> {\n const existing = await readConfigFile(cwd);\n return writeConfigFile(cwd, { ...existing, siteUuid });\n}\n\n/**\n * Persist the WP-format api_key issued at provision. Authenticates both the\n * Pulse endpoints and connector log reporting. Never embed it in the public\n * disclosure widget.\n *\n * Drops any `pulseAuth` written by an earlier version. That field resolves\n * ahead of `apiKey`, so leaving a copy behind after the credential changes\n * would leave Pulse authenticating with the value the server just replaced.\n */\nexport async function persistApiKey(cwd: string, apiKey: string): Promise<string> {\n const { pulseAuth: _dropped, ...existing } = await readConfigFile(cwd);\n return writeConfigFile(cwd, { ...existing, apiKey });\n}\n\n/**\n * Persist a Pulse-specific credential.\n *\n * Only needed when Pulse ingest and block-log reporting must use *different*\n * credentials; they share one today, so `persistApiKey` covers both. Retained\n * for callers that separate them.\n */\nexport async function persistPulseAuth(cwd: string, pulseAuth: string): Promise<string> {\n const existing = await readConfigFile(cwd);\n return writeConfigFile(cwd, { ...existing, pulseAuth });\n}\n\nasync function readConfigFile(cwd: string): Promise<ConfigFile> {\n const target = path.join(cwd, CONFIG_FILENAME);\n let raw: string;\n try {\n raw = await readFile(target, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return {};\n }\n throw new PatchstackError(\n `Could not read ${target}: ${(err as Error).message}`,\n 'CONFIG_INVALID',\n err,\n );\n }\n\n try {\n return JSON.parse(raw) as ConfigFile;\n } catch (err) {\n throw new PatchstackError(\n `Config file ${target} contains invalid JSON.`,\n 'CONFIG_INVALID',\n err,\n );\n }\n}\n\nfunction readEnv(): ConfigFile {\n const timeoutRaw = process.env.PATCHSTACK_TIMEOUT_MS;\n let timeoutMs: number | undefined;\n if (timeoutRaw !== undefined && timeoutRaw.length > 0) {\n const parsed = Number(timeoutRaw);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new PatchstackError(\n `PATCHSTACK_TIMEOUT_MS must be a positive number; got \"${timeoutRaw}\".`,\n 'CONFIG_INVALID',\n );\n }\n timeoutMs = parsed;\n }\n const environmentRaw = process.env.PATCHSTACK_ENVIRONMENT;\n return {\n siteUuid: process.env.PATCHSTACK_SITE_UUID ?? undefined,\n apiKey: process.env.PATCHSTACK_API_KEY ?? undefined,\n pulseAuth: process.env.PATCHSTACK_PULSE_AUTH ?? undefined,\n endpoint: process.env.PATCHSTACK_ENDPOINT ?? undefined,\n timeoutMs,\n environment:\n environmentRaw !== undefined && environmentRaw.length > 0 ? environmentRaw : undefined,\n };\n}\n\nfunction isUuid(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);\n}\n\nfunction isEnvironment(value: string): value is Environment {\n return value === 'production' || value === 'sandbox';\n}\n","import { existsSync, readdirSync, statSync } from 'node:fs';\nimport path from 'node:path';\n\nimport { isEmptyStack, type StackDescriptor } from './stack.js';\n\n/** Attribute that tags our injected <script> so re-runs replace it instead of stacking. */\nexport const MARKER_ATTR = 'data-patchstack-build';\n\n/** Build output directories we look for, in priority order (Vite, CRA, Next export, Nuxt). */\nexport const BUILD_DIR_CANDIDATES = ['dist', 'build', 'out', '.output/public'];\n\n/**\n * Resolve the directory holding the built HTML. Honours an explicit `--dir`\n * override, otherwise picks the first known build directory that exists.\n * Returns null when nothing is found (mark-build then no-ops without failing).\n */\nexport function resolveBuildDir(cwd: string, override?: string): string | null {\n if (override !== undefined && override !== '') {\n const abs = path.resolve(cwd, override);\n return existsSync(abs) && statSync(abs).isDirectory() ? abs : null;\n }\n\n for (const candidate of BUILD_DIR_CANDIDATES) {\n const abs = path.resolve(cwd, candidate);\n if (existsSync(abs) && statSync(abs).isDirectory()) {\n return abs;\n }\n }\n\n return null;\n}\n\n/** Recursively collect every `.html` file under `dir`. */\nexport function findHtmlFiles(dir: string): string[] {\n const out: string[] = [];\n\n const walk = (current: string): void => {\n for (const entry of readdirSync(current, { withFileTypes: true })) {\n const full = path.join(current, entry.name);\n if (entry.isDirectory()) {\n walk(full);\n } else if (entry.isFile() && entry.name.toLowerCase().endsWith('.html')) {\n out.push(full);\n }\n }\n };\n\n walk(dir);\n return out;\n}\n\n/**\n * The <script> we inject into built HTML. Always marks the build as production\n * (so the widget hides the connect/claim prompt on the published site) and, when\n * available, exposes the build fingerprint (for the parity heartbeat) and the\n * detected stack descriptor (so the widget can report how the site was built).\n */\nexport function buildInjectionSnippet(\n checksum: string | null,\n stack?: StackDescriptor | null,\n): string {\n const statements = ['window.__PATCHSTACK_PROD__=true;'];\n if (checksum !== null && checksum !== '') {\n statements.push(`window.__PATCHSTACK_BUILD__=${JSON.stringify(checksum)};`);\n }\n if (stack != null && !isEmptyStack(stack)) {\n statements.push(`window.__PATCHSTACK_STACK__=${JSON.stringify(stack)};`);\n }\n return `<script ${MARKER_ATTR}>${statements.join('')}</script>`;\n}\n\n/**\n * Insert (or replace) the marker script in a single HTML document. Idempotent:\n * a prior marker is stripped first so repeated builds don't stack tags. Prefers\n * `</head>`, falls back to `</body>`, then appends.\n */\nexport function injectMarker(html: string, snippet: string): string {\n const stripped = html.replace(\n new RegExp(`\\\\s*<script ${MARKER_ATTR}[^>]*>[\\\\s\\\\S]*?</script>`, 'gi'),\n '',\n );\n\n if (/<\\/head>/i.test(stripped)) {\n return stripped.replace(/<\\/head>/i, `${snippet}</head>`);\n }\n if (/<\\/body>/i.test(stripped)) {\n return stripped.replace(/<\\/body>/i, `${snippet}</body>`);\n }\n return stripped + snippet;\n}\n","import type { WirePackage } from './normalize.js';\n\n/**\n * A best-effort description of the stack a build was produced with, derived\n * entirely from the lockfile (ground truth) plus the build-time environment.\n *\n * The disclosure widget reads this from `window.__PATCHSTACK_STACK__` (injected\n * by `mark-build`) and reports it to Patchstack, so we learn how the sites we\n * protect are actually built and hosted — across every \"vibe\" platform — without\n * shipping a runtime probe onto the host server. Every field is a coarse label\n * or a bare key *name*: no versions beyond the framework, and never an env value.\n */\nexport interface StackDescriptor {\n /** App / meta-framework, e.g. \"next\", \"nuxt\", \"tanstack-start\", \"remix\". */\n framework: string | null;\n /** UI runtime, e.g. \"react\", \"vue\", \"svelte\", \"solid\". */\n ui: string | null;\n /** Build tool / bundler, e.g. \"vite\", \"webpack\", \"rspack\". */\n bundler: string | null;\n /** Deployment-runtime hint from deps, e.g. \"cloudflare-workers\", \"vercel\". */\n runtime: string | null;\n /** The vibe/builder platform that generated the project, e.g. \"lovable\". */\n builder: string | null;\n /** Package ecosystem the manifest came from. */\n ecosystem: 'npm';\n /** Hosting-related build-environment variable NAMES (never their values). */\n hostingEnvKeys: string[];\n}\n\ntype Category = 'framework' | 'ui' | 'bundler' | 'runtime' | 'builder';\n\ninterface StackRule {\n category: Category;\n /** Exact package name that signals this label. */\n pkg: string;\n label: string;\n}\n\n/**\n * Package → stack-label registry. First match per category wins, so order\n * within a category is priority order (most specific first). Add a row to teach\n * the connector a new framework, bundler, or vibe platform.\n */\nconst STACK_RULES: readonly StackRule[] = [\n // Meta-frameworks (most specific first).\n { category: 'framework', pkg: '@tanstack/react-start', label: 'tanstack-start' },\n { category: 'framework', pkg: '@tanstack/start', label: 'tanstack-start' },\n { category: 'framework', pkg: 'next', label: 'next' },\n { category: 'framework', pkg: 'nuxt', label: 'nuxt' },\n { category: 'framework', pkg: '@remix-run/react', label: 'remix' },\n { category: 'framework', pkg: '@remix-run/node', label: 'remix' },\n { category: 'framework', pkg: 'react-router', label: 'react-router' },\n { category: 'framework', pkg: 'astro', label: 'astro' },\n { category: 'framework', pkg: '@sveltejs/kit', label: 'sveltekit' },\n { category: 'framework', pkg: '@builder.io/qwik-city', label: 'qwik-city' },\n { category: 'framework', pkg: 'gatsby', label: 'gatsby' },\n { category: 'framework', pkg: 'express', label: 'express' },\n { category: 'framework', pkg: 'fastify', label: 'fastify' },\n\n // UI runtimes.\n { category: 'ui', pkg: '@angular/core', label: 'angular' },\n { category: 'ui', pkg: 'react-dom', label: 'react' },\n { category: 'ui', pkg: 'react', label: 'react' },\n { category: 'ui', pkg: 'vue', label: 'vue' },\n { category: 'ui', pkg: 'svelte', label: 'svelte' },\n { category: 'ui', pkg: 'solid-js', label: 'solid' },\n { category: 'ui', pkg: 'preact', label: 'preact' },\n\n // Bundlers / build tools.\n { category: 'bundler', pkg: 'vite', label: 'vite' },\n { category: 'bundler', pkg: '@rspack/core', label: 'rspack' },\n { category: 'bundler', pkg: 'webpack', label: 'webpack' },\n { category: 'bundler', pkg: 'parcel', label: 'parcel' },\n { category: 'bundler', pkg: 'rollup', label: 'rollup' },\n { category: 'bundler', pkg: 'esbuild', label: 'esbuild' },\n\n // Deployment-runtime hints from build deps.\n { category: 'runtime', pkg: 'wrangler', label: 'cloudflare-workers' },\n { category: 'runtime', pkg: '@cloudflare/workers-types', label: 'cloudflare-workers' },\n { category: 'runtime', pkg: '@cloudflare/vite-plugin', label: 'cloudflare-workers' },\n { category: 'runtime', pkg: '@vercel/node', label: 'vercel' },\n { category: 'runtime', pkg: '@netlify/functions', label: 'netlify' },\n { category: 'runtime', pkg: '@netlify/blobs', label: 'netlify' },\n\n // Vibe / builder platforms — the \"learn from each platform\" signal.\n { category: 'builder', pkg: 'lovable-tagger', label: 'lovable' },\n { category: 'builder', pkg: '@replit/vite-plugin-runtime-error-modal', label: 'replit' },\n { category: 'builder', pkg: '@replit/vite-plugin-cartographer', label: 'replit' },\n];\n\n/** Build-environment variable-name patterns that fingerprint a host, from server-insight. */\nconst HOSTING_ENV_PATTERNS: readonly RegExp[] = [\n /^CF_/,\n /^CLOUDFLARE_/,\n /^VERCEL/,\n /^NETLIFY/,\n /^AWS_(LAMBDA|REGION|EXECUTION)/,\n /^FLY_/,\n /^RENDER/,\n /^RAILWAY_/,\n /^DENO_/,\n /^EDGE_RUNTIME/,\n /^DYNO$/,\n /^K_SERVICE$/,\n /^GAE_/,\n /^FUNCTION_/,\n];\n\n/**\n * Return the sorted NAMES of hosting-related environment variables present in\n * `env`. Only names are surfaced — never values — so a build fingerprint can\n * distinguish \"deployed on Cloudflare\" from \"deployed on Vercel\" without ever\n * disclosing a secret.\n */\nexport function collectHostingEnvKeys(env: NodeJS.ProcessEnv = process.env): string[] {\n return Object.keys(env)\n .filter((key) => HOSTING_ENV_PATTERNS.some((pattern) => pattern.test(key)))\n .sort();\n}\n\n/**\n * Derive a {@link StackDescriptor} from the wire packages and the build\n * environment. Never throws: an unrecognised stack just yields nulls.\n */\nexport function detectStack(\n packages: readonly WirePackage[],\n env: NodeJS.ProcessEnv = process.env,\n): StackDescriptor {\n const present = new Set(packages.map((pkg) => pkg.name));\n\n const firstMatch = (category: Category): string | null => {\n for (const rule of STACK_RULES) {\n if (rule.category === category && present.has(rule.pkg)) {\n return rule.label;\n }\n }\n return null;\n };\n\n return {\n framework: firstMatch('framework'),\n ui: firstMatch('ui'),\n bundler: firstMatch('bundler'),\n runtime: firstMatch('runtime'),\n builder: firstMatch('builder'),\n ecosystem: 'npm',\n hostingEnvKeys: collectHostingEnvKeys(env),\n };\n}\n\n/** True when the descriptor carries no useful signal (nothing worth injecting). */\nexport function isEmptyStack(stack: StackDescriptor): boolean {\n return (\n stack.framework === null &&\n stack.ui === null &&\n stack.bundler === null &&\n stack.runtime === null &&\n stack.builder === null &&\n stack.hostingEnvKeys.length === 0\n );\n}\n","// `patchstack-connect guide` — a state-aware setup checklist.\n//\n// Instead of only printing the generic AGENT-INSTALL.md, the guide first inspects\n// the current project (package.json, lockfile, .patchstackrc.json, source tree)\n// and renders a checklist of what is already done and what is still missing, with\n// the exact commands/snippets for THIS project (right package manager, real site\n// UUID, framework-specific widget placement). Every probe is best-effort: an\n// unreadable project degrades to an all-todo checklist, never a crash.\n\nimport { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport path from 'node:path';\n\nimport { DEFAULT_ENDPOINT, buildClaimUrl } from './client.js';\nimport { resolveConfig } from './config.js';\nimport { runVerify } from './protect/install/index.js';\nimport type { VerifyCheck } from './protect/install/types.js';\nimport { detectStack } from './stack.js';\nimport { buildWidgetTag } from './widget.js';\n\n/** Substring that marks the widget as installed anywhere in the source tree. */\nconst WIDGET_NEEDLE = 'patchstack-widget';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nexport interface GuideState {\n /** package.json `name`, when readable. */\n projectName: string | null;\n hasPackageJson: boolean;\n packageManager: PackageManager;\n /** Version + section when @patchstack/connect is declared, else null. */\n installed: { version: string; section: 'devDependencies' | 'dependencies' } | null;\n siteUuid: string | null;\n claimUrl: string | null;\n /** Non-default API endpoint in effect (rc file, env, or flag), else null. */\n endpointOverride: string | null;\n hasBuildScript: boolean;\n installScanWired: boolean;\n prebuildWired: boolean;\n postbuildWired: boolean;\n widgetInstalled: boolean;\n /** False when the widget is present but its site UUID isn't this project's. */\n widgetTokenMatches: boolean | null;\n /** True when .patchstackrc.json opts out of widget management (\"widget\": false). */\n widgetOptOut: boolean;\n /** Framework label from the declared dependencies (e.g. \"next\"), best-effort. */\n framework: string | null;\n /** Existing file the widget snippet belongs in, best-effort. */\n widgetFileHint: string | null;\n /** Result of the same local inspection used by `protect --check`. */\n protectionWired: boolean;\n protectionStack: string;\n protectionChecks: VerifyCheck[];\n}\n\nconst INSTALL_COMMANDS: Record<PackageManager, string> = {\n npm: 'npm install --save @patchstack/connect',\n pnpm: 'pnpm add @patchstack/connect',\n yarn: 'yarn add @patchstack/connect',\n bun: 'bun add @patchstack/connect',\n};\n\n/**\n * Lockfile → package manager for build-script semantics. Platform-native\n * lockfiles win over package-lock.json because agents often use npm as a\n * fallback inside Bun/pnpm/yarn projects, creating a secondary npm lockfile\n * without changing the platform's actual build runner.\n */\nconst PM_BY_LOCKFILE: ReadonlyArray<{ filename: string; pm: PackageManager }> = [\n { filename: 'bun.lock', pm: 'bun' },\n { filename: 'bun.lockb', pm: 'bun' },\n { filename: 'pnpm-lock.yaml', pm: 'pnpm' },\n { filename: 'yarn.lock', pm: 'yarn' },\n { filename: 'package-lock.json', pm: 'npm' },\n];\n\n/**\n * Framework → candidate layout files the widget snippet belongs in, most\n * specific first. The first candidate that exists in the project wins.\n */\nconst WIDGET_FILE_CANDIDATES: Record<string, string[]> = {\n next: [\n 'app/layout.tsx',\n 'app/layout.jsx',\n 'src/app/layout.tsx',\n 'src/app/layout.jsx',\n 'pages/_document.tsx',\n 'pages/_document.jsx',\n 'src/pages/_document.tsx',\n ],\n nuxt: ['app.vue', 'src/app.vue', 'app/app.vue'],\n remix: ['app/root.tsx', 'app/root.jsx'],\n 'react-router': ['app/root.tsx', 'src/root.tsx'],\n 'tanstack-start': ['src/routes/__root.tsx', 'app/routes/__root.tsx'],\n sveltekit: ['src/app.html'],\n astro: ['src/layouts/Layout.astro'],\n gatsby: ['src/html.js'],\n};\n\n/** Fallback candidates for plain Vite / CRA / static projects. */\nconst GENERIC_WIDGET_FILES = ['index.html', 'public/index.html'];\n\n/** Directories never worth searching for the widget snippet. */\nconst SKIPPED_DIRS = new Set([\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n 'out',\n '.output',\n '.next',\n '.nuxt',\n '.svelte-kit',\n '.vercel',\n '.netlify',\n 'coverage',\n 'vendor',\n]);\n\n/** Source extensions that can carry the widget <script> tags. */\nconst WIDGET_EXTENSIONS = new Set([\n '.html',\n '.htm',\n '.tsx',\n '.jsx',\n '.ts',\n '.js',\n '.mjs',\n '.cjs',\n '.vue',\n '.svelte',\n '.astro',\n '.ejs',\n '.hbs',\n]);\n\nconst WIDGET_SCAN_MAX_FILES = 4000;\nconst WIDGET_SCAN_MAX_DEPTH = 6;\nconst WIDGET_SCAN_MAX_BYTES = 512 * 1024;\n\ninterface PackageJson {\n name?: string;\n packageManager?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n}\n\nexport function detectPackageManager(cwd: string): PackageManager {\n const declared = readPackageJson(cwd)?.packageManager?.split('@')[0];\n if (declared === 'npm' || declared === 'pnpm' || declared === 'yarn' || declared === 'bun') {\n return declared;\n }\n for (const { filename, pm } of PM_BY_LOCKFILE) {\n if (existsSync(path.join(cwd, filename))) {\n return pm;\n }\n }\n return 'npm';\n}\n\nexport function installCommand(pm: PackageManager): string {\n return INSTALL_COMMANDS[pm];\n}\n\nfunction readPackageJson(cwd: string): PackageJson | null {\n try {\n return JSON.parse(readFileSync(path.join(cwd, 'package.json'), 'utf8')) as PackageJson;\n } catch {\n return null;\n }\n}\n\n/** Prefer the actually-installed version over the declared range. */\nfunction installedVersion(cwd: string, declaredRange: string): string {\n try {\n const pkg = JSON.parse(\n readFileSync(path.join(cwd, 'node_modules', '@patchstack', 'connect', 'package.json'), 'utf8'),\n ) as { version?: string };\n if (typeof pkg.version === 'string' && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // fall through to the declared range\n }\n return declaredRange;\n}\n\nexport interface WidgetScanResult {\n found: boolean;\n /**\n * When a site UUID is known: does any file carrying the widget also carry\n * that UUID as its userToken? null when the widget is absent or no UUID is\n * known yet. A stale/wrong userToken makes the widget silently no-op, so a\n * mismatch is worth surfacing rather than passing the check.\n */\n uuidMatches: boolean | null;\n}\n\n/**\n * Bounded recursive search for the widget marker in the source tree. Depth,\n * file-count and file-size capped so the guide stays instant on big projects.\n */\nexport function findWidgetMarker(cwd: string, siteUuid?: string | null): WidgetScanResult {\n let budget = WIDGET_SCAN_MAX_FILES;\n let sawWidget = false;\n let sawTokenMatch = false;\n\n // Stop early only once the answer can't improve: with no UUID to match, the\n // first hit settles it; with a UUID, keep looking until a matching file shows.\n const settled = (): boolean => sawTokenMatch || (sawWidget && siteUuid == null);\n\n const walk = (dir: string, depth: number): void => {\n if (depth > WIDGET_SCAN_MAX_DEPTH || budget <= 0) {\n return;\n }\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (budget <= 0 || settled()) {\n return;\n }\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (SKIPPED_DIRS.has(entry.name) || entry.name.startsWith('.')) {\n continue;\n }\n walk(full, depth + 1);\n continue;\n }\n if (!entry.isFile() || !WIDGET_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) {\n continue;\n }\n budget -= 1;\n try {\n if (statSync(full).size > WIDGET_SCAN_MAX_BYTES) {\n continue;\n }\n const content = readFileSync(full, 'utf8');\n if (!content.includes(WIDGET_NEEDLE)) {\n continue;\n }\n sawWidget = true;\n if (siteUuid != null && content.includes(siteUuid)) {\n sawTokenMatch = true;\n }\n } catch {\n // unreadable file — skip\n }\n }\n };\n\n walk(cwd, 0);\n return {\n found: sawWidget,\n uuidMatches: sawWidget && siteUuid != null ? sawTokenMatch : null,\n };\n}\n\nfunction resolveWidgetFileHint(cwd: string, framework: string | null): string | null {\n const candidates = [\n ...(framework !== null ? WIDGET_FILE_CANDIDATES[framework] ?? [] : []),\n ...GENERIC_WIDGET_FILES,\n ];\n for (const candidate of candidates) {\n if (existsSync(path.join(cwd, candidate))) {\n return candidate;\n }\n }\n return null;\n}\n\nexport async function collectGuideState(cwd: string): Promise<GuideState> {\n const pkg = readPackageJson(cwd);\n const packageManager = detectPackageManager(cwd);\n\n let installed: GuideState['installed'] = null;\n if (pkg?.devDependencies?.['@patchstack/connect'] !== undefined) {\n installed = {\n version: installedVersion(cwd, pkg.devDependencies['@patchstack/connect']),\n section: 'devDependencies',\n };\n } else if (pkg?.dependencies?.['@patchstack/connect'] !== undefined) {\n installed = {\n version: installedVersion(cwd, pkg.dependencies['@patchstack/connect']),\n section: 'dependencies',\n };\n }\n\n let siteUuid: string | null = null;\n let claimUrl: string | null = null;\n let endpointOverride: string | null = null;\n let widgetOptOut = false;\n try {\n const config = await resolveConfig({ cwd });\n siteUuid = config.siteUuid;\n if (siteUuid !== null) {\n claimUrl = buildClaimUrl(config.endpoint, siteUuid);\n }\n if (config.endpoint !== DEFAULT_ENDPOINT) {\n endpointOverride = config.endpoint;\n }\n widgetOptOut = !config.widget;\n } catch {\n // invalid config — the checklist just shows the site as not provisioned\n }\n\n // Framework detection needs only the declared top-level dependencies, so we\n // read package.json instead of the (much heavier) lockfile scan.\n const declaredNames = Object.keys({ ...pkg?.dependencies, ...pkg?.devDependencies });\n const stack = detectStack(\n declaredNames.map((name) => ({ name, version: '' })),\n {},\n );\n\n const widget = findWidgetMarker(cwd, siteUuid);\n const protection = runVerify(cwd);\n\n return {\n projectName: pkg?.name ?? null,\n hasPackageJson: pkg !== null,\n packageManager,\n installed,\n siteUuid,\n claimUrl,\n endpointOverride,\n hasBuildScript: Boolean(pkg?.scripts?.build?.trim()),\n installScanWired: (pkg?.scripts?.postinstall ?? '').includes('patchstack-connect scan'),\n // bun run doesn't execute npm-style pre/post scripts, so chaining inside\n // the build script itself also counts as wired (and is what we suggest on bun).\n prebuildWired:\n (pkg?.scripts?.prebuild ?? '').includes('patchstack-connect scan') ||\n (pkg?.scripts?.build ?? '').includes('patchstack-connect scan'),\n postbuildWired:\n (pkg?.scripts?.postbuild ?? '').includes('patchstack-connect mark-build') ||\n (pkg?.scripts?.build ?? '').includes('patchstack-connect mark-build'),\n widgetInstalled: widget.found,\n widgetTokenMatches: widget.uuidMatches,\n widgetOptOut,\n framework: stack.framework,\n widgetFileHint: resolveWidgetFileHint(cwd, stack.framework),\n protectionWired: protection.wired,\n protectionStack: protection.stack,\n protectionChecks: protection.checks,\n };\n}\n\nconst ANSI = {\n reset: '\\u001B[0m',\n bold: '\\u001B[1m',\n dim: '\\u001B[2m',\n green: '\\u001B[32m',\n yellow: '\\u001B[33m',\n cyan: '\\u001B[36m',\n};\n\n/** Setup steps still missing — 0 means the checklist is fully green. */\nexport function countRemainingSteps(state: GuideState): number {\n return [\n state.installed?.section === 'dependencies',\n state.siteUuid !== null,\n state.installScanWired,\n !state.hasBuildScript || (state.prebuildWired && state.postbuildWired),\n state.widgetOptOut || (state.widgetInstalled && state.widgetTokenMatches !== false),\n state.protectionWired,\n ].filter((step) => !step).length;\n}\n\nexport function renderGuideChecklist(state: GuideState, useColor: boolean): string {\n const paint = (code: string, text: string): string =>\n useColor ? `${code}${text}${ANSI.reset}` : text;\n const done = (text: string): string => ` ${paint(ANSI.green, '✔')} ${text}`;\n const todo = (text: string): string => ` ${paint(ANSI.yellow, '✖')} ${paint(ANSI.bold, text)}`;\n const detail = (text: string): string => ` ${paint(ANSI.dim, text)}`;\n const lines: string[] = [];\n\n const headerParts = [state.framework, state.packageManager].filter(\n (part): part is string => part !== null,\n );\n const name = state.projectName ?? path.basename(process.cwd());\n lines.push(paint(ANSI.bold, `Patchstack setup status — ${name} (${headerParts.join(' · ')})`));\n if (state.endpointOverride !== null) {\n lines.push(\n detail(\n `endpoint override in effect: ${state.endpointOverride} (set via .patchstackrc.json, PATCHSTACK_ENDPOINT, or --endpoint)`,\n ),\n );\n }\n lines.push('');\n\n if (!state.hasPackageJson) {\n lines.push(todo('No package.json found in this directory.'));\n lines.push(detail('Run the guide from the project root.'));\n return lines.join('\\n');\n }\n\n // 1. Install\n if (state.installed?.section === 'dependencies') {\n lines.push(done(`@patchstack/connect installed (${state.installed.version}, ${state.installed.section})`));\n } else if (state.installed !== null) {\n lines.push(todo(`Move @patchstack/connect to runtime dependencies (currently ${state.installed.section})`));\n lines.push(detail(`Run → ${installCommand(state.packageManager)}`));\n lines.push(detail('The generated guard imports @patchstack/connect/protect at runtime.'));\n } else {\n lines.push(todo('Install @patchstack/connect as a runtime dependency'));\n lines.push(detail(`Run → ${installCommand(state.packageManager)}`));\n if (state.packageManager === 'bun') {\n lines.push(detail(`(if bun isn't available here, ${INSTALL_COMMANDS.npm} works too)`));\n }\n }\n\n // 2. Provision (first scan)\n if (state.siteUuid !== null) {\n lines.push(done(`Site provisioned (${state.siteUuid})`));\n } else {\n lines.push(todo('Provision the site — run the first scan'));\n lines.push(detail('Run → npx @patchstack/connect scan'));\n lines.push(detail('Reads the lockfile, registers the project, writes .patchstackrc.json,'));\n lines.push(detail('and prints a dashboard link. The CLI prints the link but never opens it.'));\n }\n\n // 3. Dependency-change scan\n if (state.installScanWired) {\n lines.push(done('Dependency-install scan wired (postinstall)'));\n } else {\n lines.push(todo('Scan again whenever dependencies are installed'));\n lines.push(detail('Edit package.json → \"postinstall\": \"patchstack-connect scan\"'));\n }\n\n // 4. Build hooks\n if (!state.hasBuildScript) {\n lines.push(done('No build script to integrate (postinstall covers dependency changes)'));\n } else if (state.prebuildWired && state.postbuildWired) {\n lines.push(done('Build hooks wired (scan before builds, mark-build after)'));\n } else if (state.packageManager === 'bun') {\n // bun run skips npm-style pre/post scripts, so chain inside the build script.\n lines.push(todo('Wire the build hooks yourself — edit package.json (bun skips pre/post hooks, so chain inside \"build\")'));\n lines.push(detail('Edit package.json → \"build\": \"patchstack-connect scan && <existing build command> && patchstack-connect mark-build\"'));\n } else {\n lines.push(todo('Wire the build hooks yourself — edit package.json \"scripts\" (chain with && if a hook already exists)'));\n if (!state.prebuildWired) {\n lines.push(detail('Edit package.json → \"prebuild\": \"patchstack-connect scan\"'));\n }\n if (!state.postbuildWired) {\n lines.push(detail('Edit package.json → \"postbuild\": \"patchstack-connect mark-build\"'));\n }\n }\n\n // 5. Disclosure widget\n const widgetOk = state.widgetInstalled && state.widgetTokenMatches !== false;\n if (state.widgetOptOut && !widgetOk) {\n lines.push(done('Disclosure widget disabled by config (\"widget\": false in .patchstackrc.json)'));\n } else if (widgetOk) {\n lines.push(done('Disclosure widget installed'));\n } else if (state.widgetInstalled) {\n lines.push(todo(\"Fix the disclosure widget yourself — its site UUID doesn't match this project's\"));\n lines.push(detail(`Edit the widget tag → set data-site-uuid (or userToken) to '${state.siteUuid}' (a wrong UUID makes the widget silently no-op)`));\n } else if (state.siteUuid === null) {\n lines.push(todo('Add the \"Report a vulnerability\" widget — the first scan does this for you'));\n lines.push(detail('Run → npx @patchstack/connect scan (provisions the site and adds the widget tag'));\n lines.push(detail(' to the root HTML shell: index.html / public/index.html / src/app.html)'));\n } else {\n lines.push(todo('Add the \"Report a vulnerability\" widget yourself — this root is code, not a plain HTML shell'));\n lines.push(detail('Note → a normal `scan` adds this tag to a plain HTML shell automatically; add it by hand here:'));\n const placement =\n state.widgetFileHint !== null\n ? `Edit ${state.widgetFileHint} → put it just before </body>:`\n : \"Edit your root layout → put it just before </body> (the framework's HTML/layout mechanism, never a JS entry point):\";\n lines.push(detail(placement));\n lines.push(detail(` ${buildWidgetTag(state.siteUuid)}`));\n lines.push(detail('The site UUID is public by design — it ships in client-side HTML.'));\n }\n\n // 6. Runtime protection\n if (state.protectionWired) {\n lines.push(done(`Runtime protection wired (${state.protectionStack})`));\n } else {\n lines.push(todo(`Finish runtime protection (${state.protectionStack})`));\n for (const check of state.protectionChecks.filter((item) => !item.ok)) {\n lines.push(detail(`${check.label}${check.hint ? ` — ${check.hint}` : ''}`));\n }\n lines.push(detail('Verify → npx @patchstack/connect protect --check'));\n }\n\n // 7. Dashboard access — always keep the URL prominent.\n lines.push('');\n if (state.claimUrl !== null) {\n lines.push(` ${paint(ANSI.cyan, '➜')} ${paint(ANSI.bold, 'Dashboard link (open to view reports):')}`);\n lines.push(` ${paint(ANSI.cyan, state.claimUrl)}`);\n lines.push(detail('Open this link in a browser. The CLI never opens it.'));\n if (state.endpointOverride !== null) {\n lines.push(detail('(this URL inherits the endpoint override above)'));\n }\n } else {\n lines.push(detail('The dashboard link appears after the first scan (re-print any time with `status`).'));\n }\n\n const remaining = countRemainingSteps(state);\n lines.push('');\n if (remaining === 0) {\n lines.push(\n done(\n paint(\n ANSI.bold,\n 'All setup steps complete. Commit .patchstackrc.json, package.json, the runtime guard changes, and the file carrying the widget snippet.',\n ),\n ),\n );\n if (state.claimUrl !== null) {\n lines.push(detail('The only manual action left is opening the dashboard link above (if not already connected).'));\n }\n } else {\n lines.push(\n ` ${paint(ANSI.yellow, String(remaining))} step(s) remaining — details in the reference guide below.`,\n );\n }\n\n return lines.join('\\n');\n}\n","// Shared helpers for the `patchstack-connect protect` scaffolder (adapters + orchestrator).\n\nimport { readFileSync, existsSync, writeFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport const read = (p: string): string => readFileSync(p, 'utf8');\nexport const log = (msg: string): void => console.log(`patchstack protect: ${msg}`);\n\n/** True when `name` is in the project's dependencies or devDependencies. */\nexport function hasDependency(cwd: string, name: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }[name]);\n } catch {\n return false;\n }\n}\n\nconst SITE_UUID_PLACEHOLDER = '__PATCHSTACK_SITE_UUID__';\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * Bake the site UUID written by `scan` into a managed runtime-guard template.\n *\n * The UUID is public project configuration (the disclosure widget exposes the\n * same value). Keeping the environment-variable fallback in the template lets\n * unscanned projects remain inert and lets deployments override it explicitly.\n */\nexport function bakeSiteUuid(cwd: string, guardRelPath: string): boolean {\n const rc = join(cwd, '.patchstackrc.json');\n if (!existsSync(rc)) {\n log('no .patchstackrc.json — guard uses PATCHSTACK_SITE_UUID env or the bundled fallback');\n return false;\n }\n\n let uuid: unknown;\n try {\n uuid = JSON.parse(read(rc)).siteUuid;\n } catch {\n log('.patchstackrc.json unreadable — skipping site-UUID bake');\n return false;\n }\n\n if (typeof uuid !== 'string' || !UUID_RE.test(uuid)) {\n log('.patchstackrc.json siteUuid missing or malformed — guard uses PATCHSTACK_SITE_UUID env or the bundled fallback');\n return false;\n }\n\n const guardPath = join(cwd, guardRelPath);\n if (!existsSync(guardPath)) return false;\n const source = read(guardPath);\n if (!source.includes(SITE_UUID_PLACEHOLDER)) {\n log(`${guardRelPath} site UUID already baked`);\n return false;\n }\n\n writeFileSync(guardPath, source.replace(SITE_UUID_PLACEHOLDER, uuid));\n log(`baked site UUID into ${guardRelPath} — live rules from the Patchstack API`);\n return true;\n}\n\n// Guard templates ship next to the built CLI (dist/protect/templates). Resolve for the built\n// layout (this code is bundled into dist/cli.js at the dist root → protect/templates) and the\n// source layout (this file lives in src/protect/install/ → ../templates).\nconst HERE = dirname(fileURLToPath(import.meta.url));\nexport function templatesDir(): string {\n const builtLayout = join(HERE, 'protect', 'templates'); // built: dist/cli.js → dist/protect/templates\n const candidates = [\n builtLayout,\n join(HERE, '..', 'templates'), // source: src/protect/install/ → src/protect/templates\n join(HERE, 'templates'),\n ];\n return candidates.find((p) => existsSync(p)) ?? builtLayout;\n}\n","// Adapter: TanStack Start + Supabase (the shape Lovable emits).\n//\n// Wires the always-on guard with zero changes to the user's own code — patches the generated\n// Supabase client (browser→Supabase tunnel) and src/start.ts (request + function middleware),\n// scaffolds src/integrations/patchstack/{guard.ts,rules.json}, and bakes the site UUID.\n// Idempotent + upgrades in place via the managed `#region` blocks.\n\nimport { writeFileSync, existsSync, mkdirSync, copyFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { bakeSiteUuid, read, log, templatesDir } from '../util.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nconst CLIENT_TUNNEL = [\n '',\n \" // PATCHSTACK: in the browser, tunnel Supabase traffic through the app's own server guard\",\n ' // (same-origin) so payloads are inspected before they reach Supabase.',\n \" if (typeof window !== 'undefined') {\",\n \" const target = typeof input === 'string' ? input : input instanceof Request ? input.url : String(input);\",\n \" const method = init?.method ?? (input instanceof Request ? input.method : 'GET');\",\n \" headers.set('x-ps-target', target);\",\n \" const guardUrl = new URL('/_patchstack/guard', window.location.origin).toString();\",\n ' return fetch(guardUrl, { ...init, method, headers });',\n ' }',\n '',\n].join('\\n');\n\nconst GUARD_IMPORT =\n 'import { GUARD_PATH, handleGuardRequest, inspectServerFn, screenResponse, guardRequest } from \"@/integrations/patchstack/guard\";';\nconst GUARD_IMPORT_RE = /import \\{[^}]*\\} from \"@\\/integrations\\/patchstack\\/guard\";/;\n\nconst START_IMPORTS = ['import { getRequest } from \"@tanstack/react-start/server\";', GUARD_IMPORT].join('\\n');\n\n// Managed middleware blocks, delimited by #region markers so a re-run can UPGRADE them in place\n// (e.g. adding the route-WAF hook to an already-wired app) instead of skipping. Keep the markers —\n// reconcileBlock() keys off them.\nconst REQUEST_MIDDLEWARE_BLOCK = [\n '// #region patchstack-guard (managed by patchstack-connect protect — do not edit)',\n '// Browser→Supabase tunnel + response screening; optional route WAF via PATCHSTACK_ROUTE_WAF=1.',\n 'const patchstackGuard = createMiddleware().server(async ({ next }) => {',\n ' const request = getRequest();',\n ' if (request) {',\n ' const { pathname } = new URL(request.url);',\n ' if (pathname === GUARD_PATH) return handleGuardRequest(request);',\n ' if (process.env.PATCHSTACK_ROUTE_WAF === \"1\") {',\n ' const blocked = await guardRequest(request);',\n ' if (blocked) return blocked;',\n ' }',\n ' }',\n ' return screenResponse(await next());',\n '});',\n '// #endregion patchstack-guard',\n].join('\\n');\n\nconst FUNCTION_MIDDLEWARE_BLOCK = [\n '// #region patchstack-function-guard (managed by patchstack-connect protect — do not edit)',\n '// Inspect server-function args before they reach the database.',\n 'const patchstackFunctionGuard = createMiddleware({ type: \"function\" }).server(async ({ next, data }) => {',\n ' const blocked = await inspectServerFn(data);',\n ' if (blocked) throw new Error(blocked.message);',\n ' return next();',\n '});',\n '// #endregion patchstack-function-guard',\n].join('\\n');\n\n// Reconcile a managed block: replace a marked region in place (UPGRADE), migrate a legacy\n// (un-marked) block, or insert before `insertBefore` (fresh). Legacy blocks are our own single\n// arrow-fn statements whose only line-leading `});` is the terminator, so we bound them from the\n// `const` line (plus the comment header immediately above) to that `});`.\nfunction reconcileBlock(s: string, region: string, block: string, legacyConst: string, insertBefore: string): string {\n const lines = s.split('\\n');\n const startMarker = `// #region ${region} `;\n const endMarker = `// #endregion ${region}`;\n const si = lines.findIndex((l) => l.includes(startMarker));\n if (si !== -1) {\n const ei = lines.findIndex((l, i) => i > si && l.trim() === endMarker);\n if (ei !== -1) {\n lines.splice(si, ei - si + 1, ...block.split('\\n'));\n return lines.join('\\n');\n }\n }\n const ci = lines.findIndex((l) => l.includes(legacyConst));\n if (ci !== -1) {\n const close = lines.findIndex((l, i) => i >= ci && l.trim() === '});');\n if (close !== -1) {\n let start = ci;\n while (start > 0 && (lines[start - 1] ?? '').trim().startsWith('//')) start--; // eat old comment header\n lines.splice(start, close - start + 1, ...block.split('\\n'));\n return lines.join('\\n');\n }\n }\n return s.replace(insertBefore, block + '\\n\\n' + insertBefore);\n}\n\nfunction detect(cwd: string): boolean {\n const pkgPath = join(cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n let pkg: { dependencies?: Record<string, string>; devDependencies?: Record<string, string> };\n try {\n pkg = JSON.parse(read(pkgPath));\n } catch {\n return false;\n }\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return (\n Boolean(deps['@tanstack/react-start']) &&\n existsSync(join(cwd, 'src/start.ts')) &&\n existsSync(join(cwd, 'src/integrations/supabase/client.ts'))\n );\n}\n\nconst GUARD_FILE = 'src/integrations/patchstack/guard.ts';\n\nfunction scaffold(cwd: string, opts: WireOptions): string[] {\n const templates = templatesDir();\n const dst = join(cwd, 'src/integrations/patchstack');\n mkdirSync(dst, { recursive: true });\n copyFileSync(join(templates, 'guard.ts'), join(dst, 'guard.ts')); // guard.ts is managed — always refreshed\n const changed = [GUARD_FILE];\n const rulesDst = join(dst, 'rules.json');\n // Default: the high-precision starter, written only if absent (don't clobber the user's rules on\n // re-run). --demo: (re)seed the broad multi-class sample bundle for a self-contained demonstration.\n if (opts.demo) {\n copyFileSync(join(templates, 'demo-rules.json'), rulesDst);\n changed.push('src/integrations/patchstack/rules.json');\n log('scaffolded guard.ts + rules.json (demo sample rule set)');\n } else if (!existsSync(rulesDst)) {\n copyFileSync(join(templates, 'rules.json'), rulesDst);\n changed.push('src/integrations/patchstack/rules.json');\n log('scaffolded guard.ts + rules.json (starter rules)');\n } else {\n log('scaffolded guard.ts (kept existing rules.json)');\n }\n return changed;\n}\n\nfunction patchClient(cwd: string): boolean {\n const p = join(cwd, 'src/integrations/supabase/client.ts');\n const s = read(p);\n if (s.includes('x-ps-target')) {\n log('client.ts already wired');\n return false;\n }\n const anchor = \"headers.set('apikey', supabaseKey);\";\n if (!s.includes(anchor)) {\n log('client.ts anchor not found — skipping (template changed?)');\n return false;\n }\n writeFileSync(p, s.replace(anchor, anchor + '\\n' + CLIENT_TUNNEL));\n log('patched client.ts (tunnel Supabase through the guard)');\n return true;\n}\n\nfunction patchStart(cwd: string): boolean {\n const p = join(cwd, 'src/start.ts');\n let s = read(p);\n const importAnchor = 'import { createStart, createMiddleware } from \"@tanstack/react-start\";';\n const exportAnchor = 'export const startInstance';\n const rmAnchor = 'requestMiddleware: [';\n if (!s.includes(importAnchor) || !s.includes(exportAnchor)) {\n log('start.ts anchors not found — skipping (template changed?)');\n return false;\n }\n\n // Each step reconciles idempotently: a re-run (including after a connect upgrade) refreshes the\n // managed blocks in place — never duplicates, never leaves a stale version behind.\n const original = s;\n\n // Imports — refresh the managed guard import line wholesale (upgrade), else insert both imports.\n if (GUARD_IMPORT_RE.test(s)) {\n s = s.replace(GUARD_IMPORT_RE, GUARD_IMPORT);\n } else {\n s = s.replace(importAnchor, importAnchor + '\\n' + START_IMPORTS);\n }\n\n // Middleware blocks — upgrade a marked region / migrate a legacy block / insert fresh.\n s = reconcileBlock(s, 'patchstack-guard', REQUEST_MIDDLEWARE_BLOCK, 'const patchstackGuard =', exportAnchor);\n s = reconcileBlock(s, 'patchstack-function-guard', FUNCTION_MIDDLEWARE_BLOCK, 'const patchstackFunctionGuard =', exportAnchor);\n\n // Register the browser-tunnel guard in requestMiddleware.\n if (s.includes(rmAnchor) && !s.includes('requestMiddleware: [patchstackGuard')) {\n s = s.replace(rmAnchor, rmAnchor + 'patchstackGuard, ');\n }\n\n // Register the server-function guard in functionMiddleware (create the key if the app has none).\n if (!s.includes('functionMiddleware: [patchstackFunctionGuard')) {\n const fmAnchor = 'functionMiddleware: [';\n if (s.includes(fmAnchor)) {\n s = s.replace(fmAnchor, fmAnchor + 'patchstackFunctionGuard, ');\n } else if (s.includes(rmAnchor)) {\n s = s.replace(rmAnchor, 'functionMiddleware: [patchstackFunctionGuard],\\n ' + rmAnchor);\n }\n }\n\n if (s === original) {\n log('start.ts already wired');\n return false;\n }\n writeFileSync(p, s);\n log('patched start.ts (guard registered as request + function middleware)');\n return true;\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n const changed = scaffold(cwd, opts);\n // In demo mode, keep the local sample rules active — don't bake a site UUID (which would make\n // the guard fetch live Pulse rules instead of the bundled demo set).\n if (!opts.demo && bakeSiteUuid(cwd, GUARD_FILE)) changed.push(GUARD_FILE);\n if (patchClient(cwd)) changed.push('src/integrations/supabase/client.ts');\n if (patchStart(cwd)) changed.push('src/start.ts');\n log(\n opts.demo\n ? 'done — guard wired with the demo sample rules (blocks by default). Set PATCHSTACK_MODE=dry-run for log-only.'\n : 'done — guard wired and always-on (blocks by default). Set PATCHSTACK_MODE=dry-run for log-only.',\n );\n return { ok: true, changed: [...new Set(changed)] };\n}\n\nfunction verify(cwd: string): VerifyResult {\n const guardPath = join(cwd, GUARD_FILE);\n const clientPath = join(cwd, 'src/integrations/supabase/client.ts');\n const startPath = join(cwd, 'src/start.ts');\n const guard = existsSync(guardPath) ? read(guardPath) : '';\n const client = existsSync(clientPath) ? read(clientPath) : '';\n const start = existsSync(startPath) ? read(startPath) : '';\n\n const checks = [\n { label: 'guard.ts scaffolded', ok: guard.length > 0, hint: 'run `patchstack-connect protect`' },\n { label: 'Supabase client tunnels through the guard', ok: client.includes('x-ps-target'), hint: 'run `patchstack-connect protect` to re-patch src/integrations/supabase/client.ts' },\n { label: 'request middleware defined + registered', ok: start.includes('const patchstackGuard =') && start.includes('requestMiddleware: [patchstackGuard'), hint: 'run `patchstack-connect protect` to re-patch src/start.ts' },\n { label: 'server-function middleware defined + registered', ok: start.includes('const patchstackFunctionGuard =') && start.includes('functionMiddleware: [patchstackFunctionGuard'), hint: 'run `patchstack-connect protect` to re-patch src/start.ts' },\n ];\n return { wired: checks.every((c) => c.ok), checks };\n}\n\nexport const tanstackSupabaseAdapter: Adapter = {\n name: 'tanstack-supabase',\n label: 'TanStack Start + Supabase',\n detect,\n wire,\n verify,\n};\n","// Adapter: Next.js. Wires the guard as edge middleware (request-phase WAF + egress SSRF).\n// If the app has no middleware yet, scaffolds `middleware.ts` (+ patchstack.rules.json). If a\n// middleware file already exists, we do NOT clobber it — we scaffold the rules and print a plan\n// (add the guard to your middleware), so an existing middleware is never silently overwritten.\n\nimport { writeFileSync, existsSync, mkdirSync, copyFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { bakeSiteUuid, read, log, templatesDir } from '../util.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nfunction hasNextDep(cwd: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }.next);\n } catch {\n return false;\n }\n}\n\n// Next reads middleware from `middleware.ts` at the project root, or `src/middleware.ts` when the\n// app uses a `src/` dir. Return the existing one if present, else the conventional target.\nfunction middlewareInfo(cwd: string): { relDir: string; relFile: string; exists: boolean } {\n const candidates = ['middleware.ts', 'middleware.js', 'src/middleware.ts', 'src/middleware.js'];\n for (const rel of candidates) {\n if (existsSync(join(cwd, rel))) return { relDir: rel.includes('/') ? 'src' : '.', relFile: rel, exists: true };\n }\n const useSrc = existsSync(join(cwd, 'src'));\n return { relDir: useSrc ? 'src' : '.', relFile: useSrc ? 'src/middleware.ts' : 'middleware.ts', exists: false };\n}\n\nfunction detect(cwd: string): boolean {\n return hasNextDep(cwd);\n}\n\nfunction rulesFile(relDir: string): string {\n return relDir === '.' ? 'patchstack.rules.json' : `${relDir}/patchstack.rules.json`;\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n const templates = templatesDir();\n const mw = middlewareInfo(cwd);\n const dir = join(cwd, mw.relDir === '.' ? '' : mw.relDir);\n mkdirSync(dir, { recursive: true });\n\n // Co-locate the rules next to the middleware (the template imports ./patchstack.rules.json).\n const rulesDst = join(dir, 'patchstack.rules.json');\n const changed: string[] = [];\n if (opts.demo || !existsSync(rulesDst)) {\n copyFileSync(join(templates, opts.demo ? 'demo-rules.json' : 'rules.json'), rulesDst);\n changed.push(rulesFile(mw.relDir));\n }\n\n const mwPath = join(cwd, mw.relFile);\n const existing = mw.exists ? read(mwPath) : '';\n if (mw.exists && existing.includes('patchstack-next')) {\n // Already ours — do NOT re-copy the template over it: middleware.ts is user-editable, so\n // overwriting would discard any edits made after scaffolding.\n log(`${mw.relFile} already has the Patchstack middleware — left as-is`);\n return { ok: true, changed };\n }\n if (mw.exists) {\n // The app's own middleware — leave it, and tell the user how to add the guard.\n log(\n `existing ${mw.relFile} left untouched — scaffolded ${rulesFile(mw.relDir)}; add the guard to your ` +\n `middleware: import { createProtection } from \"@patchstack/connect/protect\", run fetchGuard() on the ` +\n `request, and return the block Response. Then: npx patchstack-connect protect --check`,\n );\n return { ok: true, changed };\n }\n\n // Fresh → write the managed middleware.\n copyFileSync(join(templates, 'next-middleware.ts'), mwPath);\n if (!opts.demo) bakeSiteUuid(cwd, mw.relFile);\n changed.push(mw.relFile);\n log(`scaffolded ${mw.relFile} (Patchstack middleware)`);\n return { ok: true, changed: [...new Set(changed)] };\n}\n\nfunction verify(cwd: string): VerifyResult {\n const mw = middlewareInfo(cwd);\n const present = mw.exists && read(join(cwd, mw.relFile)).includes('patchstack-next');\n const rulesPresent = existsSync(join(cwd, rulesFile(mw.relDir)));\n return {\n wired: present && rulesPresent,\n checks: [\n { label: 'Patchstack middleware present', ok: present, hint: `run \\`patchstack-connect protect\\` (writes ${mw.relFile})` },\n { label: 'rules co-located with the middleware', ok: rulesPresent, hint: 'run `patchstack-connect protect`' },\n ],\n };\n}\n\nexport const nextAdapter: Adapter = {\n name: 'nextjs',\n label: 'Next.js',\n detect,\n wire,\n verify,\n};\n","// Adapter: SvelteKit. Wires the guard as a server hook (`src/hooks.server.ts` → `handle`).\nimport { join } from 'node:path';\nimport { read } from '../util.js';\nimport { wireSeam, verifySeam, type SeamSpec } from '../seam.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nconst SPEC: SeamSpec = {\n templateName: 'sveltekit-hooks.ts',\n candidates: ['src/hooks.server.ts', 'src/hooks.server.js'],\n target: 'src/hooks.server.ts',\n marker: 'patchstack-sveltekit',\n planHint: 'add the guard to your `handle` (compose with `sequence()` from \"@sveltejs/kit/hooks\"), then: npx patchstack-connect protect --check',\n seamLabel: 'SvelteKit server hook',\n};\n\nfunction detect(cwd: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }['@sveltejs/kit']);\n } catch {\n return false;\n }\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n return wireSeam(cwd, opts, SPEC);\n}\n\nfunction verify(cwd: string): VerifyResult {\n return verifySeam(cwd, SPEC);\n}\n\nexport const sveltekitAdapter: Adapter = {\n name: 'sveltekit',\n label: 'SvelteKit',\n detect,\n wire,\n verify,\n};\n","// Shared \"seam-file is the guard\" wiring, used by adapters whose framework has a single server hook\n// that IS the guard (SvelteKit `hooks.server.ts`, Astro `src/middleware.ts`). Scaffold the seam from\n// a template + co-locate patchstack.rules.json. An EXISTING seam file is never clobbered — we scaffold\n// the rules and print a plan instead (so a hand-written hook is preserved).\n\nimport { existsSync, mkdirSync, copyFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { bakeSiteUuid, read, log, templatesDir } from './util.js';\nimport type { WireOptions, WireResult, VerifyResult } from './types.js';\n\nexport interface SeamSpec {\n templateName: string; // template copied to the seam target when none exists\n candidates: string[]; // existing seam files to look for, in order (repo-relative)\n target: string; // where to create the seam if none exists (repo-relative)\n marker: string; // #region marker id proving it's ours (e.g. 'patchstack-sveltekit')\n planHint: string; // guidance when an existing seam file can't be safely edited\n seamLabel: string; // human label for the check (e.g. 'SvelteKit hook')\n}\n\nfunction rulesRel(seamRel: string): string {\n const d = dirname(seamRel);\n return (d === '.' ? 'patchstack.rules.json' : `${d}/patchstack.rules.json`).replace(/\\\\/g, '/');\n}\n\nexport function wireSeam(cwd: string, opts: WireOptions, spec: SeamSpec): WireResult {\n const templates = templatesDir();\n const existing = spec.candidates.find((c) => existsSync(join(cwd, c)));\n const seamRel = existing ?? spec.target;\n mkdirSync(dirname(join(cwd, seamRel)), { recursive: true });\n\n // Rules co-locate next to the seam (the templates import ./patchstack.rules.json).\n const rulesDst = join(cwd, rulesRel(seamRel));\n const changed: string[] = [];\n if (opts.demo || !existsSync(rulesDst)) {\n copyFileSync(join(templates, opts.demo ? 'demo-rules.json' : 'rules.json'), rulesDst);\n changed.push(rulesRel(seamRel));\n }\n\n const current = existing ? read(join(cwd, existing)) : '';\n if (existing && current.includes(spec.marker)) {\n // Already ours — do NOT re-copy the template over it: the whole seam file is user-editable\n // (unlike the tanstack region-marked blocks), so overwriting would discard any edits.\n log(`${existing} already has the Patchstack guard — left as-is`);\n return { ok: true, changed };\n }\n if (existing) {\n log(`existing ${existing} left untouched — scaffolded ${rulesRel(seamRel)}; ${spec.planHint}`);\n return { ok: true, changed };\n }\n\n copyFileSync(join(templates, spec.templateName), join(cwd, seamRel));\n if (!opts.demo) bakeSiteUuid(cwd, seamRel);\n changed.push(seamRel);\n log(`scaffolded ${seamRel}`);\n return { ok: true, changed: [...new Set(changed)] };\n}\n\nexport function verifySeam(cwd: string, spec: SeamSpec): VerifyResult {\n const existing = spec.candidates.find((c) => existsSync(join(cwd, c)));\n const seamRel = existing ?? spec.target;\n const present = existing ? read(join(cwd, existing)).includes(spec.marker) : false;\n const rulesPresent = existsSync(join(cwd, rulesRel(seamRel)));\n return {\n wired: present && rulesPresent,\n checks: [\n { label: `${spec.seamLabel} present`, ok: present, hint: `run \\`patchstack-connect protect\\` (writes ${spec.target})` },\n { label: 'rules co-located with the guard', ok: rulesPresent, hint: 'run `patchstack-connect protect`' },\n ],\n };\n}\n","// Adapter: Astro. Wires the guard as middleware (`src/middleware.ts` → `onRequest`).\nimport { join } from 'node:path';\nimport { read } from '../util.js';\nimport { wireSeam, verifySeam, type SeamSpec } from '../seam.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nconst SPEC: SeamSpec = {\n templateName: 'astro-middleware.ts',\n candidates: ['src/middleware.ts', 'src/middleware.js', 'src/middleware/index.ts', 'src/middleware/index.js'],\n target: 'src/middleware.ts',\n marker: 'patchstack-astro',\n planHint: 'add the guard to your `onRequest` (compose with `sequence()` from \"astro:middleware\"), then: npx patchstack-connect protect --check',\n seamLabel: 'Astro middleware',\n};\n\nfunction detect(cwd: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }.astro);\n } catch {\n return false;\n }\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n return wireSeam(cwd, opts, SPEC);\n}\n\nfunction verify(cwd: string): VerifyResult {\n return verifySeam(cwd, SPEC);\n}\n\nexport const astroAdapter: Adapter = {\n name: 'astro',\n label: 'Astro',\n detect,\n wire,\n verify,\n};\n","// Adapter: Nuxt (Nitro). Wires the guard as a server middleware file (`server/middleware/`).\n// Nuxt runs each file there as independent middleware, so our file coexists with the app's own —\n// there's no single hook to compose. Scaffolds a new managed file (never overwrites a divergent one).\nimport { hasDependency } from '../util.js';\nimport { wireSeam, verifySeam, type SeamSpec } from '../seam.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nconst SPEC: SeamSpec = {\n templateName: 'nuxt-middleware.ts',\n candidates: ['server/middleware/patchstack.ts', 'server/middleware/patchstack.js'],\n target: 'server/middleware/patchstack.ts',\n marker: 'patchstack-nuxt',\n planHint: 'add a `server/middleware/` handler that runs the guard, then: npx patchstack-connect protect --check',\n seamLabel: 'Nuxt server middleware',\n};\n\nfunction detect(cwd: string): boolean {\n return hasDependency(cwd, 'nuxt');\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n return wireSeam(cwd, opts, SPEC);\n}\n\nfunction verify(cwd: string): VerifyResult {\n return verifySeam(cwd, SPEC);\n}\n\nexport const nuxtAdapter: Adapter = {\n name: 'nuxt',\n label: 'Nuxt',\n detect,\n wire,\n verify,\n};\n","// Locate the source file + variable where an app instance is created, for the register-into-app\n// adapters (Express/Fastify/NestJS). Dependency-free: walk src/ (or the repo root) for a source\n// file matching `re`, which MUST capture the app variable name in group 1.\n\nimport { readFileSync, existsSync, readdirSync, lstatSync } from 'node:fs';\nimport { join, relative, dirname } from 'node:path';\n\n// Build/output/test dirs are skipped so we never patch a COMPILED artifact (e.g. dist/main.js) —\n// which would leave the real src/ entry unprotected and vary by machine.\nconst SKIP_DIRS = new Set([\n 'node_modules', 'patchstack', 'dist', 'build', 'out', 'coverage', '.next', '.output', '.svelte-kit',\n 'test', 'tests', '__tests__', 'e2e', 'examples', 'fixtures', '__fixtures__',\n]);\nconst MAX_DEPTH = 8;\n\nexport function findAppInstance(cwd: string, re: RegExp): { relPath: string; appVar: string } | null {\n const root = existsSync(join(cwd, 'src')) ? join(cwd, 'src') : cwd;\n let hit: { relPath: string; appVar: string } | null = null;\n const walk = (dir: string, depth: number): void => {\n if (hit || depth > MAX_DEPTH) return;\n let entries: string[];\n try {\n entries = readdirSync(dir).sort(); // deterministic order across machines\n } catch {\n return;\n }\n for (const name of entries) {\n if (hit) return;\n if (SKIP_DIRS.has(name) || name.startsWith('.')) continue;\n const p = join(dir, name);\n let st;\n try {\n st = lstatSync(p); // lstat, not stat — do NOT follow symlinks (avoids symlink-cycle recursion)\n } catch {\n continue;\n }\n if (st.isSymbolicLink()) continue;\n if (st.isDirectory()) walk(p, depth + 1);\n else if (/\\.(?:ts|js|mjs|cjs)$/.test(name)) {\n let src: string;\n try {\n src = readFileSync(p, 'utf8');\n } catch {\n continue;\n }\n const m = re.exec(src);\n if (m) hit = { relPath: relative(cwd, p).replace(/\\\\/g, '/'), appVar: m[1]! };\n }\n }\n };\n walk(root, 0);\n return hit;\n}\n\n/** Relative ESM specifier from `fromRel` to `toRel` (both repo-relative, extension stripped). */\nexport function importSpecifier(fromRel: string, toRel: string, preserveExtension = false): string {\n let spec = relative(dirname(fromRel), toRel).replace(/\\\\/g, '/');\n if (!preserveExtension) spec = spec.replace(/\\.(?:ts|js)$/, '');\n if (!spec.startsWith('.')) spec = `./${spec}`;\n return spec;\n}\n","// Shared \"register-into-app\" wiring for adapters whose framework exposes a mutable app instance you\n// hook a guard onto (Express `app.use`, Fastify `app.register`, NestJS `app.use` on main.ts). Scaffold\n// the guard, then insert the registration call right after the app instance is created — dependency-free\n// anchor + #region-marker patching, idempotent.\n\nimport { writeFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { read, log } from './util.js';\nimport { scaffoldGeneric } from './generic.js';\nimport { findAppInstance, importSpecifier } from './find-app.js';\nimport type { WireOptions, WireResult, VerifyResult } from './types.js';\n\nexport interface RegisterSpec {\n appRe: RegExp; // matches the app-instance line; MUST capture the app var in group 1\n guardTemplate: string; // guard template scaffolded as src/patchstack/guard.ts\n /** Optional JavaScript templates for apps that execute their source files directly. */\n guardTemplateEsm?: string;\n guardTemplateCjs?: string;\n importName: string; // named export the entry imports from the guard\n call: (appVar: string) => string; // the registration statement, e.g. `${v}.use(patchstackMiddleware);`\n /** Prefer a registration anchor after app creation, such as Express's JSON body parser. */\n callAfter?: (appVar: string) => RegExp;\n /** Scaffold but leave the app untouched when the preferred anchor is absent. */\n requireCallAfter?: boolean;\n label: string; // human label for logs / verify checks, e.g. 'Express app'\n manualHint: string; // guidance when no app-instance site is found\n}\n\nconst REGION = '// #region patchstack (managed by patchstack-connect protect — do not edit)';\n\ninterface GuardTarget {\n template: string;\n file: string;\n importLine: (name: string, specifier: string) => string;\n preserveExtension: boolean;\n}\n\nfunction guardTarget(cwd: string, entryRel: string, spec: RegisterSpec): GuardTarget {\n if (/\\.cjs$/.test(entryRel) || (/\\.js$/.test(entryRel) && packageType(cwd) !== 'module')) {\n if (spec.guardTemplateCjs) {\n return {\n template: spec.guardTemplateCjs,\n file: 'guard.cjs',\n importLine: (name, target) => `const { ${name} } = require(\"${target}\");`,\n preserveExtension: true,\n };\n }\n } else if (/\\.(?:js|mjs)$/.test(entryRel) && spec.guardTemplateEsm) {\n return {\n template: spec.guardTemplateEsm,\n file: entryRel.endsWith('.mjs') ? 'guard.mjs' : 'guard.js',\n importLine: (name, target) => `import { ${name} } from \"${target}\";`,\n preserveExtension: true,\n };\n }\n\n return {\n template: spec.guardTemplate,\n file: 'guard.ts',\n importLine: (name, target) => `import { ${name} } from \"${target}\";`,\n preserveExtension: false,\n };\n}\n\nfunction packageType(cwd: string): string | undefined {\n try {\n return JSON.parse(read(join(cwd, 'package.json'))).type;\n } catch {\n return undefined;\n }\n}\n\nexport function wireRegister(cwd: string, opts: WireOptions, spec: RegisterSpec): WireResult {\n const entry = findAppInstance(cwd, spec.appRe);\n if (!entry) {\n const { changed } = scaffoldGeneric(cwd, opts, spec.guardTemplate);\n log(`${spec.label} not located — scaffolded guard; ${spec.manualHint}`);\n return { ok: true, changed };\n }\n\n const target = guardTarget(cwd, entry.relPath, spec);\n const { changed, dir } = scaffoldGeneric(cwd, opts, target.template, target.file);\n\n const p = join(cwd, entry.relPath);\n const s = read(p);\n if (s.includes(spec.importName)) {\n log(`${entry.relPath} already wired`);\n return { ok: true, changed };\n }\n\n const sourceLines = s.split('\\n');\n const sourceAppIdx = sourceLines.findIndex((line) => spec.appRe.test(line));\n const requiredAnchor = spec.callAfter?.(entry.appVar);\n if (\n spec.requireCallAfter &&\n requiredAnchor &&\n !sourceLines.some((line, index) => index > sourceAppIdx && requiredAnchor.test(line))\n ) {\n log(`${entry.relPath} body-parser anchor not found — scaffolded guard; ${spec.manualHint}`);\n return { ok: true, changed };\n }\n\n const importLine = target.importLine(\n spec.importName,\n importSpecifier(entry.relPath, `${dir}/${target.file}`, target.preserveExtension),\n );\n const lines = s.split('\\n');\n let lastImport = -1;\n for (let i = 0; i < lines.length; i++) {\n if (/^\\s*(?:import\\b|(?:const|let|var)\\s+.+?=\\s*require\\()/.test(lines[i] ?? '')) lastImport = i;\n }\n lines.splice(lastImport + 1, 0, importLine);\n const appIdx = lines.findIndex((l) => spec.appRe.test(l));\n if (appIdx !== -1) {\n const preferred = spec.callAfter?.(entry.appVar);\n const preferredIdx = preferred\n ? lines.findIndex((line, index) => index > appIdx && preferred.test(line))\n : -1;\n const callIdx = preferredIdx === -1 ? appIdx : preferredIdx;\n lines.splice(callIdx + 1, 0, REGION, spec.call(entry.appVar), '// #endregion patchstack');\n }\n writeFileSync(p, lines.join('\\n'));\n changed.push(entry.relPath);\n log(`patched ${entry.relPath} (${spec.call(entry.appVar).trim()})`);\n return { ok: true, changed: [...new Set(changed)] };\n}\n\nexport function verifyRegister(cwd: string, spec: RegisterSpec): VerifyResult {\n const dir = existsSync(join(cwd, 'src')) ? 'src/patchstack' : 'patchstack';\n const entry = findAppInstance(cwd, spec.appRe);\n const target = entry ? guardTarget(cwd, entry.relPath, spec) : null;\n const scaffolded = target ? existsSync(join(cwd, dir, target.file)) : false;\n const entrySource = entry ? read(join(cwd, entry.relPath)) : '';\n const entryLines = entrySource.split('\\n');\n const anchor = entry && spec.callAfter ? spec.callAfter(entry.appVar) : null;\n const anchorIndex = anchor ? entryLines.findIndex((line) => anchor.test(line)) : -1;\n const callIndex = entry ? entryLines.findIndex((line) => line.includes(spec.call(entry.appVar))) : -1;\n const ordered = anchor ? anchorIndex !== -1 && callIndex > anchorIndex : callIndex !== -1;\n const wired = entrySource.includes(spec.importName) && ordered;\n return {\n wired: scaffolded && wired,\n checks: [\n { label: `${spec.label} guard scaffolded`, ok: scaffolded, hint: 'run `patchstack-connect protect`' },\n { label: `guard registered on the ${spec.label}`, ok: wired, hint: spec.manualHint },\n ],\n };\n}\n","// Generic fallback for stacks no built-in adapter matches. Rather than silently skip, we scaffold\n// a framework-agnostic guard, print a wiring plan (with best-effort entry-point detection), and\n// provide a `--check` verifier — so the builder's own agent can finish the wiring and confirm it,\n// entirely through the CLI (no server, no hosted infra).\n\nimport { readFileSync, existsSync, mkdirSync, copyFileSync, readdirSync, lstatSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { bakeSiteUuid, read, templatesDir } from './util.js';\nimport type { WireOptions, VerifyResult } from './types.js';\n\nconst GUARD_MARKER = 'patchstack/guard';\n\nfunction genericDir(cwd: string): string {\n return existsSync(join(cwd, 'src')) ? 'src/patchstack' : 'patchstack';\n}\n\nexport function scaffoldGeneric(\n cwd: string,\n opts: WireOptions,\n guardTemplate = 'generic-guard.ts',\n guardFile = 'guard.ts',\n): { changed: string[]; dir: string } {\n const templates = templatesDir();\n const dir = genericDir(cwd);\n const dst = join(cwd, dir);\n mkdirSync(dst, { recursive: true });\n copyFileSync(join(templates, guardTemplate), join(dst, guardFile));\n const guardRel = `${dir}/${guardFile}`;\n const changed = [guardRel];\n if (!opts.demo) bakeSiteUuid(cwd, guardRel);\n const rulesDst = join(dst, 'rules.json');\n if (opts.demo || !existsSync(rulesDst)) {\n copyFileSync(join(templates, opts.demo ? 'demo-rules.json' : 'rules.json'), rulesDst);\n changed.push(`${dir}/rules.json`);\n }\n return { changed, dir };\n}\n\n// Best-effort: likely server entry files + whether Express is a dependency.\nfunction candidateEntries(cwd: string): string[] {\n const names = [\n 'src/server.ts', 'src/server.js', 'src/index.ts', 'src/index.js', 'src/app.ts', 'src/app.js',\n 'src/main.ts', 'server.ts', 'server.js', 'index.ts', 'index.js', 'app.ts', 'app.js',\n ];\n const hits = names.filter((n) => existsSync(join(cwd, n)));\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n if (typeof pkg.main === 'string' && existsSync(join(cwd, pkg.main))) hits.push(pkg.main);\n } catch {\n /* ignore */\n }\n return [...new Set(hits)];\n}\n\nfunction usesExpress(cwd: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }.express);\n } catch {\n return false;\n }\n}\n\nexport function wiringPlan(cwd: string, dir: string): string {\n const entries = candidateEntries(cwd);\n const express = usesExpress(cwd);\n const lines = [\n `no built-in adapter matched this stack — scaffolded a generic guard at ${dir}/guard.ts + ${dir}/rules.json.`,\n 'Finish by wiring it into your server (pick the one that fits):',\n ` • Web-Fetch entry: export default { fetch: protectFetch(yourHandler) } // import from \"${dir}/guard\"`,\n ` • Node / Express: app.use(patchstackMiddleware) // add before your routes`,\n entries.length\n ? `Likely server ${entries.length === 1 ? 'entry' : 'entries'}: ${entries.join(', ')}${express ? ' (Express detected)' : ''}.`\n : 'Could not locate a server entry — wire it wherever requests enter your app.',\n 'Then confirm it is hooked up: npx patchstack-connect protect --check',\n ];\n return lines.join('\\n');\n}\n\nexport function genericVerify(cwd: string): VerifyResult {\n const dir = genericDir(cwd);\n const scaffolded = existsSync(join(cwd, dir, 'guard.ts'));\n const imported = scaffolded && guardIsImported(cwd, join(cwd, dir, 'guard.ts'));\n return {\n wired: scaffolded && imported,\n checks: [\n { label: 'generic guard scaffolded', ok: scaffolded, hint: 'run `patchstack-connect protect`' },\n {\n label: 'guard imported into a server entry',\n ok: imported,\n hint: `import { protectFetch } (or patchstackMiddleware) from \"${dir}/guard\" and wire it into your request path`,\n },\n ],\n };\n}\n\nfunction guardIsImported(cwd: string, guardPath: string): boolean {\n const root = existsSync(join(cwd, 'src')) ? join(cwd, 'src') : cwd;\n let found = false;\n const walk = (d: string, depth: number): void => {\n if (found || depth > 8) return;\n let entries: string[];\n try {\n entries = readdirSync(d);\n } catch {\n return;\n }\n for (const name of entries) {\n if (found) return;\n if (name === 'node_modules' || name === 'patchstack' || name.startsWith('.')) continue;\n const p = join(d, name);\n let st;\n try {\n st = lstatSync(p); // don't follow symlinks (avoids symlink-cycle recursion)\n } catch {\n continue;\n }\n if (st.isSymbolicLink()) continue;\n if (st.isDirectory()) walk(p, depth + 1);\n else if (/\\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(name) && p !== guardPath) {\n try {\n if (readFileSync(p, 'utf8').includes(GUARD_MARKER)) found = true;\n } catch {\n /* ignore */\n }\n }\n }\n };\n walk(root, 0);\n return found;\n}\n","// Adapter: NestJS. Wires the guard in the bootstrap file — `app.use(patchstackMiddleware)` right\n// after `NestFactory.create(...)`. Nest's INestApplication.use() accepts Express-style middleware\n// (the default platform), so this reuses the framework-agnostic guard rather than a Nest module +\n// decorators. On the Fastify platform the guard is still fail-open; response screening isn't wired.\nimport { hasDependency } from '../util.js';\nimport { findAppInstance } from '../find-app.js';\nimport { wireRegister, verifyRegister, type RegisterSpec } from '../register.js';\nimport type { Adapter } from '../types.js';\n\nconst SPEC: RegisterSpec = {\n appRe: /(?:const|let|var)\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*await\\s+NestFactory\\.create/,\n guardTemplate: 'generic-guard.ts',\n guardTemplateEsm: 'generic-guard.js',\n guardTemplateCjs: 'generic-guard.cjs',\n importName: 'patchstackMiddleware',\n call: (v) => `${v}.use(patchstackMiddleware);`,\n label: 'NestJS app',\n manualHint: 'add `app.use(patchstackMiddleware)` right after your NestFactory.create(...) call',\n};\n\nexport const nestjsAdapter: Adapter = {\n name: 'nestjs',\n label: 'NestJS',\n detect: (cwd) => hasDependency(cwd, '@nestjs/core') && findAppInstance(cwd, SPEC.appRe) !== null,\n wire: (cwd, opts) => wireRegister(cwd, opts, SPEC),\n verify: (cwd) => verifyRegister(cwd, SPEC),\n};\n","// Adapter: Fastify (Node). Scaffolds the Fastify guard plugin and registers it on the app —\n// `app.register(patchstackFastify)` right after the `fastify()` instance is created.\nimport { hasDependency } from '../util.js';\nimport { findAppInstance } from '../find-app.js';\nimport { wireRegister, verifyRegister, type RegisterSpec } from '../register.js';\nimport type { Adapter } from '../types.js';\n\nconst SPEC: RegisterSpec = {\n appRe: /(?:const|let|var)\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*(?:fastify|Fastify)\\(/,\n guardTemplate: 'fastify-plugin.ts',\n guardTemplateEsm: 'fastify-plugin.js',\n guardTemplateCjs: 'fastify-plugin.cjs',\n importName: 'patchstackFastify',\n call: (v) => `${v}.register(patchstackFastify);`,\n label: 'Fastify app',\n manualHint: 'add `app.register(patchstackFastify)` right after you create your fastify() app',\n};\n\nexport const fastifyAdapter: Adapter = {\n name: 'fastify',\n label: 'Fastify (Node)',\n detect: (cwd) => hasDependency(cwd, 'fastify') && findAppInstance(cwd, SPEC.appRe) !== null,\n wire: (cwd, opts) => wireRegister(cwd, opts, SPEC),\n verify: (cwd) => verifyRegister(cwd, SPEC),\n};\n","// Adapter: Express (Node). Scaffolds a guard that matches the entry file's module format, then\n// registers the WAF middleware after the app's body parser and before its routes — the guard reads\n// the express-parsed req.body, so it must run once the body is populated.\nimport { hasDependency } from '../util.js';\nimport { findAppInstance } from '../find-app.js';\nimport { wireRegister, verifyRegister, type RegisterSpec } from '../register.js';\nimport type { Adapter } from '../types.js';\n\n// A body parser that populates req.body, in any of the shapes AI builders emit: express.json() /\n// express.urlencoded(), body-parser's bodyParser.json() / .urlencoded(), an aliased parser\n// (any `x.json(` / `x.urlencoded(`), or a destructured `json(` / `urlencoded(`.\nconst bodyParserRe = (appVar: string) =>\n new RegExp(`^\\\\s*${appVar}\\\\.use\\\\(\\\\s*(?:[A-Za-z_$][\\\\w$]*\\\\.)?(?:json|urlencoded)\\\\(`, 'm');\n\nconst SPEC: RegisterSpec = {\n appRe: /(?:const|let|var)\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*express\\(\\)/,\n guardTemplate: 'express-guard.ts',\n guardTemplateEsm: 'express-guard.js',\n guardTemplateCjs: 'express-guard.cjs',\n importName: 'patchstackMiddleware',\n call: (v) => `${v}.use(patchstackMiddleware);`,\n callAfter: bodyParserRe,\n requireCallAfter: true,\n label: 'Express app',\n manualHint: 'add `app.use(patchstackMiddleware)` after your body parser (express.json/urlencoded or body-parser) and before the routes',\n};\n\nexport const expressAdapter: Adapter = {\n name: 'express',\n label: 'Express (Node)',\n detect: (cwd) => hasDependency(cwd, 'express') && findAppInstance(cwd, SPEC.appRe) !== null,\n wire: (cwd, opts) => wireRegister(cwd, opts, SPEC),\n verify: (cwd) => verifyRegister(cwd, SPEC),\n};\n","// `patchstack-connect protect` — scaffold the always-on runtime guard into an app.\n//\n// Stack-specific wiring lives in one adapter per builder/framework shape (see ./adapters/). This\n// orchestrator picks the first adapter that matches the app and delegates. If none matches it\n// ESCALATES (never silently skips) — the guard engine itself is stack-agnostic, so an unmatched\n// app is a gap in auto-wiring coverage to be closed by a new adapter or an agent-assisted install,\n// not a reason to leave the app unprotected quietly.\n\nimport { log } from './util.js';\nimport { tanstackSupabaseAdapter } from './adapters/tanstack-supabase.js';\nimport { nextAdapter } from './adapters/next.js';\nimport { sveltekitAdapter } from './adapters/sveltekit.js';\nimport { astroAdapter } from './adapters/astro.js';\nimport { nuxtAdapter } from './adapters/nuxt.js';\nimport { nestjsAdapter } from './adapters/nestjs.js';\nimport { fastifyAdapter } from './adapters/fastify.js';\nimport { expressAdapter } from './adapters/express.js';\nimport { scaffoldGeneric, wiringPlan, genericVerify } from './generic.js';\nimport type { Adapter, WireOptions, ProtectResult, VerifyReport } from './types.js';\n\n// Registry — order = match priority (most specific first): framework meta-frameworks before the\n// bare server libraries (a SvelteKit/Astro app may also carry express/fastify as a transitive dep).\nconst ADAPTERS: Adapter[] = [\n tanstackSupabaseAdapter,\n nextAdapter,\n sveltekitAdapter,\n astroAdapter,\n nuxtAdapter,\n nestjsAdapter,\n fastifyAdapter,\n expressAdapter,\n];\n\n/** Scaffold + wire the runtime guard into the app at `cwd`. Best-effort — never throws. */\nexport function runProtect(cwd: string, opts: WireOptions = {}): ProtectResult {\n let adapter;\n try {\n adapter = ADAPTERS.find((a) => a.detect(cwd));\n if (adapter) {\n const result = adapter.wire(cwd, opts);\n return { status: 'wired', adapter: adapter.name, changed: result.changed };\n }\n } catch (err) {\n // A wire/detect failure (read-only FS, EACCES, a bad source file) must not crash the CLI —\n // fall through to the generic scaffold + plan so the user still gets something actionable.\n log(`adapter ${adapter?.name ?? ''} failed (${(err as Error)?.message ?? err}); falling back to a generic guard`);\n }\n\n // No adapter matched (or it failed) — DON'T silently skip. Scaffold the framework-agnostic guard\n // and print a wiring plan the builder's agent (or user) can finish, then verify with `--check`.\n try {\n const { changed, dir } = scaffoldGeneric(cwd, opts);\n const plan = wiringPlan(cwd, dir);\n log(plan);\n return { status: 'scaffolded', adapter: 'generic', changed, plan };\n } catch (err) {\n log(`could not scaffold the guard (${(err as Error)?.message ?? err})`);\n return { status: 'scaffolded', adapter: 'generic', changed: [], plan: '' };\n }\n}\n\n/** Verify the guard is correctly wired (backs `protect --check`). Fail-open — never throws. */\nexport function runVerify(cwd: string): VerifyReport {\n try {\n const adapter = ADAPTERS.find((a) => a.detect(cwd));\n if (adapter) return { stack: adapter.label, ...adapter.verify(cwd) };\n return { stack: 'generic', ...genericVerify(cwd) };\n } catch (err) {\n return { stack: 'unknown', wired: false, checks: [{ label: 'verification failed', ok: false, hint: String((err as Error)?.message ?? err) }] };\n }\n}\n\nexport type { Adapter, WireOptions, WireResult, VerifyResult, VerifyReport, ProtectResult } from './types.js';\n","// Managed disclosure-widget tag — the connector installs the widget for you.\n//\n// After a successful scan the connector ensures the site's root HTML shell\n// carries the widget's one-liner CDN tag (the canonical install form from the\n// widget docs: a single <script> with `data-site-uuid`, auto-initialising on\n// DOMContentLoaded). The tag carries an ownership attribute so re-runs update\n// it in place instead of stacking copies, and so `uninstall` flows can find it.\n// A manual/legacy install (any other reference to the widget script) is always\n// left untouched — we never convert or duplicate someone's hand-rolled tag.\n\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nexport const WIDGET_SCRIPT_URL = 'https://cdn.patchstack.com/patchstack-widget.js';\n\n/** Attribute that tags the connector-managed widget tag so re-runs update it. */\nexport const WIDGET_MARKER_ATTR = 'data-patchstack-connect-widget';\n\n/** Substring that marks any widget install (managed or manual) in HTML. */\nconst WIDGET_NEEDLE = 'patchstack-widget';\n\n/**\n * Root HTML shells the connector is willing to edit, in priority order:\n * Vite/plain SPA, CRA-style, SvelteKit. Framework layouts that are code rather\n * than HTML (Next/Nuxt/Astro layouts) are never edited automatically — `guide`\n * prints the snippet and the right file for those.\n */\nexport const SOURCE_SHELL_CANDIDATES = ['index.html', 'public/index.html', 'src/app.html'];\n\nexport function buildWidgetTag(siteUuid: string): string {\n return `<script src=\"${WIDGET_SCRIPT_URL}\" data-site-uuid=\"${siteUuid}\" defer ${WIDGET_MARKER_ATTR}=\"true\"></script>`;\n}\n\nexport type WidgetEnsureAction =\n /** No widget present — the managed tag was inserted before </body>. */\n | 'added'\n /** A managed tag existed with a different UUID — replaced in place. */\n | 'updated'\n /** The managed tag is already present and current. */\n | 'unchanged'\n /** A manual (non-managed) widget install exists — left untouched. */\n | 'manual'\n /** The document has no </body> to anchor on — nothing was changed. */\n | 'no-body';\n\nexport interface WidgetEnsureResult {\n html: string;\n action: WidgetEnsureAction;\n}\n\nconst MANAGED_TAG_RE = new RegExp(\n `<script[^>]*${WIDGET_MARKER_ATTR}[^>]*>\\\\s*</script>`,\n 'i',\n);\n\n/**\n * Ensure a single HTML document carries the managed widget tag. Idempotent:\n * updates the managed tag in place, adopts (leaves alone) manual installs, and\n * only ever inserts immediately before </body>.\n */\nexport function ensureWidgetInHtml(html: string, siteUuid: string): WidgetEnsureResult {\n const tag = buildWidgetTag(siteUuid);\n\n const managed = html.match(MANAGED_TAG_RE);\n if (managed !== null) {\n if (managed[0].includes(`data-site-uuid=\"${siteUuid}\"`)) {\n return { html, action: 'unchanged' };\n }\n return { html: html.replace(MANAGED_TAG_RE, tag), action: 'updated' };\n }\n\n if (html.includes(WIDGET_NEEDLE)) {\n return { html, action: 'manual' };\n }\n\n const bodyClose = html.match(/([ \\t]*)<\\/body>/i);\n if (bodyClose === null || bodyClose.index === undefined) {\n return { html, action: 'no-body' };\n }\n const indent = bodyClose[1] ?? '';\n const insertion = `${indent} ${tag}\\n${indent}</body>`;\n return {\n html: html.slice(0, bodyClose.index) + insertion + html.slice(bodyClose.index + bodyClose[0].length),\n action: 'added',\n };\n}\n\n/** First editable root HTML shell in the project, or null when there is none. */\nexport function findSourceShell(cwd: string): string | null {\n for (const candidate of SOURCE_SHELL_CANDIDATES) {\n if (existsSync(path.join(cwd, candidate))) {\n return candidate;\n }\n }\n return null;\n}\n\nexport interface SourceWidgetResult {\n /** Project-relative path of the shell that was inspected, or null. */\n shell: string | null;\n action: WidgetEnsureAction | 'no-shell';\n}\n\n/**\n * Ensure the managed widget tag in the project's root HTML shell. Edits at most\n * that one file; returns what happened so the caller can report it.\n */\nexport function ensureSourceWidget(cwd: string, siteUuid: string): SourceWidgetResult {\n const shell = findSourceShell(cwd);\n if (shell === null) {\n return { shell: null, action: 'no-shell' };\n }\n const file = path.join(cwd, shell);\n const before = readFileSync(file, 'utf8');\n const { html, action } = ensureWidgetInHtml(before, siteUuid);\n if (html !== before) {\n writeFileSync(file, html);\n }\n return { shell, action };\n}\n","import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport { persistApiKey } from './config.js';\nimport type { Config } from './types.js';\n\n/**\n * Device authorization flow (RFC 8628) for recovering a lost credential.\n *\n * Split into `startLogin` and `waitForApproval` because the two callers need\n * opposite things. A person at a terminal wants one command that prints a code\n * and blocks. An assistant runs a command, waits for it to exit, and only then\n * reads the output — so a command that blocks for ten minutes shows it nothing\n * until the code has already expired, and looks like a hang.\n *\n * `startLogin` returns immediately with the link. `waitForApproval` polls. The\n * CLI runs both for a terminal and only the first for everything else.\n */\n\nexport interface LoginDeps {\n fetchImpl?: typeof fetch;\n /** Injected so tests do not wait. */\n sleep?: (ms: number) => Promise<void>;\n now?: () => number;\n}\n\nexport interface PendingLogin {\n /** Redeems the credential once approved. Never printed — it is a secret. */\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n expiresAt: number;\n intervalMs: number;\n}\n\nexport interface StartResult {\n status: 'started' | 'unclaimed' | 'not-found' | 'failed';\n pending?: PendingLogin;\n message?: string;\n}\n\nexport interface LoginResult {\n status: 'approved' | 'expired' | 'unclaimed' | 'not-found' | 'failed';\n message?: string;\n userCode?: string;\n verificationUri?: string;\n}\n\nfunction baseFrom(manifestEndpoint: string): string {\n const url = new URL(manifestEndpoint);\n const p = url.pathname.replace(/\\/$/, '');\n url.pathname = p.endsWith('/manifest') ? p.slice(0, -'/manifest'.length) : '/monitor/pulse';\n url.search = '';\n url.hash = '';\n return url.toString().replace(/\\/$/, '');\n}\n\n/**\n * Where a pending request waits between the two commands.\n *\n * The temp directory rather than the project: the device code is a secret with\n * a ten-minute life, and nothing that short-lived belongs in a repo where it\n * could be committed. Keyed by site so two projects do not collide.\n */\nfunction pendingPath(siteUuid: string): string {\n const key = createHash('sha256').update(siteUuid).digest('hex').slice(0, 16);\n return path.join(tmpdir(), `patchstack-login-${key}.json`);\n}\n\nexport function savePendingLogin(siteUuid: string, pending: PendingLogin): void {\n writeFileSync(pendingPath(siteUuid), JSON.stringify(pending), { encoding: 'utf8', mode: 0o600 });\n}\n\nexport function readPendingLogin(siteUuid: string): PendingLogin | null {\n try {\n return JSON.parse(readFileSync(pendingPath(siteUuid), 'utf8')) as PendingLogin;\n } catch {\n return null; // absent, unreadable, or corrupt — all mean \"nothing pending\"\n }\n}\n\nexport function clearPendingLogin(siteUuid: string): void {\n try {\n rmSync(pendingPath(siteUuid));\n } catch {\n /* already gone */\n }\n}\n\n/** Ask for a code. Returns as soon as the link is available. */\nexport async function startLogin(config: Config, deps: LoginDeps = {}): Promise<StartResult> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const now = deps.now ?? (() => Date.now());\n\n if (config.siteUuid === null) {\n return { status: 'failed', message: 'No site UUID configured — run `patchstack-connect scan` first.' };\n }\n\n const base = baseFrom(config.endpoint);\n\n const started = await fetchImpl(`${base}/device/code`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n body: JSON.stringify({ site_uuid: config.siteUuid }),\n });\n\n if (started.status === 409) {\n return {\n status: 'unclaimed',\n message:\n 'This site has not been claimed yet, so there is no owner to approve the request. Claim it in the dashboard, or delete .patchstackrc.json to provision a new site.',\n };\n }\n if (started.status === 404) {\n return { status: 'not-found', message: 'Patchstack does not recognise this site UUID.' };\n }\n if (!started.ok) {\n return { status: 'failed', message: `Could not start the login (HTTP ${started.status}).` };\n }\n\n const body = (await started.json()) as {\n device_code: string;\n user_code: string;\n expires_in: number;\n interval: number;\n };\n\n const pending: PendingLogin = {\n deviceCode: body.device_code,\n userCode: body.user_code,\n // Points at the API, which redirects to the dashboard SPA — the CLI only\n // knows the API origin, and the approval page lives on the app.\n verificationUri: `${base}/device?code=${encodeURIComponent(body.user_code)}`,\n expiresAt: now() + body.expires_in * 1000,\n intervalMs: Math.max(1, body.interval) * 1000,\n };\n\n savePendingLogin(config.siteUuid, pending);\n\n return { status: 'started', pending };\n}\n\n/**\n * Redeem a pending request if the owner has already approved it, without\n * waiting. Lets a second `login` finish a flow the first one started, so an\n * assistant that comes back after the user approves does the right thing\n * whether or not it remembers the `--wait` flag.\n */\nexport async function redeemIfApproved(\n config: Config,\n pending: PendingLogin,\n deps: LoginDeps = {},\n): Promise<'approved' | 'pending' | 'expired'> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n\n const polled = await fetchImpl(`${baseFrom(config.endpoint)}/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n body: JSON.stringify({ device_code: pending.deviceCode }),\n });\n\n if (polled.status === 428) return 'pending';\n\n if (!polled.ok) {\n if (config.siteUuid !== null) clearPendingLogin(config.siteUuid);\n return 'expired';\n }\n\n const { api_key: apiKey } = (await polled.json()) as { api_key?: string };\n if (typeof apiKey !== 'string' || apiKey.length === 0) return 'expired';\n\n await persistApiKey(process.cwd(), apiKey);\n if (config.siteUuid !== null) clearPendingLogin(config.siteUuid);\n\n return 'approved';\n}\n\n/** Poll until the owner approves, the code expires, or `until` passes. */\nexport async function waitForApproval(\n config: Config,\n pending: PendingLogin,\n deps: LoginDeps & { until?: number } = {},\n): Promise<LoginResult> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const sleep = deps.sleep ?? ((ms: number) => new Promise((r) => setTimeout(r, ms)));\n const now = deps.now ?? (() => Date.now());\n\n const deadline = Math.min(pending.expiresAt, deps.until ?? pending.expiresAt);\n const expired = { status: 'expired' as const, message: 'The login request expired. Run the command again.' };\n\n while (now() < deadline) {\n await sleep(pending.intervalMs);\n\n const polled = await fetchImpl(`${baseFrom(config.endpoint)}/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n body: JSON.stringify({ device_code: pending.deviceCode }),\n });\n\n if (polled.status === 428) continue; // still waiting on the human\n if (!polled.ok) {\n if (config.siteUuid !== null) clearPendingLogin(config.siteUuid);\n return expired;\n }\n\n const { api_key: apiKey } = (await polled.json()) as { api_key?: string };\n if (typeof apiKey !== 'string' || apiKey.length === 0) {\n return { status: 'failed', message: 'Patchstack approved the request but returned no credential.' };\n }\n\n // Approving rotates the site's OAuth secret, which Pulse ingest and\n // block-log reporting both authenticate with.\n await persistApiKey(process.cwd(), apiKey);\n if (config.siteUuid !== null) clearPendingLogin(config.siteUuid);\n\n return { status: 'approved', userCode: pending.userCode, verificationUri: pending.verificationUri };\n }\n\n return expired;\n}\n\n/**\n * Start a flow and block until it resolves. For a terminal, where someone is\n * watching the output as it streams.\n */\nexport async function login(\n config: Config,\n onPrompt: (userCode: string, verificationUri: string) => void,\n deps: LoginDeps = {},\n): Promise<LoginResult> {\n const started = await startLogin(config, deps);\n\n if (started.status !== 'started' || started.pending === undefined) {\n return { status: started.status === 'started' ? 'failed' : started.status, message: started.message };\n }\n\n onPrompt(started.pending.userCode, started.pending.verificationUri);\n\n return waitForApproval(config, started.pending, deps);\n}\n\n/** Exported for tests that need a scratch temp dir. */\nexport function makeTempDir(prefix = 'patchstack-'): string {\n return mkdtempSync(path.join(tmpdir(), prefix));\n}\n","import { createRequire } from 'node:module';\nimport { pathToFileURL } from 'node:url';\nimport { join } from 'node:path';\nimport type { TsModule } from './types.js';\n\n// Load a TypeScript compiler for parsing the target app's source. We do NOT bundle `typescript` into\n// connect (it's a heavy dep and the runtime guard never needs it) — instead we resolve the TARGET\n// app's own installed `typescript` (every TS app has it, at the exact version its code expects), then\n// fall back to a `typescript` resolvable from connect's own context (dev/global). Returns null if\n// neither is available, so the caller can degrade with a clear message rather than crash.\nexport async function loadTypeScript(cwd: string): Promise<TsModule | null> {\n // 1. The target app's node_modules (the normal case).\n try {\n const req = createRequire(pathToFileURL(join(cwd, 'package.json')));\n const resolved = req.resolve('typescript');\n const mod = await import(pathToFileURL(resolved).href);\n return (mod.default ?? mod) as TsModule;\n } catch {\n /* fall through */\n }\n // 2. A `typescript` resolvable from here (connect dev / a global install).\n try {\n const mod = await import('typescript');\n return (mod.default ?? mod) as TsModule;\n } catch {\n return null;\n }\n}\n","import { readFileSync, realpathSync } from 'node:fs';\nimport { createHash } from 'node:crypto';\nimport { relative } from 'node:path';\nimport type { SiteInputMap, Endpoint, TsModule } from './types.js';\nimport { guessScriptKind } from './ast.js';\nimport { buildModuleBindings } from './bindings.js';\nimport { collectSources, detectDeploymentShapes, detectFramework, hasEntrySignal, type WalkStats } from './sources.js';\nimport { classifyServerSurface, surfaceNote } from './surface.js';\nimport { functionNameFromPath, routeFromFilePath } from './routes.js';\nimport { collectLocalSinks } from './sinks.js';\nimport { createModuleGraph } from './module-graph.js';\nimport { isProvenFlow } from './coordinates.js';\nimport { extractFromFile } from './entries.js';\nimport { collectFileImports, countUnresolvableImports, createImportInventory, readPathAliases, scanFileImports } from './imports.js';\nimport { collectInvocations, createInvocationInventory } from './invocations.js';\n\n// Framework-AGNOSTIC input-flow extractor. It doesn't gate on a specific stack — it walks any JS/TS\n// source and applies recognizer tables for (1) entry points, (2) inputs, (3) sinks, so it generalizes\n// across builders (TanStack Start, Next, SvelteKit, Express/Fastify/Hono, …) and providers, and\n// degrades gracefully (recording what it couldn't see in `coverage.notes`). Add a stack by adding a\n// recognizer, not a new adapter.\n//\n// False-positive control: sink and validator recognizers are gated on the file's module bindings —\n// a call whose receiver is a plain local object/class/function is NOT a dependency sink, and\n// `.object({…})` is only read as an input schema when its receiver traces to a known validator\n// package. Receivers that can't be traced (handler params, cross-file imports) stay heuristic,\n// favoring recall over precision.\n\nexport interface ExtractOptions {\n /** Follow symlinks that leave the project directory (off by default — keeps analysis in-project). */\n followSymlinks?: boolean;\n}\n\nexport async function extractInputMap(cwd: string, ts: TsModule, options: ExtractOptions = {}): Promise<SiteInputMap> {\n const notes: string[] = [];\n const endpoints: Endpoint[] = [];\n const failed: string[] = [];\n let boundary = cwd;\n try { boundary = realpathSync(cwd); } catch { /* use cwd as-is */ }\n\n const graph = createModuleGraph(ts, { cwd, boundary, followOutside: options.followSymlinks }); // shared cache\n const stats: WalkStats = { discovered: 0, unwalked: 0 };\n const files = collectSources(cwd, boundary, { followOutside: options.followSymlinks }, [], new Set(), stats);\n const imports = createImportInventory(readPathAliases(cwd));\n const invocations = createInvocationInventory();\n let parsed = 0;\n let preFiltered = 0;\n let importScanFailures = 0;\n let unresolvableImports = 0;\n let sourceBytes = 0;\n const calls = { total: 0, dependency: 0, local: 0, ambiguous: 0 };\n const startedAt = Date.now();\n // Local modules an entry file imports directly — parsed after the walk for their invocations (below).\n const entryFiles = new Set<string>();\n const hopTargets = new Set<string>();\n\n for (const file of files) {\n try {\n const text = readFileSync(file, 'utf8');\n const relFile = relative(cwd, file);\n sourceBytes += text.length;\n // Imports are collected from EVERY file, entry point or not: the data layer of an AI-built app\n // usually lives in a file with no handler in it, so a pre-filtered file is exactly where the\n // interesting dependency is imported.\n if (!hasEntrySignal(text)) {\n preFiltered++;\n const scanned = scanFileImports(text, ts);\n if (scanned === null) importScanFailures++; // this file's imports are unknown, not empty\n else imports.add(relFile, scanned, false);\n unresolvableImports += countUnresolvableImports(text, ts);\n continue;\n }\n parsed++;\n entryFiles.add(file);\n // Coordinates are only valid for the exact file content they were derived from.\n const fingerprint = createHash('sha256').update(text).digest('hex').slice(0, 16);\n const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true, guessScriptKind(ts, file));\n const bindings = buildModuleBindings(sf, ts);\n for (const specifier of bindings.imports) {\n if (!specifier.startsWith('.')) continue; // node_modules is not this app's surface\n const target = graph.resolveLocal(file, specifier);\n if (target !== undefined) hopTargets.add(target);\n }\n imports.add(relFile, collectFileImports(sf, ts), true);\n // Counted on this path too. A parsed file is not a covered file: `collectFileImports` requires a\n // string-literal specifier, so a computed require in an entry file is just as unattributable as\n // one in a pre-filtered file — and this is the path where it is easiest to assume otherwise.\n unresolvableImports += countUnresolvableImports(text, ts);\n const ctx = { file, owner: relFile, graph };\n // The ctx reaches helper summaries too, so a same-file helper using an imported client resolves.\n // The invocation inventory rides the parse we already did for sinks — no second pass, which is what\n // makes it cheap enough to ship before deciding whether to parse more files.\n const called = collectInvocations(sf, ts, bindings, ctx);\n invocations.add(called.invocations);\n calls.total += called.counts.total;\n calls.dependency += called.counts.dependency;\n calls.local += called.counts.local;\n calls.ambiguous += called.counts.ambiguous;\n const localSinks = collectLocalSinks(sf, ts, bindings, ctx);\n for (const ep of extractFromFile(sf, ts, localSinks, bindings, ctx)) {\n // A FILE-BASED route handler carries its URL path in its location, not in the code, so derive\n // it here — without this a rule can only be param-pinned, never route-scoped (`when.path`).\n if (ep.route === undefined && ep.entryKind === 'edge-function') {\n const fn = functionNameFromPath(relFile);\n if (fn) ep.route = '/' + fn; // how the platform invokes it (…/functions/v1/<name>)\n }\n if (ep.route === undefined && (ep.entryKind === 'route-handler' || ep.entryKind === 'server-action')) {\n const derived = routeFromFilePath(relFile);\n if (derived.route) {\n ep.route = derived.route;\n if (derived.dynamic) ep.routeDynamic = true;\n }\n }\n endpoints.push({ ...ep, file: relFile, fingerprint });\n }\n } catch (e) {\n // The fail-open below is right for production but hides bugs during development: a crash in the\n // extractor looks identical to an unparseable file. PS_MAP_DEBUG surfaces it.\n if (typeof process !== 'undefined' && process.env?.PS_MAP_DEBUG) console.error('[patchstack] map error', file, e);\n // Fail-open: one unreadable/unparseable file must never kill the whole map.\n failed.push(relative(cwd, file));\n }\n }\n\n // --- one hop: the local modules an entry file imports ----------------------\n // An entry file's dependency calls are usually not written IN the entry file. `src/server.js` imports\n // `loadConfig` from `./config`, and the `JSON5.parse(...)` call lives in config.js — a file with no entry\n // signal, so the walk above only scanned its imports. Reading the call from the file it is written in is\n // the difference between reporting the API an advisory names and reporting nothing about it.\n //\n // ONE hop, from entry files only, invocations only: no sinks, no endpoints, no recursion into what the\n // hop file itself imports. The bound is structural — reachable from an entry by a relative import —\n // rather than a file budget, so coverage is predictable from the app's shape instead of from its size.\n let hopParsed = 0;\n let hopFailures = 0;\n for (const target of hopTargets) {\n if (entryFiles.has(target)) continue; // already collected above, along with its endpoints\n try {\n const text = readFileSync(target, 'utf8');\n const sf = ts.createSourceFile(target, text, ts.ScriptTarget.Latest, true, guessScriptKind(ts, target));\n const bindings = buildModuleBindings(sf, ts);\n // `owner` is the hop file, so a site points at the line that makes the call rather than at the\n // entry file that reaches it. A coordinate naming the wrong file cannot be checked by hand.\n const called = collectInvocations(sf, ts, bindings, { file: target, owner: relative(cwd, target), graph });\n invocations.add(called.invocations);\n calls.total += called.counts.total;\n calls.dependency += called.counts.dependency;\n calls.local += called.counts.local;\n calls.ambiguous += called.counts.ambiguous;\n hopParsed++;\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.PS_MAP_DEBUG) console.error('[patchstack] map hop error', target, e);\n // Fail-open, and counted: these files were already read once for their imports, so they must NOT\n // join `failed` (that would double-count the skip and flip the import-completeness flag over a\n // gap that belongs to a different question).\n hopFailures++;\n }\n }\n\n notes.push('Static analysis is best-effort — this is the DETECTED surface, not a proof of completeness.');\n notes.push('`inputs` and `sinks` are INVENTORIES (both present in the handler). Only `flows` asserts that an input reaches a sink: require confidence \"exact-local\" or \"transformed-local\" before pinning a rule, and identify the input by `inputId` — a field NAME can occur in more than one request namespace.');\n notes.push('Sinks are followed into same-file helpers and ONE hop into an imported relative module (a dependency\\u2019s internals are not followed); deeper or dynamic indirection is not traced. Sinks inside declared-but-uncalled local functions are excluded.');\n notes.push('A sink `package` is resolved from the file’s imports (`attribution: \"import\"`) or inferred from another import in the same file (`\"inferred\"`); an inferred package is a hint for a reviewer, not evidence about the receiver, and never licenses a rule.');\n if (!options.followSymlinks) notes.push('Symlinks leaving the project directory were not followed (use --follow-symlinks to include them).');\n if (failed.length > 0) {\n const sample = failed.slice(0, 5).join(', ');\n notes.push(`${failed.length} file(s) could not be analyzed and were skipped (fail-open): ${sample}${failed.length > 5 ? ', …' : ''}.`);\n }\n const unresolved = endpoints.filter((e) => e.inputsResolved === false).length;\n if (unresolved > 0) {\n notes.push(`${unresolved} endpoint(s) declare an input validator that could not be statically parsed — their inputs are UNKNOWN, not empty (marked inputsResolved: false).`);\n }\n const heuristicOnly = endpoints.filter((e) => e.sinks.length > 0 && e.inputs.length > 0 && !e.flows.some((f) => isProvenFlow(f.confidence))).length;\n if (heuristicOnly > 0) {\n notes.push(`${heuristicOnly} endpoint(s) have inputs and sinks but no proven data link — their flows say \"may reach\", not \"does reach\" (see each flow's confidence).`);\n }\n if (endpoints.length === 0) notes.push('No recognized server-side entry points found under the analyzed roots.');\n\n const importList = imports.list();\n const unmodelled = importList.filter((d) => d.recognizedSinkKinds.length === 0).length;\n // A file we could not read is a file whose imports we do not know — the same unknown as a failed scan.\n // An unwalked subtree is the quietest gap of the three: it produces no file, so no counter moves and\n // the tree just looks smaller. It has to be part of this or the flag certifies an inventory with a\n // hole in it.\n // Two kinds of gap, one flag. ENVIRONMENTAL gaps (unread, unscanned, unwalked) might close on a\n // re-run with different permissions; an INHERENT gap — a specifier computed at runtime — never will,\n // because no static pass can resolve it. Both make the inventory incomplete, so both clear the flag;\n // they are reported apart so a reviewer can tell \"try again\" from \"this app cannot be answered\n // statically\" instead of re-running against a permanent property of the source.\n const importCoverageGaps = {\n unreadableFiles: failed.length,\n unscannableFiles: importScanFailures,\n unwalkedPaths: stats.unwalked,\n unresolvableImports,\n };\n const environmentalGaps = failed.length + importScanFailures + stats.unwalked;\n const importsComplete = environmentalGaps === 0 && unresolvableImports === 0;\n notes.push('`imports` lists every package the app imports, from ALL source files — not only files holding an entry point. Absence of a SINK for a package is never evidence; absence of the PACKAGE is evidence only when coverage.importsComplete is true.');\n notes.push(`${unmodelled} of ${importList.length} imported package(s) have no recognized sink family (recognizedSinkKinds: []). The extractor models a small set of API families, so for those packages it cannot tell whether input reaches them: a vulnerability in one must stay \"needs review\" and can never be closed as unreachable using this map.`);\n if (environmentalGaps > 0) {\n notes.push(`The import inventory is INCOMPLETE: ${failed.length} file(s) could not be read, ${importScanFailures} could not be scanned, and ${stats.unwalked} path(s) could not be walked at all (unreadable directory, broken link, or a symlink leaving the project). A package may therefore be imported without appearing in \\`imports\\`. Do not read a package's absence as \"not imported\" while coverage.importsComplete is false.`);\n }\n if (unresolvableImports > 0) {\n notes.push(`The import inventory is INCOMPLETE for a reason no re-run can fix: ${unresolvableImports} import(s) do not name a resolvable module — either the specifier is computed at runtime (\\`require(REGISTRY[kind])\\`) or the loader itself was aliased (\\`const r = require\\`), so which package is loaded is not knowable from the source. Those imports appear NOWHERE in \\`imports\\` — not as an unresolved entry, simply absent — so a package's absence is not evidence of it being unused. This is a property of the application's code, not a scan failure. Reported conservatively: an aliased loader counts even if every call through it uses a literal.`);\n }\n\n const invocationList = invocations.list();\n if (invocationList.length > 0 || parsed > 0) {\n notes.push(`\\`apiInvocations\\` records ${invocationList.length} dependency API call(s) resolved from ${parsed} entry file(s) plus ${hopParsed} local module(s) they import directly. POSITIVE EVIDENCE ONLY: a package missing from it may still have its API called — see coverage.apiInventoryLimitations.`);\n }\n if (hopFailures > 0) {\n notes.push(`${hopFailures} local module(s) imported by an entry file could not be parsed, so any dependency call written in them is missing from \\`apiInvocations\\`.`);\n }\n\n // Node-only and best-effort: the map runs in a build, but the runtime this file belongs to must stay\n // edge-safe, so nothing here may assume `process`.\n //\n // Two numbers, because the obvious one is not the one a performance decision needs. `memoryUsage().rss`\n // is the resident size AT THIS MOMENT — after extraction, with the walk's garbage possibly already\n // collected — so calling it a peak would overstate what it measures. `resourceUsage().maxRSS` is a real\n // high-water mark, but for the whole process (it includes loading TypeScript), so it is an upper bound on\n // the cost of running `map` rather than extraction's own peak. Both are reported and both are labelled\n // for what they are.\n let rssBytes;\n let peakRssBytes;\n try {\n if (typeof process !== 'undefined') {\n if (typeof process.memoryUsage === 'function') rssBytes = process.memoryUsage().rss;\n if (typeof process.resourceUsage === 'function') {\n const maxRssKb = process.resourceUsage().maxRSS; // kilobytes, per Node's docs\n if (typeof maxRssKb === 'number' && maxRssKb > 0) peakRssBytes = maxRssKb * 1024;\n }\n }\n } catch { /* not available */ }\n\n const deploymentShapes = detectDeploymentShapes(cwd, { boundary, followOutside: options.followSymlinks });\n // Emitted UNCONDITIONALLY, and the empty case is the one that needs it most: an empty list is the only\n // state a consumer could read as \"this app has no server\", and a JSON reader sees none of the type\n // documentation that says otherwise. Attaching the caveat only when something was found put the warning\n // everywhere except the case it warns about.\n notes.push(deploymentShapes.length === 0\n ? '`deploymentShapes` is EMPTY: no deployment artifact was recognized. That is not evidence the app has no server-side runtime — a serverless handler this analysis cannot parse produces no endpoint and looks identical to an app that has none, and entry-point recognition has no completeness flag (coverage.importsComplete covers the import inventory only). A definitive answer needs deployment or build attestation, which source analysis cannot supply.'\n : `\\`deploymentShapes\\` records ${deploymentShapes.length} deployment artifact(s) the project declares (${deploymentShapes.map((s) => s.shape).join(', ')}). POSITIVE EVIDENCE ONLY, and findings differ in strength: only \\`runtime-entry\\` (a worker entry, or a provider function directory with source) shows something that serves. \\`deployment-config\\` means the project deploys to a platform — a static site on Netlify has a \\`netlify.toml\\` — and \\`layout\\` (a root \\`api/\\` or \\`functions/\\` folder) is an ordinary application folder. Neither may on its own be read as a server runtime.`);\n\n // Classified from what was positively found: the endpoints above, the deployment artifacts, and the\n // manifest. Emitted with its evidence and its own caveat, in every state — the `unknown` and static\n // states are the ones a consumer could over-read, so neither travels without the sentence that bounds it.\n const serverSurface = classifyServerSurface(cwd, endpoints.length, deploymentShapes, ts);\n notes.push(surfaceNote(serverSurface));\n\n return {\n version: 3,\n framework: detectFramework(cwd),\n deploymentShapes,\n serverSurface,\n endpoints,\n imports: importList,\n apiInvocations: invocationList,\n coverage: {\n adapter: 'agnostic-v1',\n filesDiscovered: stats.discovered,\n filesParsed: parsed,\n filesPreFiltered: preFiltered,\n filesHopParsed: hopParsed,\n filesSkipped: failed.length,\n pathsUnwalked: stats.unwalked,\n importsComplete,\n importCoverageGaps,\n apiInvocations: invocationList.length,\n callsTotal: calls.total,\n callsDependency: calls.dependency,\n callsLocal: calls.local,\n callsAmbiguous: calls.ambiguous,\n sourceBytes,\n analysisMs: Date.now() - startedAt,\n ...(rssBytes !== undefined ? { rssBytes } : {}),\n ...(peakRssBytes !== undefined ? { peakRssBytes } : {}),\n // The list IS the partiality statement. There is deliberately no `apiInventoryComplete`: parsing\n // every file would raise recall without removing any of these, so no parsing budget could make an\n // absent invocation mean \"not called\".\n apiInventoryLimitations: [\n 'only files carrying an entry-point signal, and the local modules they import directly, are parsed — a call two hops away is unseen',\n 'a computed callee or property (`client[name]()`) cannot be resolved to an API',\n 'a dynamic import()/require() with a non-literal specifier is not traced',\n 'reflection, generated code, and syntax that fails to parse are invisible',\n 'a receiver reached through more than one local hop, or through dependency injection, is not followed',\n ],\n roots: ['.'],\n notes,\n },\n };\n}\n\n\nfunction escapeRe(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// Re-exported so `./extract.js` stays the directory's entry point for consumers and tests.\nexport { runtimeCoordinate } from './coordinates.js';\nexport { functionNameFromPath, routeFromFilePath } from './routes.js';\nexport type { WalkStats } from './sources.js';\nexport type { ModuleGraph } from './sinks.js';\n","import type { TsModule } from './types.js';\n\n// Dependency-free AST helpers shared by every recognizer in this directory.\n\n// Leftmost identifier of a member/call chain (`supabase.from(x).insert` → \"supabase\", `fs.writeFile` → \"fs\").\n// `new` is part of a chain like any other link: `new Pool().query` roots at `Pool`, and so does\n// `function getDb() { return new Pool() }` — the shape a generated app uses for a database client. Omitting\n// it dropped the receiver entirely, which reads as \"not a dependency\" rather than \"not followed\".\nexport function rootIdentifier(node: any, ts: TsModule): string | undefined {\n let cur = node;\n while (cur) {\n if (ts.isIdentifier(cur)) return cur.text;\n if (ts.isPropertyAccessExpression(cur) || ts.isElementAccessExpression(cur) || ts.isCallExpression(cur) || ts.isNewExpression(cur) || ts.isNonNullExpression(cur) || ts.isParenthesizedExpression(cur) || ts.isAwaitExpression(cur)) {\n cur = cur.expression;\n } else return undefined;\n }\n return undefined;\n}\n\n// Source span of a node: the auditable coordinate, AND the sink's identity for flow analysis (a line is\n// not an identity — two sinks can share one, and an enclosing statement can hold unrelated expressions).\nexport function spanOf(node: any): { line?: number; start?: number; end?: number } {\n const out: { line?: number; start?: number; end?: number } = { line: lineOf(node) };\n try { out.start = node.getStart(); out.end = node.getEnd(); } catch { /* synthetic node */ }\n return out;\n}\n\n// 1-based line of a node in its source file — the auditable coordinate rules and humans point at.\nexport function lineOf(node: any): number | undefined {\n const sf = typeof node?.getSourceFile === 'function' ? node.getSourceFile() : undefined;\n if (!sf) return undefined;\n try { return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1; } catch { return undefined; }\n}\n\nexport function guessScriptKind(ts: TsModule, file: string) {\n if (file.endsWith('.tsx')) return ts.ScriptKind.TSX;\n if (file.endsWith('.jsx')) return ts.ScriptKind.JSX;\n if (file.endsWith('.js')) return ts.ScriptKind.JS;\n return ts.ScriptKind.TS;\n}\n\nexport function isFnLike(n: any, ts: TsModule): n is import('typescript').ArrowFunction | import('typescript').FunctionExpression {\n return ts.isArrowFunction(n) || ts.isFunctionExpression(n);\n}\nexport function hasExport(node: any, ts: TsModule): boolean {\n return Boolean(node.modifiers?.some((m: any) => m.kind === ts.SyntaxKind.ExportKeyword));\n}\n\n// --- call-chain + method ----------------------------------------------------\nexport function unwindChain(node: any, ts: TsModule): { baseName?: string; baseCall?: any; calls: Record<string, any> } {\n const calls: Record<string, any> = {};\n let cur = node;\n while (cur && ts.isCallExpression(cur)) {\n const callee = cur.expression;\n if (ts.isPropertyAccessExpression(callee)) { calls[callee.name.text] = cur; cur = callee.expression; }\n else if (ts.isIdentifier(callee)) return { baseName: callee.text, baseCall: cur, calls };\n else break;\n }\n return { calls };\n}\n\nexport function methodFromObjectArg(baseCall: any, ts: TsModule): string | undefined {\n const arg = baseCall?.arguments?.[0];\n if (!arg || !ts.isObjectLiteralExpression(arg)) return undefined;\n for (const p of arg.properties) {\n if (ts.isPropertyAssignment(p) && (p.name as any)?.text === 'method' && ts.isStringLiteralLike(p.initializer)) {\n return p.initializer.text.toUpperCase();\n }\n }\n return undefined;\n}\n\nexport function bindingKey(el: any, ts: TsModule): string | undefined {\n if (!ts.isBindingElement(el)) return undefined;\n const prop = el.propertyName ?? el.name;\n return prop && ts.isIdentifier(prop) ? prop.text : undefined;\n}\n\n// A named function *declaration*, or a function bound to a variable/property — i.e. code that only runs\n// if something calls it. An inline callback (an arrow passed as an argument), an IIFE, or a function\n// used directly in an expression is NOT this: those execute where they appear.\nexport function isUninvokedFunctionDeclaration(n: any, ts: TsModule): boolean {\n if (ts.isFunctionDeclaration(n)) return true;\n if (isFnLike(n, ts)) {\n const p = n.parent;\n if (p && (ts.isVariableDeclaration(p) || ts.isPropertyAssignment(p) || ts.isPropertyDeclaration(p))) return true;\n }\n return false;\n}\n\n/**\n * Is `name` bound by an enclosing function parameter (or catch clause) at this call site? If so the call\n * is NOT the global of that name — a callback parameter called `fetch` is the single most likely way to\n * fake an SSRF candidate. Scoped to parameters/catch bindings: cheap, and it covers the shadowing shapes\n * that occur in practice. Erring here loses a candidate rather than inventing one.\n */\nexport function isShadowedByEnclosingBinding(node: any, name: string, ts: TsModule): boolean {\n for (let cur = node?.parent; cur; cur = cur.parent) {\n if (ts.isCatchClause(cur) && cur.variableDeclaration && ts.isIdentifier(cur.variableDeclaration.name)\n && cur.variableDeclaration.name.text === name) return true;\n const params = (cur as any).parameters;\n if (!params) continue;\n for (const p of params) {\n if (!p?.name) continue;\n if (ts.isIdentifier(p.name) && p.name.text === name) return true;\n if (ts.isObjectBindingPattern(p.name) || ts.isArrayBindingPattern(p.name)) {\n for (const el of p.name.elements) {\n if (ts.isBindingElement(el) && ts.isIdentifier(el.name) && el.name.text === name) return true;\n }\n }\n }\n }\n return false;\n}\n\n/** Method name a call invokes (`db.from(t).insert(x)` → \"insert\", `exec(x)` → \"exec\"). */\nexport function calleeName(call: any, ts: TsModule): string | undefined {\n const c = call?.expression;\n if (!c) return undefined;\n if (ts.isPropertyAccessExpression(c)) return c.name.text;\n if (ts.isIdentifier(c)) return c.text; // also covers `new Function(...)`\n return undefined;\n}\n\n/** Is this identifier occurrence a VALUE read (rather than a property key, a member name, a binding)? */\nexport function isValueRead(id: any, ts: TsModule): boolean {\n const p = id.parent;\n if (!p) return true;\n if (ts.isPropertyAssignment(p) && p.name === id) return false; // { title: … } — a key\n if (ts.isPropertyAccessExpression(p) && p.name === id) return false; // x.title — the member name\n if (ts.isBindingElement(p) && p.propertyName === id) return false; // { title: t } — the source key\n if ((ts.isVariableDeclaration(p) || ts.isParameter(p) || ts.isBindingElement(p)) && p.name === id) return false;\n if (ts.isPropertySignature(p) || ts.isMethodSignature(p)) return false;\n return true; // includes ShorthandPropertyAssignment `{ title }`, which IS a read\n}\n\n// From a `.insert` property access, the CallExpression that invokes it — the sink's operation call.\nexport function opCallOf(propAccess: any, ts: TsModule): any {\n const p = propAccess?.parent;\n return p && ts.isCallExpression(p) && p.expression === propAccess ? p : propAccess;\n}\n\nexport function localCalls(node: any, ts: TsModule): string[] {\n const names: string[] = [];\n const visit = (n: any) => {\n if (ts.isCallExpression(n) && ts.isIdentifier(n.expression)) names.push(n.expression.text);\n ts.forEachChild(n, visit);\n };\n visit(node);\n return names;\n}\n","import { builtinModules } from 'node:module';\nimport type { TsModule } from './types.js';\nimport { isFnLike, isUninvokedFunctionDeclaration, rootIdentifier } from './ast.js';\n\nconst BUILTINS = new Set(builtinModules);\n\n// Per-file module bindings: resolve a local identifier to the npm package (or node: builtin) it came\n// from — directly (an import), or via `const x = <importedFn|new ImportedClass>(...)` /\n// `const x = require('mod')`; derived names resolve transitively (`const conn = pool.promise()`).\n// `imports` is every module specifier the file imports (for the fallback). `locals` is every name\n// declared in-file that does NOT trace to a module — calls on those receivers are not dependency\n// sinks. (Names assigned outside their declaration, e.g. `let fs; fs = require('fs')`, are treated\n// as local — an accepted miss.)\nexport interface Bindings {\n resolve(name: string): string | undefined;\n /** For `import { saveOrder as write }`, maps the local name back to the EXPORTED name. */\n exportNameOf(name: string): string | undefined;\n /**\n * HOW a name reached its package: `direct` from an import/require declaration, `factory` through a\n * traced call chain (`const db = createClient(...)`, `const conn = pool.promise()`).\n *\n * Recorded rather than inferred because the API inventory reports it as evidence: \"this call is on a\n * value we followed through a factory\" is a weaker claim than \"this call is on an imported binding\",\n * and a consumer deciding what to act on needs to tell them apart.\n */\n originOf(name: string): 'direct' | 'factory' | undefined;\n /**\n * Whether the name is a NAMED MEMBER of its package (`import { Pool } from 'pg'`,\n * `const { parse } = require('json5')`) rather than the module object itself (`import * as fs`,\n * `import JSON5 from 'json5'`, `const JSON5 = require('json5')`).\n *\n * Both are `direct`, but only the member's name belongs to the package. A module object's local name is\n * the app's invention — the same require is written `JSON5`, `J5`, or `json5` in three codebases — so it\n * is not a name any advisory can be matched against.\n */\n isPackageMember(name: string): boolean;\n imports: Set<string>;\n locals: Set<string>;\n}\nexport function buildModuleBindings(sf: any, ts: TsModule): Bindings {\n const nameToModule = new Map<string, string>(); // local name → module specifier\n const declared = new Set<string>(); // every name declared in this file\n const exportNames = new Map<string, string>(); // local alias → exported name\n const members = new Set<string>(); // names bound to a NAMED export, not to the module object\n const imports = new Set<string>();\n const origins = new Map<string, 'direct' | 'factory'>();\n\n const record = (local: string, mod: string, origin: 'direct' | 'factory' = 'direct') => {\n nameToModule.set(local, mod);\n imports.add(mod);\n if (!origins.has(local)) origins.set(local, origin);\n };\n const declareBound = (nameNode: any) => {\n if (ts.isIdentifier(nameNode)) declared.add(nameNode.text);\n else if (ts.isObjectBindingPattern(nameNode) || ts.isArrayBindingPattern(nameNode)) {\n for (const el of nameNode.elements) if (ts.isBindingElement(el) && ts.isIdentifier(el.name)) declared.add(el.name.text);\n }\n };\n\n const visit = (node: any) => {\n // import … from 'mod'\n if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteralLike(node.moduleSpecifier)) {\n const mod = node.moduleSpecifier.text;\n imports.add(mod);\n const clause = node.importClause;\n if (clause?.name) record(clause.name.text, mod); // default\n const nb = clause?.namedBindings;\n if (nb) {\n if (ts.isNamespaceImport(nb)) record(nb.name.text, mod);\n else if (ts.isNamedImports(nb)) for (const el of nb.elements) {\n record(el.name.text, mod);\n members.add(el.name.text);\n // `import { saveOrder as write }` — looking up `write` in the target module would miss.\n if (el.propertyName && ts.isIdentifier(el.propertyName)) exportNames.set(el.name.text, el.propertyName.text);\n }\n }\n }\n if (ts.isFunctionDeclaration(node) && node.name) declared.add(node.name.text);\n if (ts.isClassDeclaration(node) && node.name) declared.add(node.name.text);\n // const x = require('mod') / const { a } = require('mod')\n if (ts.isVariableStatement(node)) {\n for (const decl of node.declarationList.declarations) {\n declareBound(decl.name);\n const init = decl.initializer;\n const reqMod = requireSpecifier(init, ts);\n if (reqMod) {\n if (ts.isIdentifier(decl.name)) record(decl.name.text, reqMod);\n else if (ts.isObjectBindingPattern(decl.name)) for (const el of decl.name.elements) if (ts.isIdentifier(el.name)) {\n record(el.name.text, reqMod);\n members.add(el.name.text);\n // `const { merge: deepMerge } = require(\"lodash\")` — the CommonJS twin of an import alias.\n // Without this the local alias looks like the package's own export name, and reporting it as\n // one invents an API the package does not have.\n if (el.propertyName && ts.isIdentifier(el.propertyName)) exportNames.set(el.name.text, el.propertyName.text);\n }\n }\n // const x = tracedFactory(...) / const x = new TracedClass(...) → x carries that package.\n // Looking up nameToModule (not just direct imports) makes this transitive: pool → conn → ….\n // Recorded as pending too, so a factory resolved LATER (a local wrapper, below) still binds x.\n if (init && ts.isIdentifier(decl.name)) {\n const callee = ts.isCallExpression(init) ? init.expression : ts.isNewExpression(init) ? init.expression : undefined;\n const root = callee ? rootIdentifier(callee, ts) : undefined;\n if (root) {\n pending.push([decl.name.text, root]);\n if (nameToModule.has(root)) record(decl.name.text, nameToModule.get(root)!, 'factory');\n }\n }\n }\n }\n // A LOCAL factory that hands back a dependency object: `function getClient() { return createClient(…) }`.\n // Without this, `const supabase = getClient()` looks like a plain local and every sink on it is\n // dropped as \"not a dependency\" — silently losing the real client (the common AI-generated shape).\n if ((ts.isFunctionDeclaration(node) || isFnLike(node, ts)) && node.body) {\n const fnName = ts.isFunctionDeclaration(node) && node.name\n ? node.name.text\n : ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)\n ? node.parent.name.text\n : undefined;\n if (fnName) {\n const root = returnedRootIdentifier(node.body, ts);\n if (root) pending.push([fnName, root]);\n }\n }\n ts.forEachChild(node, visit);\n };\n const pending: Array<[string, string]> = []; // [localName, rootIdentifierItCameFrom]\n visit(sf);\n // Fixpoint: resolve chains like createClient → getClient → supabase (bounded; order-independent).\n for (let i = 0; i < 4; i++) {\n let changed = false;\n for (const [name, root] of pending) {\n if (!nameToModule.has(name) && nameToModule.has(root)) { record(name, nameToModule.get(root)!, 'factory'); changed = true; }\n }\n if (!changed) break;\n }\n const locals = new Set([...declared].filter((n) => !nameToModule.has(n)));\n return {\n resolve: (name: string) => nameToModule.get(name),\n exportNameOf: (name: string) => exportNames.get(name),\n originOf: (name: string) => origins.get(name),\n isPackageMember: (name: string) => members.has(name),\n imports,\n locals,\n };\n}\n\n// Root identifier of what a function body returns (`return createClient(…)` → \"createClient\"), for\n// following a local factory to the dependency it wraps. Concise arrow bodies are the expression itself.\nfunction returnedRootIdentifier(body: any, ts: TsModule): string | undefined {\n if (!ts.isBlock(body)) return rootIdentifier(body, ts); // concise arrow body\n let found: string | undefined;\n const visit = (n: any) => {\n if (found) return;\n if (isUninvokedFunctionDeclaration(n, ts) && n !== body) return; // don't read a nested fn's return\n if (ts.isReturnStatement(n) && n.expression) { found = rootIdentifier(n.expression, ts); return; }\n ts.forEachChild(n, visit);\n };\n visit(body);\n return found;\n}\n\nfunction requireSpecifier(init: any, ts: TsModule): string | undefined {\n if (init && ts.isCallExpression(init) && ts.isIdentifier(init.expression) && init.expression.text === 'require') {\n const a = init.arguments[0];\n if (a && ts.isStringLiteralLike(a)) return a.text;\n }\n return undefined;\n}\n\n// Normalize a module specifier to its npm package root (keep scope, drop subpath). Node builtins are\n// normalized to the `node:` form even when imported bare (`import fs from 'fs'`) — there IS an npm\n// package named `fs`, and CVE correlation must never confuse the two. Relative paths → undefined.\nexport function npmPackageOf(spec: string | undefined): string | undefined {\n if (!spec) return undefined;\n if (spec.startsWith('.') || spec.startsWith('/')) return undefined;\n if (spec.startsWith('node:')) return spec;\n if (BUILTINS.has(spec)) return `node:${spec}`;\n const parts = spec.split('/');\n return spec.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0];\n}\n","import { readFileSync, readdirSync, realpathSync, statSync } from 'node:fs';\nimport { join, relative, isAbsolute } from 'node:path';\nimport { ROUTE_CALL_RE } from './routes.js';\nimport type { DeploymentEvidence, DeploymentShape } from './types.js';\n\n// Cheap textual pre-filter so we only parse files that could contain an entry point. Derived from the\n// same list as the AST recognizer (see ROUTE_REGISTER_NAMES).\nexport function hasEntrySignal(text: string): boolean {\n return (\n text.includes('createServerFn') ||\n /\\bexport\\s+(async\\s+)?(function|const)\\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b/.test(text) ||\n ROUTE_CALL_RE.test(text) ||\n text.includes(\"'use server'\") || text.includes('\"use server\"') ||\n text.includes('Deno.serve') || /\\bserve\\s*\\(/.test(text)\n );\n}\n\nexport function detectFramework(cwd: string): string {\n try {\n const pkg = JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8'));\n const d = { ...pkg.dependencies, ...pkg.devDependencies };\n if (d['@tanstack/react-start'] || d['@tanstack/start'] || d['@tanstack/solid-start']) return 'tanstack-start';\n if (d['next']) return 'next';\n if (d['@sveltejs/kit']) return 'sveltekit';\n if (d['@nestjs/core']) return 'nestjs';\n if (d['fastify']) return 'fastify';\n if (d['express']) return 'express';\n if (d['hono']) return 'hono';\n } catch { /* ignore */ }\n // A Deno/edge functions project may have no package.json at all.\n try {\n if (statSync(join(cwd, 'supabase', 'functions')).isDirectory()) return 'supabase-functions';\n } catch { /* not a supabase project */ }\n try {\n if (statSync(join(cwd, 'functions')).isDirectory()) return 'deno-functions';\n } catch { /* ignore */ }\n return 'unknown';\n}\n\nconst isSourceFile = (name: string) => /\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/.test(name) && !name.endsWith('.d.ts');\n\n// Directories that never hold app source, so walking the whole project stays cheap. (We walk the whole\n// project rather than `src` only: server entrypoints, route dirs and platform function dirs commonly\n// live at the root — `server.ts`, `app/`, `api/`, `routes/`, `functions/`, `netlify/`, `supabase/`.)\nconst SKIP_DIRS = new Set([\n 'node_modules', 'dist', 'build', 'out', 'coverage', 'public', 'static', 'assets',\n '.git', '.next', '.nuxt', '.svelte-kit', '.output', '.vercel', '.wrangler', '.turbo', '.cache',\n 'vendor', 'tmp', 'temp', '__pycache__',\n]);\n\nexport interface WalkStats {\n discovered: number;\n /**\n * Directories or links the walk could not traverse (permissions, a broken link, a vanished path) plus\n * subtrees deliberately left unvisited because a symlink escapes the project.\n *\n * These never become \"files\", so nothing downstream can notice them by counting: an unreadable\n * directory simply makes the tree look smaller. That is fine for the surface view and NOT fine for the\n * import inventory, whose whole value is that a package's absence means something — an unwalked subtree\n * can import anything. Any non-zero value here forfeits that claim.\n */\n unwalked: number;\n}\n\n/**\n * Walk the project for source files. Symlinks are followed ONLY while they stay inside the project\n * boundary (`boundary`, a realpath) — a link to an external repo would otherwise pull unrelated code\n * (and its paths) into the map. `followOutside` opts out of the boundary check. A realpath visited-set\n * makes link cycles safe.\n */\nexport function collectSources(\n dir: string,\n boundary: string,\n opts: { followOutside?: boolean },\n out: string[] = [],\n seen = new Set<string>(),\n stats: WalkStats = { discovered: 0, unwalked: 0 },\n): string[] {\n let key: string;\n try { key = realpathSync(dir); } catch { stats.unwalked++; return out; }\n if (seen.has(key)) return out; // already walked via another path — not a gap\n if (!opts.followOutside && !isInside(key, boundary)) { stats.unwalked++; return out; }\n seen.add(key);\n let entries;\n try { entries = readdirSync(dir, { withFileTypes: true }); } catch { stats.unwalked++; return out; }\n // Directory order is filesystem-dependent (APFS and ext4 disagree), and it decides the order of\n // endpoints and import sites in the document. Sorting makes the same tree produce the same bytes on\n // any machine — otherwise a rebuild in CI looks like a changed app and cuts a pointless new revision.\n entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n for (const e of entries) {\n if (SKIP_DIRS.has(e.name) || (e.name.startsWith('.') && e.name !== '.')) continue;\n const full = join(dir, e.name);\n if (e.isDirectory()) collectSources(full, boundary, opts, out, seen, stats);\n else if (e.isSymbolicLink()) {\n let st, real;\n try { st = statSync(full); real = realpathSync(full); } catch { stats.unwalked++; continue; }\n // The link escapes the project: deliberate, but still a part of the tree we did not read, so it\n // counts against the inventory's completeness exactly like a failure would — but only when it\n // could have held source. A symlinked README outside the project must not forfeit the claim.\n if (!opts.followOutside && !isInside(real, boundary)) {\n if (st.isDirectory() || isSourceFile(e.name)) stats.unwalked++;\n continue;\n }\n if (st.isDirectory()) collectSources(full, boundary, opts, out, seen, stats);\n else if (st.isFile() && isSourceFile(e.name)) { out.push(full); stats.discovered++; }\n } else if (isSourceFile(e.name)) { out.push(full); stats.discovered++; }\n }\n return out;\n}\n\nexport function isInside(candidate: string, boundary: string): boolean {\n if (candidate === boundary) return true;\n const rel = relative(boundary, candidate);\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel);\n}\n\n// --- deployment shapes ------------------------------------------------------\n// What the PROJECT says about where it runs, as opposed to what its source says it does.\n//\n// The two answers come apart in the direction that matters. A project can hold a serverless function\n// this extractor cannot parse — an unfamiliar handler signature, a runtime it does not model — and the\n// endpoint walk then reports nothing, which is indistinguishable from an app that has no server at all.\n// A consumer reading only `endpoints: []` would call that app static and tell its owner there is nothing\n// to protect.\n//\n// So these are POSITIVE artifacts: a config file or a platform directory that exists. Each finding names\n// the thing that proved it, because a classification a consumer cannot explain is one it should not act\n// on — and the absence of every shape below is still not evidence of absence, only of \"we found none\".\n//\n// Findings are not equally strong, and the difference is carried in the data rather than left for a\n// consumer to rediscover:\n//\n// runtime-entry code that SERVES — a worker entry, or a provider function directory with source\n// deployment-config the project deploys to a platform, which says nothing about anything serving\n// layout an ordinary application folder that MIGHT be functions (`api/`, `functions/`)\n//\n// The `deployment-config` line is the one worth being careful about: a static site on Netlify has a\n// `netlify.toml`, a static Vercel project has a `vercel.json`, and a Pages project deploying only assets\n// has a `wrangler.toml`. Reading any of those as a server runtime would classify a large share of purely\n// static apps as having one — so they establish \"deploys somewhere\", nothing more.\n//\n// `layout` exists because `api/client.ts` is a perfectly normal front-end folder and `api/handler.ts` is a\n// Vercel function, and from the outside they are the same directory name.\n//\n// A classifier may use `deployment-config` and `layout` to stay UNDECIDED; neither may conclude a runtime.\n//\n// `DeploymentEvidence` and `DeploymentShape` are imported from `types.ts` rather than restated: they are the\n// document's contract, and two structural copies of a vocabulary is how the two drift apart later.\ninterface ShapeCandidate {\n shape: string;\n evidence: DeploymentEvidence;\n files?: string[];\n dirs?: string[];\n /**\n * Require the per-function directory layout (`<name>/index.ts`) rather than any source underneath.\n *\n * Supabase needs this: the convention puts shared code in `supabase/functions/_shared/*.ts`, which the\n * platform does not deploy and which exists in projects with no deployed function at all. Counting it\n * would report a runtime for a project that serves nothing — and this signal is the one the product\n * messaging leans on, so a false positive here is a wrong statement to a customer.\n */\n requiresFunctionEntry?: boolean;\n}\n\nconst DEPLOYMENT_SHAPES: ShapeCandidate[] = [\n // Config first: these are declarations by the project itself, and they survive a build output being\n // absent (a fresh clone has no `.vercel`/`.wrangler` directory).\n { shape: 'vercel', evidence: 'deployment-config', files: ['vercel.json'] },\n { shape: 'netlify', evidence: 'deployment-config', files: ['netlify.toml'] },\n // Wrangler names a Workers/Pages deployment. `.jsonc` and `.json` are both current spellings.\n { shape: 'cloudflare-workers', evidence: 'deployment-config', files: ['wrangler.toml', 'wrangler.jsonc', 'wrangler.json'] },\n // Pages advanced mode: a single worker entry at the project root takes over routing entirely. Unlike a\n // wrangler config, this file IS the server — it is a runtime entry, not a deployment declaration.\n { shape: 'cloudflare-pages-advanced', evidence: 'runtime-entry', files: ['_worker.js', '_worker.ts'] },\n { shape: 'netlify-functions', evidence: 'runtime-entry', dirs: ['netlify/functions', 'netlify/edge-functions'] },\n { shape: 'supabase-functions', evidence: 'runtime-entry', dirs: ['supabase/functions'], requiresFunctionEntry: true },\n // Ambiguous by nature and reported as one shape: a root `functions/` directory is Cloudflare Pages\n // Functions, Firebase functions, or a Deno layout depending on the platform, and nothing inside the\n // repository always distinguishes them. Naming it honestly is better than guessing a provider.\n { shape: 'root-functions-directory', evidence: 'layout', dirs: ['functions'] },\n // The bare-root Vercel convention: `api/handler.ts` with no framework router. Next owns `pages/api`\n // and `app/api` instead, which the endpoint walk already recognizes, so this is reported as its own\n // shape rather than folded into `vercel`.\n { shape: 'root-api-directory', evidence: 'layout', dirs: ['api'] },\n];\n\nexport interface DeploymentScanOptions {\n /** Project boundary (a real path). Candidates resolving outside it are refused. */\n boundary?: string;\n /** Follow artifacts that resolve outside the project (off by default, like the source walk). */\n followOutside?: boolean;\n}\n\n/**\n * Deployment artifacts present in the project, each with the file or directory that evidenced it.\n *\n * Cheap by construction: a handful of `statSync` calls at known paths, no walking. Never throws — an\n * unreadable project yields an empty list, which is a \"found none\" and must not be read as \"has none\".\n *\n * Symlinks are resolved and refused when they leave the project, the same rule the source walk applies. A\n * symlinked `api/` pointing at a sibling workspace would otherwise become THIS project's deployment\n * evidence — the analysis would describe a runtime that belongs to different code.\n */\nexport function detectDeploymentShapes(cwd: string, opts: DeploymentScanOptions = {}): DeploymentShape[] {\n let boundary = opts.boundary ?? cwd;\n try { boundary = realpathSync(boundary); } catch { /* use as given */ }\n\n const inProject = (path: string): boolean => {\n if (opts.followOutside) return true;\n try {\n return isInside(realpathSync(path), boundary);\n } catch {\n return false; // unresolvable is not in-project, and not evidence\n }\n };\n\n const found: DeploymentShape[] = [];\n\n for (const candidate of DEPLOYMENT_SHAPES) {\n for (const file of candidate.files ?? []) {\n const full = join(cwd, file);\n try {\n if (statSync(full).isFile() && inProject(full)) {\n found.push({ shape: candidate.shape, source: file, evidence: candidate.evidence });\n break; // one spelling is enough; the shape is the claim, not the filename\n }\n } catch { /* not this one */ }\n }\n\n for (const dir of candidate.dirs ?? []) {\n const full = join(cwd, dir);\n\n // Containment is settled BEFORE anything reads the directory. `statSync` follows symlinks, so a\n // linked `api/` reports as a directory here — and inspecting its contents first would mean this\n // analysis had already read a tree outside the project, whatever it then did with the result. The\n // guarantee is \"we do not look\", not \"we look and discard\".\n try {\n if (!statSync(full).isDirectory() || !inProject(full)) continue;\n } catch {\n continue; // missing, or unresolvable — either way not evidence\n }\n\n // A directory with no source file in it is scaffolding, not a deployment: an empty `api/` would\n // otherwise make every project that once considered serverless look like it ships it.\n if (candidate.requiresFunctionEntry ? holdsFunctionEntry(full) : holdsSourceFile(full)) {\n found.push({ shape: candidate.shape, source: dir, evidence: candidate.evidence });\n break;\n }\n }\n }\n\n return found;\n}\n\n/**\n * Whether a directory holds at least one deployable FUNCTION, in the per-function layout: a child directory\n * whose name does not start with `_`, containing an `index.*` source file.\n *\n * Only ever called for a directory the caller has already confirmed is inside the project.\n *\n * The underscore rule is the platform's own: Supabase treats `supabase/functions/_shared/` as shared code\n * and does not deploy it, so a project can have that directory full of TypeScript and serve nothing.\n */\nfunction holdsFunctionEntry(dir: string): boolean {\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isDirectory() || entry.name.startsWith('_')) continue;\n try {\n for (const nested of readdirSync(join(dir, entry.name), { withFileTypes: true })) {\n if (nested.isFile() && /^index\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/.test(nested.name)) return true;\n }\n } catch { /* unreadable candidate */ }\n }\n } catch { /* unreadable */ }\n\n return false;\n}\n\n/**\n * Whether a directory holds at least one source file, one level down included.\n *\n * No boundary check here, and deliberately not: `readdirSync(withFileTypes)` classifies a symlink as\n * neither a file nor a directory, so a linked entry can never satisfy either branch and cannot smuggle\n * outside code into this test. Every entry that reaches a `return true` is a real file at a real path\n * under `dir`, which the caller has already confirmed is in-project.\n *\n * (A first version did check the boundary at each hop. It was unreachable — verified by removing the\n * top-level refusal, which failed the escaping-directory tests while the nested one stayed green.)\n *\n * The accepted cost is a legitimate in-project symlink inside a provider directory not counting as\n * source. That errs toward reporting no shape, which the map already states is not evidence of absence.\n */\nfunction holdsSourceFile(dir: string): boolean {\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.isFile() && isSourceFile(entry.name)) return true;\n // One level deeper covers the per-function layout (`netlify/functions/hello/index.ts`) without\n // turning this into a walk.\n if (entry.isDirectory()) {\n try {\n for (const nested of readdirSync(join(dir, entry.name), { withFileTypes: true })) {\n if (nested.isFile() && isSourceFile(nested.name)) return true;\n }\n } catch { /* unreadable subdirectory */ }\n }\n }\n } catch { /* unreadable */ }\n\n return false;\n}\n","import type { TsModule } from './types.js';\nimport { isFnLike } from './ast.js';\n\n// One list drives BOTH the AST route-registration recognizer and the textual pre-filter — they must\n// never diverge: a file the pre-filter skips is invisible to every recognizer.\nconst ROUTE_REGISTER_NAMES = ['get', 'post', 'put', 'patch', 'delete', 'options', 'all', 'head', 'use'];\nexport const ROUTE_REGISTER = new Set(ROUTE_REGISTER_NAMES);\nexport const ROUTE_CALL_RE = new RegExp(`\\\\.(${[...ROUTE_REGISTER_NAMES, 'route'].join('|')})\\\\s*\\\\(`);\n\n// Derive the URL path of a FILE-BASED route handler from its location, across the conventions AI\n// builders actually emit. Dynamic segments become `:name` and set `dynamic` so a consumer knows the\n// route is a PATTERN (the engine's `when.path` takes a glob or /regex/, not an Express param), rather\n// than mistaking `/api/:id` for a literal path.\n// Next App Router app/api/items/route.ts -> /api/items\n// app/api/items/[id]/route.ts -> /api/items/:id (dynamic)\n// app/(marketing)/api/x/route.ts -> /api/x (route group stripped)\n// Next Pages Router pages/api/items/index.ts -> /api/items\n// pages/api/[id].ts -> /api/:id (dynamic)\n// SvelteKit src/routes/api/items/+server.ts -> /api/items\n// Nuxt server/api/items.post.ts -> /api/items\n// The deployed name of a platform function, from its conventional location:\n// supabase/functions/<name>/index.ts (Supabase Edge Functions)\n// functions/<name>/index.ts | functions/<name>.ts (Base44 / generic Deno function dirs)\nexport function functionNameFromPath(relFile: string): string | undefined {\n const parts = relFile.split(/[\\\\/]/).filter(Boolean);\n const i = parts.lastIndexOf('functions');\n if (i === -1 || i === parts.length - 1) return undefined;\n const next = parts[i + 1];\n if (!next) return undefined;\n const base = next.replace(/\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/, '');\n return base === 'index' ? undefined : base;\n}\n\nexport function routeFromFilePath(relFile: string): { route?: string; dynamic?: boolean } {\n const parts = relFile.split(/[\\\\/]/).filter(Boolean);\n if (parts.length === 0) return {};\n const base = (parts[parts.length - 1] ?? '').replace(/\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/, '');\n const dirs = parts.slice(0, -1);\n const at = (name: string) => dirs.lastIndexOf(name);\n\n let segs: string[] | null = null;\n if (base === 'route' && at('app') !== -1) {\n segs = dirs.slice(at('app') + 1); // Next App Router\n } else if (base === '+server' && at('routes') !== -1) {\n segs = dirs.slice(at('routes') + 1); // SvelteKit\n } else if (at('pages') !== -1) {\n segs = [...dirs.slice(at('pages') + 1), ...(base === 'index' ? [] : [base])]; // Next Pages Router\n } else if (at('server') !== -1) {\n // Nuxt server routes; a `.post`/`.get` suffix encodes the method, not a path segment.\n segs = [...dirs.slice(at('server') + 1), ...(base === 'index' ? [] : [base.replace(/\\.(get|post|put|patch|delete|head|options)$/i, '')])];\n }\n if (!segs) return {};\n\n // Next route groups `(marketing)` and parallel/private segments don't appear in the URL.\n segs = segs.filter((s) => !(s.startsWith('(') && s.endsWith(')')) && !s.startsWith('@') && !s.startsWith('_'));\n\n let dynamic = false;\n const mapped = segs.map((s) => {\n const m = /^\\[+(\\.{0,3})(.+?)\\]+$/.exec(s); // [id], [...slug], [[...slug]]\n if (m) {\n dynamic = true;\n return ':' + m[2];\n }\n return s;\n });\n const route = '/' + mapped.join('/');\n return { route: route.length > 1 ? route.replace(/\\/+$/, '') : '/', dynamic };\n}\n\n// Unwind `router.route('/x').get(h).post(h2)` down to the `.route('/x')` call to recover the path.\nexport function routeFromChain(expr: any, ts: TsModule): string | undefined {\n let cur = expr;\n while (cur && ts.isCallExpression(cur) && ts.isPropertyAccessExpression(cur.expression)) {\n const nm = cur.expression.name.text;\n if (nm === 'route') {\n const a = cur.arguments[0];\n return a && ts.isStringLiteralLike(a) ? a.text : undefined;\n }\n if (!ROUTE_REGISTER.has(nm)) return undefined;\n cur = cur.expression.expression;\n }\n return undefined;\n}\n\n// Read `{ method, url|path, handler }` from a Fastify-style route object (handler as arrow/function\n// property or as an object-method shorthand).\nexport function routeObject(obj: any, ts: TsModule): { url?: string; methods: string[]; handler?: any } {\n let url: string | undefined;\n let handler: any;\n const methods: string[] = [];\n for (const p of obj.properties) {\n const key = (p.name as any)?.text;\n if (ts.isPropertyAssignment(p)) {\n if ((key === 'url' || key === 'path') && ts.isStringLiteralLike(p.initializer)) url = p.initializer.text;\n if (key === 'method') {\n if (ts.isStringLiteralLike(p.initializer)) methods.push(p.initializer.text.toUpperCase());\n else if (ts.isArrayLiteralExpression(p.initializer)) {\n for (const el of p.initializer.elements) if (ts.isStringLiteralLike(el)) methods.push(el.text.toUpperCase());\n }\n }\n if (key === 'handler' && isFnLike(p.initializer, ts)) handler = p.initializer;\n } else if (ts.isMethodDeclaration(p) && key === 'handler') handler = p;\n }\n return { url, methods, handler };\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { DeploymentShape, ServerSurface, SurfaceSignal, TsModule } from './types.js';\n\n// Does this app have a server side at all?\n//\n// The question is worth answering because the answer changes what protection MEANS: an app with no server\n// runtime cannot run a request guard, so its advisories are dependency and bundle hygiene rather than\n// request-path risk. Told plainly, that is useful. Told wrongly, it is the worst output this analysis can\n// produce — \"nothing to protect here\" on an app we simply failed to read.\n//\n// So the classification is built from POSITIVE signals on both sides, and the honest answer is usually\n// neither:\n//\n// server-runtime-detected a recognized endpoint, or an artifact that SERVES (a worker entry, a provider\n// function directory with source)\n// static-build-detected a static generator identified AND nothing suggesting a server surface\n// unknown everything else — including \"we found nothing and cannot say why\"\n//\n// A deployment CONFIG is not in that first list, and that is the correction that matters most here: a static\n// site on Netlify has a `netlify.toml`, a static Vercel project has a `vercel.json`, and a Pages project\n// serving only assets has a `wrangler.toml`. Reading those as a runtime would have classified a large share\n// of purely static apps as having a server. They stay visible in the evidence and they still rule out a\n// confident static claim — a project that deploys somewhere is not one this analysis can call server-free —\n// but the answer with nothing else behind it is `unknown`.\n//\n// Three rules keep `static-build-detected` from becoming the default for an unrecognised stack:\n//\n// 1. It needs a static generator NAMED. Absence of server signals is not evidence; `endpoints: []` is\n// what an unparsed framework looks like, and entry-point recognition has no completeness flag.\n// 2. A server-framework dependency blocks it. An app with `express` installed and no endpoint we could\n// read is a parsing gap, not a static site.\n// 3. Any deployment shape blocks it — config and `layout` included. A root `api/` folder holding source\n// may be a front-end helper or a pile of platform functions, and from here they are the same folder.\n// That ambiguity belongs in `unknown`, not in a claim either way.\n//\n// Even `static-build-detected` is not deployment attestation: it says the source describes a static build,\n// not that nothing server-side is deployed. Only build or platform metadata can carry that, and this\n// analysis never sees it.\n\n/** Dependencies that build a static bundle and, on their own, no server. */\nconst STATIC_GENERATORS: Array<{ dep: string; label: string }> = [\n { dep: 'vite', label: 'vite' },\n { dep: 'react-scripts', label: 'create-react-app' },\n { dep: 'gatsby', label: 'gatsby' },\n { dep: 'parcel', label: 'parcel' },\n { dep: '@sveltejs/adapter-static', label: 'sveltekit-static-adapter' },\n];\n\n/**\n * Build tools that turn a static bundler into an SSR stack.\n *\n * Vite is the awkward one: it is the default bundler for client-only apps AND the foundation of several\n * server frameworks, so `vite` in a manifest is not by itself a static build. Anything here vetoes the\n * static reading and leaves the app `unknown`, which is the conservative direction for a state whose product\n * meaning is \"no request-path protection needed\".\n */\nconst SSR_COMPANIONS = ['vike', 'vite-plugin-ssr', '@react-router/node', '@react-router/serve', 'vite-plugin-node'];\n\n/**\n * Dependencies that mean a server, so a static claim is off the table.\n *\n * Deliberately wider than the framework detector: this list only has to answer \"might this app serve\n * requests\", and over-answering yes costs a claim we would rather not make anyway.\n */\nconst SERVER_DEPENDENCIES = [\n 'express', 'fastify', 'hono', 'koa', '@nestjs/core', '@hapi/hapi', 'h3', 'polka', 'restify',\n '@tanstack/react-start', '@tanstack/start', '@tanstack/solid-start', 'nuxt', 'remix',\n '@remix-run/node', '@remix-run/server-runtime',\n];\n\n/**\n * Frameworks that ship BOTH modes, where another dependency decides which one this project is.\n *\n * `@sveltejs/kit` is the case that made this necessary: every static SvelteKit app has it alongside\n * `@sveltejs/adapter-static`, so treating kit as an unconditional server dependency made a real static\n * SvelteKit project permanently `unknown` — and the test that \"proved\" the adapter worked installed the\n * adapter with no kit, which is not a package set anyone ships.\n */\nconst CONDITIONAL_SERVER_DEPENDENCIES: Array<{ dep: string; staticWhen: string }> = [\n { dep: '@sveltejs/kit', staticWhen: '@sveltejs/adapter-static' },\n];\n\n/** Astro and Next ship both modes, so the adapter or the output setting decides. */\nconst SSR_ADAPTERS = ['@astrojs/node', '@astrojs/vercel', '@astrojs/cloudflare', '@astrojs/netlify', '@astrojs/deno'];\n\n/** How each deployment-evidence level appears in the surface evidence list. */\nconst SHAPE_SIGNAL: Record<DeploymentShape['evidence'], SurfaceSignal['signal']> = {\n 'runtime-entry': 'runtime-entry',\n 'deployment-config': 'deployment-config',\n layout: 'ambiguous-layout',\n};\n\ninterface Manifest {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n}\n\nfunction readManifest(cwd: string): Manifest | null {\n try {\n const parsed = JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8'));\n\n return typeof parsed === 'object' && parsed !== null ? parsed as Manifest : null;\n } catch {\n return null; // no manifest, or unreadable — either way nothing is identified from it\n }\n}\n\n/**\n * Whether a Next project is configured to emit a static export rather than run a server.\n *\n * The config is PARSED, not pattern-matched. A regex over the file text accepts\n * `// output: 'export'`, the same words inside a string, and an example block nobody exports — and each of\n * those would have reclassified an ordinary server-mode Next app as static, which is the direction that\n * loses protection. Parsing is also not the same as executing: the AST is read, the config never runs.\n *\n * Only a value reachable from the module's export counts, so dead code declaring `output: 'export'` is\n * ignored too. The wrapper form (`withPlugins(config)`, `withMDX({...})`) is followed one level, since it\n * is how most real Next configs are written.\n */\nfunction nextExportsStatically(cwd: string, manifest: Manifest, ts: TsModule | undefined): string | null {\n const scripts = Object.values(manifest.scripts ?? {}).join(' ');\n // Scripts are JSON strings — no comments to be fooled by.\n if (/\\bnext\\s+export\\b/.test(scripts)) return 'next export (build script)';\n\n if (ts === undefined) return null; // no compiler available: nothing is claimed from the config\n\n for (const file of ['next.config.js', 'next.config.mjs', 'next.config.ts', 'next.config.cjs']) {\n let text: string;\n try {\n text = readFileSync(join(cwd, file), 'utf8');\n } catch {\n continue;\n }\n\n try {\n const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true);\n if (exportedConfigIsStatic(sf, ts)) return `output: 'export' (${file})`;\n } catch { /* unparseable config claims nothing */ }\n }\n\n return null;\n}\n\n/**\n * `output: 'export'` on the object this module actually exports.\n *\n * Alias following is cycle-safe by construction. `const a = b; const b = a; export default a` would\n * otherwise recurse until the stack gave out, and while the surrounding catch turns that into a\n * conservative `unknown`, a malformed config should be an ordinary answer rather than an exception used as\n * control flow — a thrown RangeError also discards any signal found before it.\n */\nfunction exportedConfigIsStatic(sf: any, ts: TsModule): boolean {\n const objects: any[] = [];\n const followed = new Set<string>();\n\n const collectFrom = (expr: any): void => {\n if (!expr) return;\n if (ts.isObjectLiteralExpression(expr)) { objects.push(expr); return; }\n // `export default withPlugins({...})` / `module.exports = withMDX(config)`\n if (ts.isCallExpression(expr)) { for (const arg of expr.arguments) collectFrom(arg); return; }\n // `const nextConfig = {...}; export default nextConfig`\n if (ts.isIdentifier(expr)) {\n const name = expr.text;\n if (followed.has(name)) return; // already resolved, or part of a cycle\n followed.add(name);\n const visit = (node: any): void => {\n if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === name) {\n collectFrom(node.initializer);\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n }\n };\n\n const findExports = (node: any): void => {\n // `export default X`\n if (ts.isExportAssignment(node)) collectFrom(node.expression);\n // `module.exports = X`\n if (ts.isBinaryExpression(node)\n && node.operatorToken.kind === ts.SyntaxKind.EqualsToken\n && ts.isPropertyAccessExpression(node.left)\n && node.left.name.text === 'exports') {\n collectFrom(node.right);\n }\n ts.forEachChild(node, findExports);\n };\n findExports(sf);\n\n for (const object of objects) {\n for (const property of object.properties) {\n if (!ts.isPropertyAssignment(property)) continue;\n const key = property.name;\n const keyName = ts.isIdentifier(key) || ts.isStringLiteralLike(key) ? key.text : undefined;\n if (keyName !== 'output') continue;\n if (ts.isStringLiteralLike(property.initializer) && property.initializer.text === 'export') return true;\n }\n }\n\n return false;\n}\n\n/**\n * Static generators this project positively identifies, each with the dependency or setting that named it.\n *\n * Astro and Next are conditional: both ship a server mode, so `astro` alone says nothing and an SSR adapter\n * rules the static reading out entirely.\n */\nfunction staticSignals(cwd: string, ts: TsModule | undefined): SurfaceSignal[] {\n const manifest = readManifest(cwd);\n if (manifest === null) return [];\n\n const deps = { ...manifest.dependencies, ...manifest.devDependencies };\n const signals: SurfaceSignal[] = [];\n\n for (const generator of STATIC_GENERATORS) {\n if (deps[generator.dep] !== undefined) {\n signals.push({ signal: 'static-generator', source: generator.label });\n }\n }\n\n if (deps['astro'] !== undefined && !SSR_ADAPTERS.some((adapter) => deps[adapter] !== undefined)) {\n signals.push({ signal: 'static-generator', source: 'astro (no SSR adapter)' });\n }\n\n if (deps['next'] !== undefined) {\n const exported = nextExportsStatically(cwd, manifest, ts);\n if (exported !== null) signals.push({ signal: 'static-generator', source: `next: ${exported}` });\n }\n\n return signals;\n}\n\n/** Server-framework dependencies present, each named — they block a static conclusion. */\nfunction serverDependencySignals(cwd: string, ts: TsModule | undefined): SurfaceSignal[] {\n const manifest = readManifest(cwd);\n if (manifest === null) return [];\n\n const deps = { ...manifest.dependencies, ...manifest.devDependencies };\n const found = SERVER_DEPENDENCIES.filter((dep) => deps[dep] !== undefined);\n\n // Both-mode frameworks: present, but not a server dependency when the project also installs the\n // dependency that makes it static.\n for (const conditional of CONDITIONAL_SERVER_DEPENDENCIES) {\n if (deps[conditional.dep] !== undefined && deps[conditional.staticWhen] === undefined) {\n found.push(conditional.dep);\n }\n }\n\n // An SSR companion turns a static bundler into a server stack, so it vetoes the static reading the same\n // way a server framework does. `vite` alone is not a static build.\n for (const companion of SSR_COMPANIONS) if (deps[companion] !== undefined) found.push(companion);\n\n // `next` counts as a server dependency UNLESS the project exports statically, which `staticSignals`\n // establishes from the same manifest.\n if (deps['next'] !== undefined && nextExportsStatically(cwd, manifest, ts) === null) found.push('next');\n if (deps['astro'] !== undefined) {\n for (const adapter of SSR_ADAPTERS) if (deps[adapter] !== undefined) found.push(adapter);\n }\n\n return found.map((dep) => ({ signal: 'server-dependency', source: dep }));\n}\n\n/**\n * Classify the app's server surface from what was positively found.\n *\n * `endpointCount` and `deploymentShapes` come from the analysis that already ran; the manifest signals are\n * read here. Nothing in this function infers from absence except the final fall-through to `unknown`,\n * which is the one honest thing absence supports.\n */\nexport function classifyServerSurface(\n cwd: string,\n endpointCount: number,\n deploymentShapes: DeploymentShape[],\n ts?: TsModule,\n): ServerSurface {\n const evidence: SurfaceSignal[] = [];\n\n if (endpointCount > 0) {\n evidence.push({ signal: 'endpoint', source: `${endpointCount} recognized entry point(s)` });\n }\n for (const shape of deploymentShapes) {\n evidence.push({\n signal: SHAPE_SIGNAL[shape.evidence],\n source: `${shape.shape} (${shape.source})`,\n });\n }\n\n const servers = serverDependencySignals(cwd, ts);\n const statics = staticSignals(cwd, ts);\n\n // Only code that SERVES settles this: a recognized endpoint, a worker entry, or a provider function\n // directory with source in it. A deployment config does not — a static site on Netlify has a\n // `netlify.toml` and no server — and a `layout` folder does not either, since `api/client.ts` is an\n // ordinary front-end helper. Both remain in the evidence, and both still block a static claim below.\n const servesRequests = deploymentShapes.some((shape) => shape.evidence === 'runtime-entry');\n if (endpointCount > 0 || servesRequests) {\n return { state: 'server-runtime-detected', evidence };\n }\n\n evidence.push(...servers, ...statics);\n\n const blocked = servers.length > 0 || deploymentShapes.length > 0;\n if (statics.length > 0 && !blocked) {\n return { state: 'static-build-detected', evidence };\n }\n\n return { state: 'unknown', evidence };\n}\n\n/** The sentence that goes with each state, so a consumer states the same limits the analysis does. */\nexport function surfaceNote(surface: ServerSurface): string {\n if (surface.state === 'server-runtime-detected') {\n // \"Applicable\", not \"applies\". Recognizing code that serves requests establishes which KIND of\n // protection is relevant to these paths; it establishes nothing about whether a guard is installed,\n // fetching rules or enforcing them — none of which a build-time map can see. The previous wording\n // (\"Request-path protection applies to this app\") read as a protection status, and since this note is\n // rendered verbatim by consumers, it put that claim on a dashboard.\n return 'serverSurface: a server runtime was recognized in the analysed source (see its evidence). Request-path shielding is APPLICABLE to these paths — this is not a statement that a guard is installed, fetching rules, or enforcing them.';\n }\n\n if (surface.state === 'static-build-detected') {\n return 'serverSurface: a static build was identified and no server runtime was recognized in the analysed source. This is NOT deployment attestation — it describes the source, not what is deployed, and a serverless function added at the platform level would not appear here. Advisories against this app are dependency and bundle concerns rather than request-path risk.';\n }\n\n return 'serverSurface is UNKNOWN: neither a server runtime nor a static build could be positively identified. This is the honest answer for an unrecognised stack, and it must not be read as \"no server side\" — an unparsed framework produces no endpoints, and entry-point recognition has no completeness flag.';\n}\n","import { createHash } from 'node:crypto';\nimport type { ArgumentRole, CandidateFamily, Sink, SinkKind, TsModule } from './types.js';\nimport {\n isFnLike,\n isShadowedByEnclosingBinding,\n isUninvokedFunctionDeclaration,\n localCalls,\n opCallOf,\n rootIdentifier,\n spanOf,\n} from './ast.js';\nimport { npmPackageOf, type Bindings } from './bindings.js';\n\nconst DB_OPS = new Set(['insert', 'update', 'delete', 'select', 'upsert', 'rpc']);\nconst PRISMA_OPS = new Set(['create', 'createMany', 'update', 'updateMany', 'delete', 'deleteMany', 'upsert', 'findFirst', 'findUnique', 'findMany', 'count', 'aggregate']);\nconst FS_CALLS = /^(readFile|writeFile|readFileSync|writeFileSync|appendFile|createReadStream|createWriteStream|unlink|rm|rmSync|mkdir|readdir|stat|open)$/;\nconst EXEC_CALLS = /^(exec|execSync|spawn|spawnSync|execFile|execFileSync|fork)$/;\nconst HTTP_CALLS = /^(fetch|got|request)$/;\nconst HTTP_MEMBER_METHODS = new Set(['get', 'post', 'put', 'patch', 'delete', 'head', 'request']);\n// When a sink's base can't be traced precisely, infer its package from the file's imports of a known\n// provider for that sink kind (a file almost always uses one db/http client).\nconst DB_PACKAGES = ['@supabase/supabase-js', '@prisma/client', 'drizzle-orm', 'knex', 'kysely', 'pg', 'mysql2', 'mysql', 'sequelize', 'typeorm', 'mongoose', 'better-sqlite3'];\n// Drivers that are not in the inference list above but do establish a database API when a receiver\n// resolves to them. Extend deliberately: this list is what separates \"a package we can trace\" from\n// \"a package that proves a DB API\", and admitting the wrong one produces a false SQL-injection rule.\nconst MORE_DB_PACKAGES = ['postgres', 'mssql', 'tedious', 'oracledb', 'sqlite3', 'mongodb', 'ioredis',\n '@planetscale/database', '@neondatabase/serverless', '@libsql/client', '@vercel/postgres', 'slonik', 'sql.js'];\n/**\n * Does `pkg` establish a DATABASE api? Package provenance is not API provenance: `.query()` is a generic\n * method name, and an `@apollo/client` (or any HTTP-ish client) instance resolves to a real package while\n * having nothing to do with SQL. Without this gate, `client.query(req.body.sql)` compiled a precise\n * SQL-injection candidate for a GraphQL call — a rule that blocks legitimate traffic and mitigates nothing.\n * Subpath imports count (`drizzle-orm/node-postgres`).\n */\nconst isDbPackage = (pkg: string) =>\n DB_PACKAGES.includes(pkg) || MORE_DB_PACKAGES.includes(pkg) ||\n [...DB_PACKAGES, ...MORE_DB_PACKAGES].some((p) => pkg.startsWith(p + '/'));\nconst HTTP_PACKAGES = ['axios', 'got', 'node-fetch', 'undici', 'superagent', 'ky'];\nconst isHttpPackage = (pkg: string) => HTTP_PACKAGES.includes(pkg) || pkg === 'node:http' || pkg === 'node:https';\n// A filesystem/process API is not only a node: builtin — these wrappers expose the same sinks, and\n// requiring a match keeps recognition tied to a RESOLVED import rather than to a method name.\nconst FS_PACKAGES = ['fs-extra', 'graceful-fs', 'memfs'];\nconst isFsPackage = (pkg: string) => /^node:fs(\\/promises)?$/.test(pkg) || FS_PACKAGES.includes(pkg);\nconst EXEC_PACKAGES = ['execa', 'cross-spawn', 'shelljs', 'zx'];\nconst isExecPackage = (pkg: string) => pkg === 'node:child_process' || EXEC_PACKAGES.includes(pkg);\n\n/**\n * Which sink families this package can produce, per the recognizer tables above — i.e. what the map is\n * even *able* to see about it. Empty for the vast majority of npm: a package with no recognizer can still\n * be imported and called, we just have no model of its API, so no flow into it will ever be reported.\n * Exposed so the import inventory can say that out loud rather than let a consumer read \"no sink\" as\n * \"not reachable\". Takes a package ROOT (subpaths already normalized away by `npmPackageOf`), except for\n * `node:fs/promises`, whose subpath is part of the builtin's identity.\n */\nexport function recognizedSinkKinds(pkg: string): SinkKind[] {\n const kinds: SinkKind[] = [];\n if (isDbPackage(pkg)) kinds.push('db');\n if (isFsPackage(pkg)) kinds.push('fs');\n if (isExecPackage(pkg)) kinds.push('exec');\n if (isHttpPackage(pkg)) kinds.push('http');\n return kinds;\n}\n\nexport interface ModuleGraph {\n /** Sinks of `exportName` in the module `specifier` resolves to, relative to `fromFile`. */\n importedSinks(fromFile: string, specifier: string, exportName: string): Sink[];\n /**\n * What `exportName` traces to inside the module `specifier` resolves to — for a client instance\n * re-exported from a local module (`export const db = createClient(...)`). ONE hop: a re-export\n * chain (`export { db } from './client'`) is not followed.\n *\n * Three parts, because the package alone cannot answer whether the NAME belongs to that package:\n * package the npm package the value came from\n * origin `direct` — the target module imported this very binding from the package;\n * `factory` — the target module DERIVED it (a call result, or its own function)\n * name what the target module knows the binding as inside the package, i.e. its import\n * alias resolved back (`import { merge as deepMerge }` → `merge`). The consumer's\n * local name is the app's choice and is not part of the package's surface.\n */\n importedBinding(\n fromFile: string,\n specifier: string,\n exportName: string,\n ): { package: string; origin: 'direct' | 'factory'; name: string } | undefined;\n /**\n * The in-project file a RELATIVE specifier resolves to, or undefined — a bare package specifier, a path\n * that resolves to nothing, or a target outside the project boundary. Exposed because a caller that\n * wants to analyse the target itself (rather than ask this graph about it) still needs the same\n * resolution and the same boundary refusal; re-deriving either would let them drift apart.\n */\n resolveLocal(fromFile: string, specifier: string): string | undefined;\n}\n\nexport interface SinkContext {\n /** Absolute path of the file being analyzed (for resolving relative imports). */\n file: string;\n /** The same file, REPO-RELATIVE — part of a sink's identity, so it must not vary by machine. */\n owner: string;\n graph: ModuleGraph;\n}\n\n// --- sinks (agnostic) -------------------------------------------------------\nexport function collectLocalSinks(sf: any, ts: TsModule, bindings: Bindings, ctx?: SinkContext): Map<string, Sink[]> {\n const map = new Map<string, Sink[]>();\n const visit = (node: any) => {\n if (ts.isFunctionDeclaration(node) && node.name && node.body) map.set(node.name.text, directSinks(node.body, ts, bindings, ctx));\n else if (ts.isVariableStatement(node)) {\n for (const decl of node.declarationList.declarations) {\n if (ts.isIdentifier(decl.name) && decl.initializer && isFnLike(decl.initializer, ts)) {\n map.set(decl.name.text, directSinks(decl.initializer.body, ts, bindings, ctx));\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return map;\n}\n\nexport function sinksFrom(arrowOrNode: any, ts: TsModule, localSinks: Map<string, Sink[]>, bindings: Bindings, ctx?: SinkContext): Sink[] {\n if (!arrowOrNode) return [];\n const body = arrowOrNode.isSyntheticBody ? arrowOrNode.body\n : isFnLike(arrowOrNode, ts) ? arrowOrNode.body : arrowOrNode;\n if (!body) return [];\n const sinks = directSinks(body, ts, bindings, ctx);\n for (const called of localCalls(body, ts)) {\n // Same-file helper.\n for (const s of localSinks.get(called) ?? []) sinks.push(s);\n // Imported helper: the name resolves to a RELATIVE module → follow one hop into it.\n if (ctx) {\n const spec = bindings.resolve(called);\n if (spec && spec.startsWith('.')) {\n for (const s of ctx.graph.importedSinks(ctx.file, spec, bindings.exportNameOf(called) ?? called)) sinks.push(s);\n }\n }\n }\n // `import * as helper from './util'; helper.save(x)` — the namespace twin of the imported-helper hop\n // above. `directSinks` correctly refuses to call that receiver a dependency sink, so without this the\n // helper's REAL sinks would vanish with it and the endpoint would look clean. Sinks found this way\n // carry the helper's file, which already bars them from auto-generating a rule (no local call site).\n if (ctx) {\n for (const [root, member] of namespaceMemberCalls(body, ts)) {\n const spec = bindings.resolve(root);\n if (spec && spec.startsWith('.')) {\n for (const s of ctx.graph.importedSinks(ctx.file, spec, member)) sinks.push(s);\n }\n }\n }\n return dedupeSinks(sinks, ctx?.owner ?? '');\n}\n\n/** `ns.member(...)` calls in a subtree, as [namespace root, member] pairs. */\nfunction namespaceMemberCalls(node: any, ts: TsModule): Array<[string, string]> {\n const out: Array<[string, string]> = [];\n const visit = (n: any) => {\n if (ts.isCallExpression(n) && ts.isPropertyAccessExpression(n.expression) && ts.isIdentifier(n.expression.expression)) {\n out.push([n.expression.expression.text, n.expression.name.text]);\n }\n ts.forEachChild(n, visit);\n };\n visit(node);\n return out;\n}\n\n// Provider-agnostic sink recognizers over a subtree. Each sink is tagged with the npm package behind\n// it: resolved precisely from the call's base identifier via the file's imports, else inferred from\n// the file's imports of a known provider for that sink kind. A receiver that traces to a plain local\n// object/class/function is NOT a dependency sink and is dropped.\nfunction directSinks(node: any, ts: TsModule, bindings: Bindings, ctx?: SinkContext): Sink[] {\n const sinks: Sink[] = [];\n // `spec` is the raw module specifier the receiver came from, which `pkg` cannot express: a RELATIVE\n // specifier yields no package, and that is a positive fact (the receiver is app code) rather than the\n // absence of one (an untraceable receiver such as a handler param). The member-call recognizers below\n // need that distinction — `import * as helper from './util'; helper.exec(x)` is not child_process.\n const baseOf = (base: any): { pkg?: string; local?: boolean; root?: string; spec?: string; relative?: boolean } => {\n const root = base ? rootIdentifier(base, ts) : undefined;\n if (!root) return {};\n const spec = bindings.resolve(root);\n const relative = spec !== undefined && (spec.startsWith('.') || spec.startsWith('/'));\n const pkg = npmPackageOf(spec);\n if (pkg) return { pkg, root, spec };\n // A RELATIVE receiver is app code — unless one hop away it is a dependency. `import { db } from\n // './lib/db'` where that module does `export const db = createClient(...)` is the most common layout\n // in generated apps, and treating it as app code made the sink vanish entirely. Ask the target module\n // what the export traces to: a package means the receiver IS that dependency (an import-to-import\n // chain, so `attribution: 'import'`), and NO package means it stays app code — which is what keeps\n // `import * as helper from './util'; helper.exec(x)` correctly sink-free.\n if (relative && ctx && spec) {\n const viaModule = ctx.graph.importedBinding(ctx.file, spec, bindings.exportNameOf(root) ?? root);\n if (viaModule) return { pkg: viaModule.package, root, spec };\n }\n return { local: bindings.locals.has(root), root, spec, relative };\n };\n // Whether `package` is evidence or a guess. A resolved import binding is evidence ('import'); a\n // package inferred from the file's OTHER imports is a guess that is usually right ('inferred'); an\n // untraceable receiver is neither (undefined) and must not drive an auto-generated rule.\n const attributionOf = (b: { pkg?: string }, pkg: string | undefined): Sink['attribution'] =>\n b.pkg ? 'import' : pkg ? 'inferred' : undefined;\n /**\n * Claim `provider: 'sql'` only when the package actually establishes a database API. A traced package\n * that is not a DB provider stays in the INVENTORY (a `.query()` on it is worth a human's attention)\n * but is marked so no rule can be compiled from it — and it does not get to call itself SQL.\n */\n const dbApi = (pkg: string | undefined, attribution: Sink['attribution']): { provider?: string; apiUnconfirmed?: true } => {\n if (pkg && !isDbPackage(pkg)) return { apiUnconfirmed: true };\n // `provider` is a claim about the API at THIS call site, so it needs the receiver — not just the file.\n // An INFERRED package means \"this file talks to pg\", never \"this receiver is a pg client\", and\n // `res.locals.db.query(x)` in a file that imports pg is exactly that. The flow is already refused;\n // asserting `provider: 'sql'` anyway would overstate it in the inventory, where a human reads it.\n // `package` still carries the hint, and `attribution` already says how strong it is — deriving the\n // claim from it here keeps one source of truth rather than a second confidence field to drift.\n return attribution === 'import' || attribution === 'global' ? { provider: 'sql' } : {};\n };\n const infer = (kind: 'db' | 'http'): string | undefined => {\n const table = kind === 'db' ? DB_PACKAGES : HTTP_PACKAGES;\n for (const p of table) if (bindings.imports.has(p)) return p;\n return undefined;\n };\n const push = (s: Sink) => sinks.push(s);\n const visit = (n: any) => {\n // A function that is DECLARED here but not invoked here is not reached by this endpoint — walking\n // into it would report sinks the endpoint never touches (e.g. an unused local helper that shells\n // out). Skip those subtrees; when the handler DOES call such a helper, `localCalls` +\n // `collectLocalSinks` bring its sinks in by name. Inline callbacks / IIFEs are NOT skipped — those\n // do run (`items.map(x => db.insert(x))`, `.then(...)`).\n if (n !== node && isUninvokedFunctionDeclaration(n, ts)) return;\n if (ts.isCallExpression(n)) {\n const callee = n.expression;\n // db: `.from(\"t\").<op>()` (supabase/knex/kysely)\n if (ts.isPropertyAccessExpression(callee) && callee.name.text === 'from') {\n const b = baseOf(callee.expression);\n const t = n.arguments[0];\n const table = t && ts.isStringLiteralLike(t) ? t.text : undefined;\n const parent = n.parent;\n if (!b.local && !b.relative && parent && ts.isPropertyAccessExpression(parent) && DB_OPS.has(parent.name.text)) {\n const pkg = b.pkg ?? infer('db');\n const attribution = attributionOf(b, pkg);\n push({ kind: 'db', ...dbApi(pkg, attribution), package: pkg, table, op: parent.name.text, attribution, ...spanOf(opCallOf(parent, ts)) });\n }\n }\n if (ts.isPropertyAccessExpression(callee)) {\n const method = callee.name.text;\n const b = baseOf(callee.expression);\n // `!b.relative` is the member-call twin of the bare-call justification below: a receiver that\n // resolves to a RELATIVE module is app code, whatever its methods are named. Without it,\n // `import * as helper from './util'; helper.exec(req.body.cmd)` was read as child_process and\n // produced a proven, auto-generatable command-injection candidate for harmless local code.\n // Such a receiver is not dropped outright — `sinksFrom` follows it into its module instead.\n if (!b.local && !b.relative) {\n // db: prisma-style `prisma.<model>.<op>()` — the op names are generic (`delete`, `update`, …),\n // so require a real prisma signal: a resolved binding, the import, or a prisma-named receiver.\n if (PRISMA_OPS.has(method) && ts.isPropertyAccessExpression(callee.expression)) {\n const prismaLikely = b.pkg === '@prisma/client' ||\n (!b.pkg && (bindings.imports.has('@prisma/client') || /prisma/i.test(b.root ?? '')));\n // Same rule for the provider claim: only a resolved receiver earns `provider: 'prisma'`; a\n // prisma-NAMED receiver is a hint, and `package` + `attribution` already say so.\n if (prismaLikely) push({ kind: 'db', ...(b.pkg ? { provider: 'prisma' } : {}), package: '@prisma/client', table: callee.expression.name.text, op: method, attribution: b.pkg ? 'import' : 'inferred', ...spanOf(n) });\n }\n // db: raw `.query(` / `.execute(`. Any object can have a `.query` method, so an untraceable\n // receiver stays in the inventory with NO attribution — visible to a human, never auto-ruled.\n if (method === 'query' || method === 'execute') {\n const pkg = b.pkg ?? infer('db');\n const attribution = attributionOf(b, pkg);\n push({ kind: 'db', ...dbApi(pkg, attribution), package: pkg, op: method, attribution, ...spanOf(n) });\n }\n // fs / exec via a namespace: `fs.writeFile(` / `child_process.exec(`. The receiver must\n // actually resolve to a filesystem/process package — the method name alone proves nothing.\n if (FS_CALLS.test(method) && b.pkg && isFsPackage(b.pkg)) {\n push({ kind: 'fs', package: b.pkg, op: method, attribution: 'import', ...spanOf(n) });\n }\n if (EXEC_CALLS.test(method) && b.pkg && isExecPackage(b.pkg)) {\n push({ kind: 'exec', package: b.pkg, op: method, attribution: 'import', ...spanOf(n) });\n }\n // http: any client whose binding resolves to a known http package (`axios.get`, `ky.post`,\n // `http.request`), else the classic identifiers by name as a heuristic.\n if (HTTP_MEMBER_METHODS.has(method)) {\n if (b.pkg && isHttpPackage(b.pkg)) {\n push({ kind: 'http', provider: b.root, package: b.pkg, op: method, attribution: 'import', ...spanOf(n) });\n } else if (!b.spec && ts.isIdentifier(callee.expression) && /^(axios|http|https|got|ky)$/.test(callee.expression.text)) {\n push({ kind: 'http', provider: callee.expression.text, package: infer('http'), op: method, attribution: 'inferred', ...spanOf(n) });\n }\n }\n }\n }\n // Bare calls: `fetch(…)` / `exec(…)` / `readFile(…)` / `eval(…)`. A dangerous NAME is not a\n // dangerous API: `import { fetch } from './util'` and a callback parameter named `fetch` both look\n // identical here, and treating either as an HTTP request produced a FALSE SSRF candidate. So the\n // call must be justified — either it resolves to a module that plausibly provides that API, or it\n // is a genuine unresolved global (only `fetch`/`eval`/`Function` ever are).\n if (ts.isIdentifier(callee) && !bindings.locals.has(callee.text)) {\n const name = callee.text;\n const spec = bindings.resolve(name);\n const pkg = npmPackageOf(spec);\n const shadowed = isShadowedByEnclosingBinding(n, name, ts);\n // A relative import resolves to no package: it's app code, not the API it shares a name with.\n const fromModule = spec !== undefined;\n const trueGlobal = !fromModule && !shadowed;\n\n if (HTTP_CALLS.test(name)) {\n if (pkg && isHttpPackage(pkg)) push({ kind: 'http', provider: name, package: pkg, op: 'request', attribution: 'import', ...spanOf(n) });\n else if (name === 'fetch' && trueGlobal) push({ kind: 'http', provider: 'fetch', op: 'request', attribution: 'global', ...spanOf(n) });\n }\n // `readFile`/`exec` are never globals: without a matching module binding this is app code.\n if (FS_CALLS.test(name) && pkg && isFsPackage(pkg)) {\n push({ kind: 'fs', package: pkg, op: name, attribution: 'import', ...spanOf(n) });\n }\n if (EXEC_CALLS.test(name) && pkg && isExecPackage(pkg)) {\n push({ kind: 'exec', package: pkg, op: name, attribution: 'import', ...spanOf(n) });\n }\n if (name === 'eval' && trueGlobal) push({ kind: 'eval', op: 'eval', attribution: 'global', ...spanOf(n) });\n }\n }\n if (ts.isNewExpression(n) && ts.isIdentifier(n.expression) && n.expression.text === 'Function'\n && !bindings.locals.has('Function') && !isShadowedByEnclosingBinding(n, 'Function', ts)) {\n push({ kind: 'eval', op: 'new Function', attribution: 'global', ...spanOf(n) });\n }\n ts.forEachChild(n, visit);\n };\n visit(node);\n return sinks;\n}\n\n// --- adapter summaries: which argument means what ---------------------------\n// Small, testable per-library summaries, keyed by sink kind so an overloaded name (`get`) can't be read\n// as the wrong thing. This is the cheap foundation the review recommended BEFORE a whole-program\n// dataflow engine: without argument roles, \"the input reaches this sink\" cannot be turned into a rule,\n// because the mitigation class depends on WHICH argument received the value.\nconst ARGUMENT_ROLES: Record<string, Record<string, ArgumentRole[]>> = {\n exec: {\n exec: ['command'], execSync: ['command'],\n execFile: ['file', 'args'], execFileSync: ['file', 'args'],\n spawn: ['command', 'args'], spawnSync: ['command', 'args'], fork: ['file', 'args'],\n },\n http: {\n fetch: ['url', 'init'], request: ['url', 'options'],\n get: ['url', 'options'], head: ['url', 'options'], delete: ['url', 'options'],\n post: ['url', 'body'], put: ['url', 'body'], patch: ['url', 'body'],\n },\n fs: {\n readFile: ['path'], readFileSync: ['path'], open: ['path'],\n writeFile: ['path', 'content'], writeFileSync: ['path', 'content'],\n appendFile: ['path', 'content'],\n unlink: ['path'], rm: ['path'], rmSync: ['path'], mkdir: ['path'], readdir: ['path'], stat: ['path'],\n createReadStream: ['path'], createWriteStream: ['path'],\n },\n db: {\n query: ['sql', 'values'], execute: ['sql', 'values'],\n insert: ['values'], update: ['values'], upsert: ['values'], select: ['columns'],\n // Filters: the value half is still request data reaching the query, but as a bound parameter.\n eq: ['column', 'value'], neq: ['column', 'value'], gt: ['column', 'value'], gte: ['column', 'value'],\n lt: ['column', 'value'], lte: ['column', 'value'], like: ['column', 'value'], ilike: ['column', 'value'],\n match: ['values'], filter: ['column', 'value'],\n },\n eval: { eval: ['code'], Function: ['code'] },\n};\n\n/**\n * The (sink kind, argument role) pairs where a request value arriving is inherently dangerous AND a rule\n * can express the mitigation. Deliberately narrow — notably `db`+`values` is absent: a request value in\n * a parameterized insert is genuine reachability signal but not a blockable pattern by itself.\n */\nexport const CANDIDATE_FAMILIES: Record<string, Partial<Record<ArgumentRole, CandidateFamily>>> = {\n http: { url: 'ssrf' },\n exec: { command: 'command-injection', file: 'command-injection', args: 'command-injection' },\n fs: { path: 'path-traversal' },\n db: { sql: 'sql-injection' },\n eval: { code: 'code-injection' },\n};\n\n/** Role of argument `index` for this call, given the sink kind it was recognized as. */\nexport function argumentRoleOf(sinkKind: string, method: string | undefined, index: number, total = 0): ArgumentRole {\n // `new Function(a, b, \"return a+b\")` — every argument but the LAST declares a parameter name; only the\n // last one is executable code. An index-based table cannot express that.\n if (sinkKind === 'eval' && method === 'Function') return index === total - 1 ? 'code' : 'args';\n const table = method ? ARGUMENT_ROLES[sinkKind]?.[method] : undefined;\n return table?.[index] ?? 'unknown';\n}\n\n// Deterministic identity for a sink, so `Flow.sink` (an embedded copy) can be correlated back to the\n// inventory entry without deep-equality. `owner` is the endpoint's own repo-relative file, which the\n// span alone does NOT imply: duplicated route boilerplate across two files puts the same call at the\n// same offsets, and hashing only the span made those sinks share an id while the schema promises\n// map-wide identity. A repo-relative path (never absolute) keeps the id stable across machines.\nfunction sinkId(s: Sink, owner: string): string {\n return createHash('sha256')\n .update([s.kind, s.provider, s.package, s.table, s.op, s.file ?? owner, s.start, s.end].join('|'))\n .digest('hex')\n .slice(0, 12);\n}\n\nfunction dedupeSinks(sinks: Sink[], owner: string): Sink[] {\n const seen = new Set<string>();\n const out: Sink[] = [];\n for (const s of sinks) {\n const key = `${s.kind}:${s.provider}:${s.package}:${s.table}:${s.op}:${s.line}:${s.start}`;\n if (!seen.has(key)) { seen.add(key); out.push({ ...s, id: sinkId(s, owner) }); }\n }\n return out;\n}\n","import { readFileSync, realpathSync, statSync } from 'node:fs';\nimport { dirname, join, relative, resolve as resolvePath } from 'node:path';\nimport type { Sink, TsModule } from './types.js';\nimport { guessScriptKind, isFnLike, localCalls } from './ast.js';\nimport { buildModuleBindings, npmPackageOf, type Bindings } from './bindings.js';\nimport { isInside } from './sources.js';\nimport { collectLocalSinks, type ModuleGraph } from './sinks.js';\n\n// --- cross-file (imported) helper tracing -----------------------------------\n// AI-generated apps routinely put the data access in a sibling module (`import { saveOrder } from\n// './db'`), so a handler's real sink lives one file away. Without following that, the endpoint looks\n// sink-free and no rule can be correlated to it. We follow ONE cross-file hop (plus same-file helpers\n// inside the target), which covers the common shape while keeping the walk bounded and cheap.\nconst RESOLVE_EXTS = ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs'];\n\nexport function createModuleGraph(ts: TsModule, opts: { cwd: string; boundary: string; followOutside?: boolean }): ModuleGraph {\n // file → { fnSinks, calleesOf, bindings } | null (unreadable/unparseable)\n type Entry = { fnSinks: Map<string, Sink[]>; calleesOf: Map<string, string[]>; bindings: Bindings };\n const cache = new Map<string, Entry | null>();\n\n const load = (file: string) => {\n if (cache.has(file)) return cache.get(file) ?? null;\n let entry: Entry | null = null;\n try {\n const text = readFileSync(file, 'utf8');\n const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true, guessScriptKind(ts, file));\n const bindings = buildModuleBindings(sf, ts);\n // `bindings` is kept for `importedBinding`: the module's own view of what its exports came from.\n entry = { fnSinks: collectLocalSinks(sf, ts, bindings), calleesOf: collectCallees(sf, ts), bindings };\n } catch {\n entry = null; // fail-open: an unreadable dependency must not break the map\n }\n cache.set(file, entry);\n return entry;\n };\n\n /** Shared guard: resolve a relative specifier, and refuse to leave the project. */\n const resolveInProject = (fromFile: string, specifier: string): string | undefined => {\n const target = resolveRelativeModule(fromFile, specifier);\n if (!target) return undefined;\n // Stay inside the project: `../../other-repo/db` (or a symlink) would otherwise pull an unrelated\n // codebase into this app's attack surface. The primary walker enforces this; so must the resolver.\n if (!opts.followOutside) {\n let real = target;\n try { real = realpathSync(target); } catch { /* use as-is */ }\n if (!isInside(real, opts.boundary)) return undefined;\n }\n return target;\n };\n\n return {\n resolveLocal: resolveInProject,\n\n importedSinks(fromFile, specifier, exportName) {\n const target = resolveInProject(fromFile, specifier);\n if (!target) return [];\n const mod = load(target);\n if (!mod) return [];\n const collected = [...(mod.fnSinks.get(exportName) ?? [])];\n // One same-file hop inside the target: `export function saveOrder(){ return doInsert() }`.\n for (const callee of mod.calleesOf.get(exportName) ?? []) {\n for (const s of mod.fnSinks.get(callee) ?? []) collected.push(s);\n }\n // `line` refers to the HELPER's file, not the endpoint's — carry the file so the coordinate is\n // interpretable (and so flow linking marks it `imported` rather than proven — it cannot see the call).\n const rel = relative(opts.cwd, target);\n return collected.map((s) => ({ ...s, file: rel }));\n },\n\n // A different question about the same module: not \"what sinks are in there\" but \"what does this\n // export TRACE TO\". The common AI-built layout puts the client in a lib file —\n // `export const db = createClient(...)` in `lib/db.ts`, imported everywhere — so the receiver of\n // `db.from('orders').insert(...)` resolves to a relative specifier and nothing else. Refusing it (as\n // an unattributable receiver) is right for app code but wrong here: one hop away it is a real\n // dependency, and that chain is import-to-import, fully static — evidence, not inference.\n importedBinding(fromFile, specifier, exportName) {\n const target = resolveInProject(fromFile, specifier);\n if (!target) return undefined;\n const mod = load(target);\n if (!mod) return undefined;\n // The target module's own bindings answer it: `db` there resolves through\n // `const db = createClient(...)` back to the package `createClient` was imported from.\n const pkg = npmPackageOf(mod.bindings.resolve(exportName));\n if (pkg === undefined) return undefined;\n // `origin` and `name` come from the SAME module as the package, which is the point: a consumer\n // one hop away can see neither how the value was produced there nor what the package calls it.\n return {\n package: pkg,\n origin: mod.bindings.originOf(exportName) ?? 'direct',\n name: mod.bindings.exportNameOf(exportName) ?? exportName,\n };\n },\n };\n}\n\n// Resolve a RELATIVE specifier to a real file (extension + /index, and the TS-ESM `./db.js` → db.ts\n// convention). Bare package specifiers are intentionally NOT followed — that's node_modules, and a\n// dependency's internals are not this app's attack surface.\nfunction resolveRelativeModule(fromFile: string, spec: string): string | undefined {\n if (!spec.startsWith('.')) return undefined;\n const dir = dirname(fromFile);\n const base = resolvePath(dir, spec);\n const candidates: string[] = [];\n const jsLike = /\\.(js|jsx|mjs|cjs)$/.exec(base);\n if (jsLike) {\n const stem = base.slice(0, -jsLike[0].length);\n for (const e of RESOLVE_EXTS) candidates.push(stem + e); // ./db.js may mean db.ts\n }\n candidates.push(base);\n for (const e of RESOLVE_EXTS) candidates.push(base + e);\n for (const e of RESOLVE_EXTS) candidates.push(join(base, 'index' + e));\n for (const c of candidates) {\n try {\n if (statSync(c).isFile()) return c;\n } catch {\n /* next */\n }\n }\n return undefined;\n}\n\n// name → the local function names it calls (for one same-file hop inside an imported module).\nfunction collectCallees(sf: any, ts: TsModule): Map<string, string[]> {\n const map = new Map<string, string[]>();\n const visit = (node: any) => {\n let name: string | undefined;\n let body: any;\n if (ts.isFunctionDeclaration(node) && node.name && node.body) { name = node.name.text; body = node.body; }\n else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer && isFnLike(node.initializer, ts)) {\n name = node.name.text; body = node.initializer.body;\n }\n if (name && body) map.set(name, localCalls(body, ts));\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return map;\n}\n","import type { AddressSpace, FieldShape, InputField, InputSource } from './types.js';\n\n/**\n * Map an input to the EXACT rule-engine parameter that addresses it, or null with a reason. Verified\n * against the resolver in engine/request.js — a coordinate that the resolver cannot resolve would compile\n * into a rule that silently never matches, which is worse than emitting nothing:\n * - body / json / form / multipart / server-fn args → `post.<dotted path>` (createServerFnGuard feeds\n * server-function arguments through as the JSON body, so `post.<field>` resolves them)\n * - query → `get.<name>`\n * - header → `server.HTTP_<UPPER_SNAKE>` (resolver lowercases and maps `_` → `-`)\n * - cookie → `cookie.<name>`\n * - file → `files.<field>` (`.content` / `.type` / `.filename` are separate)\n * - route-param → NONE. The resolver exposes get/post/request/cookie/server/files — NOT `req.params`.\n * - array path → NONE. `#getNestedValue` walks own properties, so `tags[].label` needs an\n * `array_key_value` rule, not a dotted parameter.\n */\nexport function runtimeCoordinate(source: InputSource | undefined, path: string): { runtimeParameter: string | null; runtimeParameterReason?: string } {\n if (/\\[\\d*\\]/.test(path)) {\n return { runtimeParameter: null, runtimeParameterReason: 'array traversal: needs an array_key_value rule, not a dotted parameter' };\n }\n switch (source) {\n case 'json-body':\n case 'form-body':\n case 'multipart':\n case 'body':\n case 'server-fn-data':\n return { runtimeParameter: `post.${path}` };\n case 'query':\n return { runtimeParameter: `get.${path}` };\n case 'cookie':\n return { runtimeParameter: `cookie.${path}` };\n case 'file':\n return { runtimeParameter: `files.${path}` };\n case 'header':\n return { runtimeParameter: `server.HTTP_${path.toUpperCase().replace(/-/g, '_')}` };\n case 'route-param':\n return { runtimeParameter: null, runtimeParameterReason: 'route parameters are not exposed by the runtime resolver' };\n default:\n return { runtimeParameter: null, runtimeParameterReason: 'input source could not be determined' };\n }\n}\n\n/**\n * The request region an input lives in — its identity, independent of whether we can currently ADDRESS\n * it. A route param has a space (`route-param`) but no coordinate; an array path has a space (`post`)\n * but needs an `array_key_value` rule. Keep those two questions apart: conflating them made an\n * unaddressable input indistinguishable from one in another region.\n */\nexport function addressSpaceOf(source: InputSource | undefined): AddressSpace {\n switch (source) {\n case 'json-body':\n case 'form-body':\n case 'multipart':\n case 'body':\n case 'server-fn-data':\n return 'post';\n case 'query': return 'get';\n case 'cookie': return 'cookie';\n case 'file': return 'files';\n case 'header': return 'server';\n case 'route-param': return 'route-param';\n default: return 'unknown';\n }\n}\n\n/**\n * Is this flow backed by a read seen at the sink's own call site? True for the two `*-local` tiers.\n * `imported` / `heuristic` / `unknown` all mean \"we did not see the argument\", for different reasons.\n */\nexport function isProvenFlow(confidence: string | undefined): boolean {\n return confidence === 'exact-local' || confidence === 'transformed-local';\n}\n\n/** `<space>:<path>` — an input's identity within an endpoint. */\nexport function inputIdOf(source: InputSource | undefined, path: string): string {\n return `${addressSpaceOf(source)}:${path}`;\n}\n\n/**\n * The rule-engine NAMESPACE an input lands in (`post`, `get`, `cookie`, `files`, `server`), or null when\n * it has no address. Derived from `runtimeCoordinate` on purpose: comparing raw source labels would call\n * `json-body` and an Express `req.body` read different places when both resolve to `post.*`, and would\n * miss that `post.id` and `get.id` are genuinely different places.\n */\nexport function namespaceOf(source: InputSource | undefined, path: string): string | null {\n const { runtimeParameter } = runtimeCoordinate(source, path);\n if (!runtimeParameter) return null;\n const dot = runtimeParameter.indexOf('.');\n return dot === -1 ? runtimeParameter : runtimeParameter.slice(0, dot);\n}\n\n/** Place extracted fields in a request region: attach `source`, the runtime coordinate, and the id. */\nexport function withCoordinates(fields: FieldShape[], source: InputSource): InputField[] {\n return fields.map((f) => {\n const src = f.source ?? source;\n return { ...f, source: src, id: inputIdOf(src, f.name), ...runtimeCoordinate(src, f.name) };\n });\n}\n","import type { FieldShape, InputField, InputSource, TsModule } from './types.js';\nimport { bindingKey, rootIdentifier } from './ast.js';\nimport { npmPackageOf, type Bindings } from './bindings.js';\nimport { addressSpaceOf, inputIdOf, runtimeCoordinate } from './coordinates.js';\n\nconst ZOD_BASE = new Set(['string', 'number', 'boolean', 'array', 'object', 'enum', 'bigint', 'date', 'record']);\n// String-format refinements a validator can declare — kept on the field so a rule can pin the shape.\nconst STRING_FORMATS = new Set(['email', 'uuid', 'url', 'ip', 'ipv4', 'ipv6', 'cuid', 'cuid2', 'ulid', 'emoji', 'datetime', 'base64', 'jwt', 'nanoid']);\n// Packages whose `.object({…})` calls describe an input schema.\nconst VALIDATOR_PACKAGES = new Set(['zod', 'valibot', 'yup', 'joi', '@hapi/joi', 'superstruct']);\n\n// --- inputs -----------------------------------------------------------------\nexport function inputsFromValidator(validatorCall: any, ts: TsModule, bindings: Bindings): FieldShape[] {\n if (!validatorCall) return [];\n return zodObjectFields(validatorCall, ts, bindings);\n}\n\n// From a raw handler: validator schema fields it parses, plus the request fields it actually reads\n// (member accesses, destructuring, `await request.json()` bodies).\nexport function inputsFromHandler(\n params: any,\n body: any,\n ts: TsModule,\n bindings: Bindings,\n opts: { payloadParam?: boolean; validatorSource?: InputSource } = {},\n): InputField[] {\n // A validated schema inside a handler describes the request body — except for a payload-style entry\n // (a server action), where the schema describes the action's own argument.\n const schemaSource = opts.validatorSource ?? 'json-body';\n const schemaFields = zodObjectFields(body, ts, bindings);\n const reads = requestMemberAccesses(params, body, ts, opts);\n\n // Keyed by IDENTITY — `<space>:<path>` — not by field name. A handler that reads `query.id` and\n // `params.id`, or validates a body field named `id` while the sink consumes `query.id`, has TWO inputs\n // that merely share a name. Name-keying made one of them disappear, and since the survivor decided the\n // coordinate, a rule could be pinned to a parameter the payload never travels in. Distinct identities\n // remove that class outright: each input carries its own address, and a flow names which one it means.\n // Same space + same path IS the same input, so a schema field and an `req.body` read of it merge\n // (the schema entry wins, since it also carries the declared type/constraints).\n const byId = new Map<string, InputField>();\n const put = (name: string, source: InputSource, extra: Omit<FieldShape, 'name' | 'source'> = {}) => {\n const id = inputIdOf(source, name);\n if (byId.has(id)) return;\n byId.set(id, { ...extra, id, name, source, ...runtimeCoordinate(source, name) });\n };\n for (const f of schemaFields) {\n const { name, source, ...shape } = f;\n put(name, source ?? schemaSource, shape);\n }\n for (const { name, sources } of reads) for (const source of sources) put(name, source);\n return [...byId.values()];\n}\n\n// Find the first validator `.object({...})` in a subtree — gated on the receiver tracing to a known\n// validator package (so an unrelated `.object(` never becomes a schema). An untraceable receiver\n// literally named `z` is accepted as a heuristic (covers `z` re-exported from a local module).\nfunction findValidatorObject(node: any, ts: TsModule, bindings: Bindings): any {\n let found: any = null;\n const find = (n: any) => {\n if (found || !n) return;\n if (ts.isCallExpression(n) && ts.isPropertyAccessExpression(n.expression) && n.expression.name.text === 'object') {\n const root = rootIdentifier(n.expression.expression, ts);\n const pkg = root ? npmPackageOf(bindings.resolve(root)) : undefined;\n const isValidator = (pkg && VALIDATOR_PACKAGES.has(pkg)) || (!pkg && root === 'z' && !bindings.locals.has(root));\n if (isValidator) {\n const arg = n.arguments[0];\n if (arg && ts.isObjectLiteralExpression(arg)) { found = arg; return; }\n }\n }\n ts.forEachChild(n, find);\n };\n find(node);\n return found;\n}\n\n// Read a validator object's fields (name + type/constraints). Nested objects/arrays are flattened to\n// dotted paths — `address.city`, `tags[].label` — the same coordinates `array_key_value` rules use.\nfunction zodObjectFields(node: any, ts: TsModule, bindings: Bindings): FieldShape[] {\n if (!node) return [];\n const lit = findValidatorObject(node.body ?? node, ts, bindings);\n return lit ? fieldsOfObject(lit, ts, bindings, '') : [];\n}\n\nfunction fieldsOfObject(objectLiteral: any, ts: TsModule, bindings: Bindings, prefix: string): FieldShape[] {\n const fields: FieldShape[] = [];\n for (const p of objectLiteral.properties) {\n if (!ts.isPropertyAssignment(p) || !p.name) continue;\n const fname = (p.name as any).text;\n if (!fname) continue;\n const shape = zodShape(p.initializer, ts);\n fields.push({ name: prefix + fname, ...shape });\n const nested = findValidatorObject(p.initializer, ts, bindings);\n if (nested) fields.push(...fieldsOfObject(nested, ts, bindings, prefix + fname + (shape.type === 'array' ? '[].' : '.')));\n }\n return fields;\n}\n\nfunction numericValue(arg: any, ts: TsModule): number | undefined {\n if (!arg) return undefined;\n if (ts.isNumericLiteral(arg)) return Number(arg.text);\n if (ts.isPrefixUnaryExpression(arg) && arg.operator === ts.SyntaxKind.MinusToken && ts.isNumericLiteral(arg.operand)) return -Number(arg.operand.text);\n return undefined;\n}\n\nfunction zodShape(node: any, ts: TsModule): Omit<FieldShape, 'name'> {\n const shape: Omit<FieldShape, 'name'> = {};\n let cur = node;\n while (cur && ts.isCallExpression(cur) && ts.isPropertyAccessExpression(cur.expression)) {\n const method = cur.expression.name.text;\n const arg0 = cur.arguments[0];\n if (ZOD_BASE.has(method) && !shape.type) shape.type = method;\n if (method === 'min') { const v = numericValue(arg0, ts); if (v !== undefined) shape.min = v; }\n if (method === 'max') { const v = numericValue(arg0, ts); if (v !== undefined) shape.max = v; }\n if (STRING_FORMATS.has(method) && !shape.format) shape.format = method;\n if (method === 'regex' && arg0 && ts.isRegularExpressionLiteral(arg0) && !shape.pattern) shape.pattern = arg0.text;\n if (method === 'optional' || method === 'nullish') shape.optional = true;\n cur = cur.expression.expression;\n }\n return shape;\n}\n\nexport const REQ_SOURCES = ['body', 'query', 'params'];\n\n// The request fields a handler reads, across the common idioms:\n// req.body.x / req.query.x / req.params.x (member access)\n// const { x } = req.body (destructuring)\n// ({ body }) => body.x / const { x } = body (destructured handler param)\n// const b = await request.json(); b.x / const { x } = await request.json() (fetch-style Request)\nfunction requestMemberAccesses(\n params: any,\n body: any,\n ts: TsModule,\n opts: { payloadParam?: boolean } = {},\n): Array<{ name: string; sources: InputSource[] }> {\n if (!body) return [];\n // Keyed by FIELD NAME, which two namespaces can share (`params.id` and `query.id` in one handler).\n // Last-write-wins silently picked one, and since the pick decided the coordinate, a handler reading\n // both compiled a rule pinned to `get.id` for data that arrives in the path segment — a wrong-input\n // pin, the one failure this whole layer exists to prevent. Collisions are now recorded, and the\n // first-seen source wins so the record is at least deterministic.\n const out = new Map<string, InputSource[]>();\n const record = (name: string, source: InputSource) => {\n const list = out.get(name) ?? [];\n if (!list.includes(source)) list.push(source);\n out.set(name, list);\n };\n const p0 = params?.[0];\n const reqName = p0 && ts.isIdentifier(p0.name) ? p0.name.text : undefined;\n // Identifiers that ARE a request-input object (destructured `({ body })` param, `await req.json()`),\n // mapped to the NAMESPACE each one came from. It has to be a map, not a set of names: with\n // `({ query: q })` the local is `q`, and matching the local against the literal 'query'/'params'\n // discards the namespace — which silently mis-addresses the input (`post.doc` for a query-string\n // field, and worse, a coordinate for a route param, which the resolver cannot address at all).\n const sourceNames = new Map<string, InputSource>();\n const payloadNames = new Set<string>();\n if (opts.payloadParam && p0 && ts.isIdentifier(p0.name)) payloadNames.add(p0.name.text);\n if (p0 && !reqName && ts.isObjectBindingPattern(p0.name)) {\n for (const el of p0.name.elements) {\n const key = bindingKey(el, ts);\n if (key && REQ_SOURCES.includes(key) && ts.isIdentifier(el.name)) {\n sourceNames.set(el.name.text, namespaceSource(key));\n }\n }\n }\n const unwrap = (e: any): any => {\n let cur = e;\n while (cur && (ts.isAwaitExpression(cur) || ts.isAsExpression(cur) || ts.isParenthesizedExpression(cur) || ts.isNonNullExpression(cur))) cur = cur.expression;\n return cur;\n };\n const isPayloadExpr = (e: any): boolean => ts.isIdentifier(e) && payloadNames.has(e.text);\n const isReqSourceExpr = (e: any): boolean =>\n isPayloadExpr(e) ||\n (ts.isPropertyAccessExpression(e) && ts.isIdentifier(e.expression) && e.expression.text === reqName && REQ_SOURCES.includes(e.name.text)) ||\n (ts.isIdentifier(e) && sourceNames.has(e.text));\n const isBodyReadCall = (e: any): boolean => {\n const inner = unwrap(e);\n return Boolean(inner && ts.isCallExpression(inner) && ts.isPropertyAccessExpression(inner.expression) &&\n ['json', 'formData'].includes(inner.expression.name.text) &&\n ts.isIdentifier(inner.expression.expression) && inner.expression.expression.text === reqName);\n };\n const visit = (n: any) => {\n // <source>.<field>\n if (ts.isPropertyAccessExpression(n) && isReqSourceExpr(n.expression)) {\n record(n.name.text, sourceOfExpr(n.expression));\n }\n if (ts.isVariableDeclaration(n) && n.initializer) {\n const init = unwrap(n.initializer);\n // const b = await request.json() → b is a request-input object from here on.\n if (ts.isIdentifier(n.name) && isBodyReadCall(n.initializer)) sourceNames.set(n.name.text, bodyReadSource(n.initializer));\n // const { query: q } = req → the SAME namespace capture as a destructured handler param, just one\n // statement later. Without this the fields read off `q` are invisible: no coordinate is emitted\n // (so nothing is mis-addressed) but the surface goes unreported, which reads as \"nothing here\".\n if (ts.isObjectBindingPattern(n.name) && ts.isIdentifier(init) && reqName && init.text === reqName) {\n for (const el of n.name.elements) {\n const key = bindingKey(el, ts);\n if (key && REQ_SOURCES.includes(key) && ts.isIdentifier(el.name)) sourceNames.set(el.name.text, namespaceSource(key));\n }\n }\n // const { a, b } = <source> | await request.json()\n if (ts.isObjectBindingPattern(n.name) && (isReqSourceExpr(init) || isBodyReadCall(n.initializer))) {\n const src = isBodyReadCall(n.initializer) ? bodyReadSource(n.initializer) : sourceOfExpr(init);\n for (const el of n.name.elements) {\n const key = bindingKey(el, ts);\n if (key) record(key, src);\n }\n }\n }\n ts.forEachChild(n, visit);\n };\n visit(body);\n return [...out].map(([name, sources]) => ({ name, sources }));\n\n // `req.body.x` / `req.query.x` / `req.params.x` — the namespace decides the runtime coordinate, and\n // route params notably have NONE, so this distinction is load-bearing rather than cosmetic.\n function sourceOfExpr(e: any): InputSource {\n if (isPayloadExpr(e)) return 'server-fn-data';\n if (ts.isPropertyAccessExpression(e)) {\n if (e.name.text === 'query') return 'query';\n if (e.name.text === 'params') return 'route-param';\n if (e.name.text === 'body') return 'body';\n }\n // The recorded namespace, so an ALIAS resolves correctly (`({ query: q }) => q.id` → query).\n if (ts.isIdentifier(e)) {\n const recorded = sourceNames.get(e.text);\n if (recorded) return recorded;\n }\n return 'body';\n }\n\n /** Map a request namespace key to the input source it implies. */\n function namespaceSource(key: string): InputSource {\n if (key === 'query') return 'query';\n if (key === 'params') return 'route-param';\n return 'body';\n }\n function bodyReadSource(init: any): InputSource {\n const t = init?.getText?.() ?? '';\n return /formData\\s*\\(/.test(t) ? 'form-body' : 'json-body';\n }\n}\n","import type { AddressSpace, ArgumentRole, Flow, InputField, Limitation, Sink, TsModule } from './types.js';\nimport { bindingKey, calleeName, isValueRead, lineOf, rootIdentifier } from './ast.js';\nimport { REQ_SOURCES } from './inputs.js';\nimport { addressSpaceOf } from './coordinates.js';\nimport { argumentRoleOf, CANDIDATE_FAMILIES } from './sinks.js';\n\n/** A tainted binding: the path prefix it stands for, and the request region it came from if known. */\ninterface Root { path: string; space?: AddressSpace }\n\n/** The address space a request-namespace binding key implies (`query` → get, `params` → route-param). */\nfunction spaceOfKey(key: string | undefined): AddressSpace | undefined {\n if (key === 'query') return 'get';\n if (key === 'params') return 'route-param';\n if (key === 'body') return 'post';\n // `data` / `input` / `payload`: a server-function argument, which the guard feeds through as the body.\n if (key === 'data' || key === 'input' || key === 'payload') return 'post';\n return undefined;\n}\n\n// --- input → sink flow linking ---------------------------------------------\n// Evidence-backed data links: for each sink, does an INPUT identifier/path appear inside the sink\n// call's arguments? \"Tainted\" roots are the handler's own parameter names (`{ data }`, `req`) plus any\n// local alias of them (`const body = await request.json()`, `const { title } = data`).\n//\n// Deliberately conservative: a match yields one of the two `*-local` tiers; no match yields `imported` /\n// `heuristic` / `unknown` depending on WHY nothing was seen. It never claims a flow it didn't see, which\n// is the point — a consumer pinning a rule should require a proven tier (see `isProvenFlow`) and treat\n// the rest as \"may reach\". Matching is per (address space, path): a read of `query.id` is not evidence\n// about the body field `id`.\n// Spread onto an endpoint: `flows`, plus `limitations` only when there are any (keeps the common case clean).\nexport function linkedFlows(body: any, params: any, inputs: InputField[], sinks: Sink[], ts: TsModule): { flows: Flow[]; limitations?: Limitation[] } {\n const { flows, limitations } = linkFlows(body, params, inputs, sinks, ts);\n return limitations.length > 0 ? { flows, limitations } : { flows };\n}\n\nfunction linkFlows(\n bodyNode: any,\n params: any,\n inputs: InputField[],\n sinks: Sink[],\n ts: TsModule,\n): { flows: Flow[]; limitations: Limitation[] } {\n if (!bodyNode || sinks.length === 0 || inputs.length === 0) return { flows: [], limitations: [] };\n\n // Tainted roots and the PATH each one stands for. `req` → '' (its own members are the path);\n // `const { billing } = await req.json()` → billing stands for 'billing', so a read of\n // `billing.email` normalizes to 'billing.email' and can be compared with the input path.\n // Bindings whose members ARE the input paths, so they contribute no segment: a request source\n // (`{ body }`), and the validated-payload conventions of the server-fn frameworks (`{ data }` for\n // TanStack). Getting this wrong shifts every path by one segment and silently kills all matching.\n const CONTAINER_KEYS = new Set([...REQ_SOURCES, 'data', 'input', 'payload']);\n // Each tainted root also carries the ADDRESS SPACE it was bound from, when that is known. A bare `req`\n // has none — its next segment decides (`req.query.x` vs `req.body.x`) — but `({ query: q })` fixes `q`\n // in `get` for good. Without this the space was dropped along with the namespace segment, so a read of\n // `query.id` was indistinguishable from a read of `body.id` and could match either input.\n const rootPath = new Map<string, Root>();\n const addRoot = (name: string, path: string, space?: AddressSpace) => {\n if (!rootPath.has(name)) rootPath.set(name, { path, space });\n };\n for (const p of params ?? []) {\n if (!p?.name) continue;\n if (ts.isIdentifier(p.name)) addRoot(p.name.text, '');\n else if (ts.isObjectBindingPattern(p.name)) {\n for (const el of p.name.elements) {\n if (!ts.isBindingElement(el) || !ts.isIdentifier(el.name)) continue;\n const key = bindingKey(el, ts);\n // A destructured request source (`{ body }`) is a container: its members ARE the paths.\n const container = key !== undefined && CONTAINER_KEYS.has(key);\n addRoot(el.name.text, container ? '' : key ?? el.name.text, container ? spaceOfKey(key) : undefined);\n }\n }\n }\n\n // Does this initializer carry request data? Includes `Schema.parse(await req.json())`: VALIDATION IS\n // NOT SANITIZATION — a validated value is still attacker-controlled, and treating it as clean would\n // silently drop every flow in a validated handler (the common TanStack/Next shape).\n const requestReadPath = (init: any): Root | undefined => {\n let cur = init;\n while (cur && (ts.isAwaitExpression(cur) || ts.isParenthesizedExpression(cur) || ts.isAsExpression(cur) || ts.isNonNullExpression(cur))) cur = cur.expression;\n if (!cur) return undefined;\n if (ts.isCallExpression(cur) && ts.isPropertyAccessExpression(cur.expression)) {\n const m = cur.expression.name.text;\n if (['json', 'formData', 'text'].includes(m)) {\n const root = rootIdentifier(cur.expression.expression, ts);\n // A body read: whatever the field names turn out to be, they are addressed in `post`.\n return root && rootPath.has(root) ? { path: '', space: 'post' } : undefined;\n }\n if (['parse', 'safeParse', 'validate', 'cast'].includes(m)) {\n for (const a of cur.arguments) {\n const inner = requestReadPath(a);\n if (inner !== undefined) return inner; // taint survives validation\n }\n return undefined;\n }\n }\n const p = pathFromTainted(cur, ts, rootPath);\n return p;\n };\n\n const aliasVisit = (n: any) => {\n if (ts.isVariableDeclaration(n) && n.initializer) {\n const base = requestReadPath(n.initializer);\n if (base !== undefined) {\n if (ts.isIdentifier(n.name)) addRoot(n.name.text, base.path, base.space);\n else if (ts.isObjectBindingPattern(n.name)) {\n for (const el of n.name.elements) {\n if (!ts.isBindingElement(el) || !ts.isIdentifier(el.name)) continue;\n const key = bindingKey(el, ts);\n // `const { query: q } = req` — the binding KEY names the space when the base has none yet.\n const space = base.space ?? (base.path === '' ? spaceOfKey(key) : undefined);\n const container = base.path === '' && key !== undefined && CONTAINER_KEYS.has(key);\n addRoot(el.name.text, container ? '' : join2(base.path, key ?? el.name.text), space);\n }\n }\n }\n }\n ts.forEachChild(n, aliasVisit);\n };\n aliasVisit(bodyNode);\n\n // Index every call by its start offset so a sink's span identifies its EXACT call node.\n // Keyed by start+end: in `db.from(t).insert(x)` BOTH calls start at `db`, so the start offset alone\n // is ambiguous — the end distinguishes them.\n const callBySpan = new Map<string, any>();\n const callVisit = (n: any) => {\n // NewExpression too, or `new Function(...)` — inventoried as an eval sink — could never be located,\n // leaving its flows permanently heuristic and its argument-role entry unreachable.\n if (ts.isCallExpression(n) || ts.isNewExpression(n)) {\n try { callBySpan.set(`${n.getStart()}:${n.getEnd()}`, n); } catch { /* synthetic */ }\n }\n ts.forEachChild(n, callVisit);\n };\n callVisit(bodyNode);\n\n const flows: Flow[] = [];\n const allLimits: Limitation[] = [];\n for (const sink of sinks) {\n // A sink from an imported module has no call site here — its flows can only be `imported`.\n const node = sink.file === undefined && sink.start !== undefined && sink.end !== undefined\n ? callBySpan.get(`${sink.start}:${sink.end}`)\n : undefined;\n // path → the argument ROLES it was read into. Per-argument attribution is what makes a candidate\n // possible: the same value in `url` vs `body`, or `path` vs `content`, implies different mitigations.\n // Keyed by `<space>:<path>` so a read of `query.id` cannot lend its evidence to the body field `id`.\n const reads = new Map<string, { read: Root; roles: Set<ArgumentRole>; exact: boolean }>();\n const sinkLimits: Limitation[] = [];\n if (node) {\n // ONLY this sink call's own arguments, plus other calls in the SAME fluent chain\n // (`.update({…}).eq('id', data.id)` is one operation). Never the enclosing statement: a sibling\n // expression such as `Promise.all([audit(data.title), db.insert({…})])` must not lend evidence.\n for (const call of fluentChainCalls(node, ts)) {\n const method = calleeName(call, ts);\n const args = call.arguments ?? [];\n for (const a of args) for (const l of sinkArgumentLimitations(a, ts, rootPath)) sinkLimits.push(l);\n for (let i = 0; i < args.length; i++) {\n const role = argumentRoleOf(sink.kind, method, i, args.length);\n // Is the ARGUMENT ITSELF the read (`readFileSync(req.body.p)`), or does the read sit inside a\n // larger expression (`readFileSync('/tmp/' + req.body.p)`)? Both mean the value arrives in the\n // same parameter, but only the first says what reaches the sink is exactly what arrived — the\n // distinction a server needs before promoting a rule to blocking without a human.\n const whole = pathFromTainted(args[i], ts, rootPath);\n for (const read of taintedReadPaths(args[i], ts, rootPath)) {\n const key = `${read.space ?? '*'}:${read.path}`;\n const exact = whole !== undefined && whole.path === read.path && whole.space === read.space;\n const entry = reads.get(key) ?? { read, roles: new Set<ArgumentRole>(), exact: false };\n entry.roles.add(role);\n entry.exact = entry.exact || exact;\n reads.set(key, entry);\n }\n }\n }\n }\n for (const input of inputs) {\n const inputPath = normalizePath(input.name);\n const inputSpace = addressSpaceOf(input.source);\n // Exact path, or the input is an ANCESTOR of what was read (`billing` covers `billing.email`).\n // A mere shared leaf name is NOT evidence: `billing.email` and `shipping.email` are different.\n // The SPACE must agree too, or the two `id`s of `query.id` / `body.id` trade evidence and a rule\n // gets pinned to whichever the extractor happened to keep. A read whose space is unknown (a bare\n // `req` handed to a helper, say) still matches on path alone — recall, at heuristic strength.\n const matched = [...reads.values()].filter(({ read }) =>\n (read.space === undefined || read.space === inputSpace)\n && (read.path === inputPath || read.path.startsWith(inputPath + '.')));\n const proven = matched.length > 0;\n // Weakest-honest tier that fits the evidence.\n const confidence: Flow['confidence'] = proven\n ? (matched.some((m) => m.exact) ? 'exact-local' : 'transformed-local')\n : sink.file !== undefined ? 'imported'\n // No span at all (a synthetic node) means no evidence is even possible. A sink whose span exists\n // but sits outside this handler — reached through a same-file helper — is ordinary co-occurrence:\n // located, just not attributable to an argument here. Calling that \"unknown\" would overstate it.\n : sink.start === undefined ? 'unknown'\n : 'heuristic';\n const roles = new Set<ArgumentRole>(matched.flatMap(({ roles: rs }) => [...rs]));\n // Prefer a role that maps to a mitigation class over a generic one (a value can reach two args).\n // A sink whose package does not establish this API cannot support the mitigation class either:\n // labelling a GraphQL `.query()` as the sql-injection family would mis-classify it for any consumer\n // that reads `candidateFamily` without also checking `ruleGeneratable`.\n const family = sink.apiUnconfirmed\n ? undefined\n : [...roles].map((r) => CANDIDATE_FAMILIES[sink.kind]?.[r]).find(Boolean);\n const argumentRole = family\n ? [...roles].find((r) => CANDIDATE_FAMILIES[sink.kind]?.[r])\n : [...roles].find((r) => r !== 'unknown') ?? (proven ? 'unknown' : undefined);\n\n // Deliberately SEPARATE from confidence: a proven tier means \"the source reaches the sink\", which is\n // not authorization to block traffic. Every remaining obstacle is listed, so this doubles as the\n // queue for improving the extractor/adapters rather than silently losing the opportunity.\n const reasons: string[] = [];\n if (!proven) reasons.push(`flow evidence is \"${confidence}\": no proven local read of this input into the sink call`);\n if (!input.runtimeParameter) reasons.push(input.runtimeParameterReason ?? 'input has no runtime parameter');\n if (sink.file !== undefined) reasons.push('sink is in an imported module: no local call-site evidence');\n if (sink.start === undefined) reasons.push('sink call could not be located in the source');\n // Only a receiver traced to a dependency ('import') or a genuine runtime global earns a rule.\n // 'inferred' is deliberately NOT enough: the package came from some OTHER import in the file, not\n // from the receiver, so `res.locals.db.query(x)` in a file that happens to import `pg` looks\n // identical to a real pool — and `res.locals.db` may be any app object. Such sinks stay in the\n // inventory for review; they just cannot compile a rule that blocks live traffic on a guess.\n if (sink.apiUnconfirmed) {\n reasons.push(`sink package \"${sink.package}\" is not a known ${sink.kind} provider: it does not establish a ${sink.kind} API (method name alone is not evidence)`);\n }\n if (sink.attribution !== 'import' && sink.attribution !== 'global') {\n reasons.push(sink.attribution === 'inferred'\n ? `sink package \"${sink.package}\" was inferred from the file's other imports, not from the receiver (${sink.kind}.${sink.op ?? '?'}): the receiver may be any app object`\n : `sink receiver could not be traced to a dependency (${sink.kind}.${sink.op ?? '?'} on an unresolved receiver): a rule here would be a guess`);\n }\n if (proven && argumentRole === 'unknown') reasons.push(`sink argument role is not modelled for ${sink.kind}.${sink.op ?? '?'}`);\n // A dynamic key or a spread in this sink's arguments means no coordinate can name the field that\n // actually reaches it — report the specific cause rather than a generic \"heuristic\".\n for (const l of sinkLimits) {\n reasons.push(l.kind === 'dynamic-key'\n ? `dynamic computed key reaches this sink (${l.detail}): the field cannot be named by a parameter`\n : `spread reaches this sink (${l.detail}): the specific field is not identifiable`);\n }\n // `!sink.apiUnconfirmed`: when the family was withheld because the PACKAGE does not establish this\n // API, the role is not what's wrong — role \"sql\" is normally blockable, and saying otherwise sends a\n // reviewer to look at the wrong thing. The package reason above already explains the refusal.\n if (proven && argumentRole && argumentRole !== 'unknown' && !family && !sink.apiUnconfirmed) {\n // e.g. a request value in a parameterized db `values` object: real reachability, but not a\n // pattern a generic blocking rule can express.\n reasons.push(`argument role \"${argumentRole}\" on a ${sink.kind} sink is not a blockable pattern on its own`);\n }\n flows.push({\n input: input.name,\n inputId: input.id,\n sink,\n confidence,\n line: sink.line,\n ...(argumentRole ? { argumentRole } : {}),\n ...(family ? { candidateFamily: family } : {}),\n ruleGeneratable: reasons.length === 0,\n ruleGeneratableReasons: reasons,\n });\n }\n for (const l of sinkLimits) allLimits.push(l);\n }\n return { flows, limitations: dedupeLimitations(allLimits) };\n}\n\nfunction dedupeLimitations(list: Limitation[]): Limitation[] {\n const seen = new Set<string>();\n return list.filter((l) => {\n const k = `${l.kind}:${l.detail}:${l.line}`;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n}\n\n/** Join two path segments, tolerating an empty base. */\nfunction join2(base: string, seg: string): string {\n return base ? `${base}.${seg}` : seg;\n}\n\n/**\n * Canonical form for comparing paths: index/array tokens are erased and empty segments collapsed, so\n * `tags[0].label`, `tags[].label` and `tags.label` all compare equal, while DISTINCT paths such as\n * `billing.email` and `shipping.email` stay distinct (the previous leaf-only comparison conflated them).\n */\nfunction normalizePath(path: string): string {\n return path\n .replace(/\\[\\d*\\]/g, '')\n .split('.')\n .filter(Boolean)\n .join('.');\n}\n\n/**\n * Calls belonging to the same fluent chain as `call` — the same logical operation. Walking UP stops at\n * anything that is not a continuation of the chain (an array literal, an argument position), which is\n * what keeps a sibling expression in the same statement from lending evidence.\n */\nfunction fluentChainCalls(call: any, ts: TsModule): any[] {\n let root = call;\n for (;;) {\n const p = root.parent;\n if (p && ts.isPropertyAccessExpression(p) && p.expression === root) { root = p; continue; }\n if (p && ts.isCallExpression(p) && p.expression === root) { root = p; continue; }\n if (p && (ts.isAwaitExpression(p) || ts.isParenthesizedExpression(p) || ts.isNonNullExpression(p)) && p.expression === root) { root = p; continue; }\n break;\n }\n const out: any[] = [];\n const collect = (n: any) => {\n if (!n) return;\n if (ts.isCallExpression(n) || ts.isNewExpression(n)) out.push(n);\n if (ts.isCallExpression(n) || ts.isPropertyAccessExpression(n) || ts.isAwaitExpression(n) || ts.isParenthesizedExpression(n) || ts.isNonNullExpression(n)) {\n collect(n.expression);\n }\n };\n collect(root);\n return out;\n}\n\n/**\n * The canonical PATHS of values genuinely read from a tainted source inside `node` — the evidence behind\n * a proven flow. Full paths, not leaf names: `data.shipping.email` yields `shipping.email`, so it can\n * never be mistaken for the distinct input `billing.email`. Array indices normalize to `[]`.\n * Property KEYS, member names and binding names are not reads.\n */\nfunction taintedReadPaths(node: any, ts: TsModule, rootPath: Map<string, Root>): Root[] {\n const out: Root[] = [];\n const seen = new Set<string>();\n const add = (r: Root) => {\n const key = `${r.space ?? '*'}:${r.path}`;\n if (!seen.has(key)) { seen.add(key); out.push(r); }\n };\n const visit = (n: any) => {\n if (!n) return;\n if (ts.isPropertyAccessExpression(n) || ts.isElementAccessExpression(n)) {\n const read = pathFromTainted(n, ts, rootPath);\n if (read !== undefined) { add(read); return; } // the inner nodes are the path, not separate reads\n }\n if (ts.isIdentifier(n) && rootPath.has(n.text) && isValueRead(n, ts)) {\n const r = rootPath.get(n.text)!;\n if (r.path) add({ path: normalizePath(r.path), space: r.space });\n }\n ts.forEachChild(n, visit);\n };\n visit(node);\n return out;\n}\n\n/**\n * Shapes that defeat parameter pinning, found in a sink call's arguments. Reporting these is the point:\n * \"we could not model this\" is far more useful to an operator than an endpoint that silently shows no\n * flow, and it is the queue for improving the extractor.\n * - `insert({ v: body[field] })` → the field is chosen at runtime; no coordinate can name it.\n * - `insert({ ...body })` → the whole payload reaches the sink; which field is unidentifiable.\n */\nfunction sinkArgumentLimitations(node: any, ts: TsModule, rootPath: Map<string, Root>): Limitation[] {\n const out: Limitation[] = [];\n const seen = new Set<string>();\n const add = (kind: Limitation['kind'], detail: string, n: any) => {\n const key = `${kind}:${detail}`;\n if (seen.has(key)) return;\n seen.add(key);\n out.push({ kind, detail, line: lineOf(n) });\n };\n const text = (n: any) => {\n try { return String(n.getText()).replace(/\\s+/g, ' ').slice(0, 120); } catch { return '<expression>'; }\n };\n const visit = (n: any) => {\n if (!n) return;\n // A computed member read off tainted data with a non-literal index.\n if (ts.isElementAccessExpression(n)) {\n const root = rootIdentifier(n.expression, ts);\n const arg = n.argumentExpression;\n if (root && rootPath.has(root) && arg && !ts.isStringLiteralLike(arg) && !ts.isNumericLiteral(arg)) {\n add('dynamic-key', text(n), n);\n }\n }\n // A spread of tainted data into the sink's argument.\n if ((ts.isSpreadAssignment?.(n) || ts.isSpreadElement(n)) && n.expression) {\n const root = rootIdentifier(n.expression, ts);\n if (root && rootPath.has(root)) add('spread-into-sink', text(n.parent ?? n), n);\n }\n ts.forEachChild(n, visit);\n };\n visit(node);\n return out;\n}\n\n/** Canonical path of a member/element access rooted in a tainted binding, or undefined if not tainted. */\nfunction pathFromTainted(node: any, ts: TsModule, rootPath: Map<string, Root>): Root | undefined {\n const segs: string[] = [];\n let cur = node;\n for (;;) {\n if (ts.isPropertyAccessExpression(cur)) { segs.unshift(cur.name.text); cur = cur.expression; continue; }\n if (ts.isElementAccessExpression(cur)) {\n const a = cur.argumentExpression;\n segs.unshift(a && ts.isStringLiteralLike(a) ? a.text : '[]');\n cur = cur.expression;\n continue;\n }\n if (ts.isNonNullExpression(cur) || ts.isParenthesizedExpression(cur) || ts.isAwaitExpression(cur)) { cur = cur.expression; continue; }\n break;\n }\n if (!cur || !ts.isIdentifier(cur)) return undefined;\n const base = rootPath.get(cur.text);\n if (base === undefined) return undefined;\n let space = base.space;\n // Drop a leading NAMESPACE segment (`req.body.webhookUrl` → `webhookUrl`). Input names — and the\n // runtime coordinates derived from them — are relative to their namespace (`post.webhookUrl`), so\n // leaving `body.` in the read path would fail to match the very inputs it came from. Without this,\n // the highest-value flows (`req.body.webhookUrl` → fetch, `req.body.command` → exec) never reach\n // proven.\n // The dropped segment is exactly what names the address space, so capture it before discarding it —\n // losing it is what made `req.query.id` and `req.body.id` the same read.\n if (base.path === '' && segs.length > 1 && REQ_SOURCES.includes(segs[0]!)) {\n space = spaceOfKey(segs[0]!) ?? space;\n segs.shift();\n }\n return { path: normalizePath([base.path, ...segs].filter(Boolean).join('.')), space };\n}\n","import type { Endpoint, Sink, TsModule } from './types.js';\nimport { hasExport, isFnLike, methodFromObjectArg, spanOf, unwindChain } from './ast.js';\nimport type { Bindings } from './bindings.js';\nimport { functionNameFromPath, ROUTE_REGISTER, routeFromChain, routeObject } from './routes.js';\nimport { withCoordinates } from './coordinates.js';\nimport { inputsFromHandler, inputsFromValidator } from './inputs.js';\nimport { sinksFrom, type SinkContext } from './sinks.js';\nimport { linkedFlows } from './flows.js';\n\nconst HTTP_METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']);\n\n// --- entry-point recognizers -----------------------------------------------\nexport function extractFromFile(sf: any, ts: TsModule, localSinks: Map<string, Sink[]>, bindings: Bindings, ctx: SinkContext): Omit<Endpoint, 'file'>[] {\n const out: Omit<Endpoint, 'file'>[] = [];\n const isServerActionsFile = fileHasUseServer(sf, ts);\n\n const visit = (node: any) => {\n if (ts.isVariableStatement(node) && hasExport(node, ts)) {\n for (const decl of node.declarationList.declarations) {\n // (1) TanStack Start: `export const NAME = createServerFn({method}).inputValidator(fn).handler(fn)`\n if (decl.initializer && ts.isCallExpression(decl.initializer)) {\n const chain = unwindChain(decl.initializer, ts);\n if (chain.baseName === 'createServerFn' && ts.isIdentifier(decl.name)) {\n const validatorCall = chain.calls['inputValidator'] ?? chain.calls['validator'];\n const inputs = withCoordinates(inputsFromValidator(validatorCall, ts, bindings), 'server-fn-data');\n const handlerFn = chain.calls['handler']?.arguments?.[0];\n const sinks = sinksFrom(handlerFn, ts, localSinks, bindings, ctx);\n const handlerBody = handlerFn && isFnLike(handlerFn, ts) ? handlerFn.body : undefined;\n const ep: Omit<Endpoint, 'file'> = {\n name: decl.name.text,\n entryKind: 'server-fn',\n method: methodFromObjectArg(chain.baseCall, ts),\n ...spanOf(decl),\n inputs,\n sinks,\n ...linkedFlows(handlerBody, handlerFn?.parameters, inputs, sinks, ts),\n };\n // Honesty marker: a validator EXISTS but couldn't be read — inputs are unknown, not \"none\".\n if (validatorCall && inputs.length === 0) ep.inputsResolved = false;\n out.push(ep);\n continue;\n }\n }\n // (2b) `export const POST = (req) => …` route handler, or a `'use server'` action arrow.\n if (ts.isIdentifier(decl.name) && decl.initializer && isFnLike(decl.initializer, ts)) {\n if (HTTP_METHODS.has(decl.name.text)) {\n out.push(handlerEntry(decl.name.text, decl.name.text, decl.initializer.parameters, decl.initializer.body, ts, localSinks, bindings, ctx, spanOf(decl)));\n } else if (isServerActionsFile) {\n out.push(handlerEntry(decl.name.text, 'server-action', decl.initializer.parameters, decl.initializer.body, ts, localSinks, bindings, ctx, spanOf(decl)));\n }\n }\n }\n }\n\n // (2a) Route handlers / server actions declared as functions.\n if (ts.isFunctionDeclaration(node) && node.name && hasExport(node, ts)) {\n if (HTTP_METHODS.has(node.name.text)) {\n out.push(handlerEntry(node.name.text, node.name.text, node.parameters, node.body, ts, localSinks, bindings, ctx, spanOf(node)));\n } else if (isServerActionsFile || hasUseServerDirective(node, ts)) {\n out.push(handlerEntry(node.name.text, 'server-action', node.parameters, node.body, ts, localSinks, bindings, ctx, spanOf(node)));\n }\n }\n\n // (2c) Deno / WinterCG function entry: `Deno.serve(handler)` or `serve(handler)` — Supabase Edge\n // Functions, Base44 backend functions, Deno workers. These platforms have no router and no route\n // file: one handler per module, invoked by the function's NAME, so the endpoint's identity comes\n // from the file location. Without this recognizer such a project maps to nothing at all.\n if (ts.isCallExpression(node)) {\n const c = node.expression;\n const denoServe = ts.isPropertyAccessExpression(c) && c.name.text === 'serve' &&\n ts.isIdentifier(c.expression) && c.expression.text === 'Deno';\n const bareServe = ts.isIdentifier(c) && c.text === 'serve';\n if (denoServe || bareServe) {\n const handler = node.arguments.find((a: any) => isFnLike(a, ts));\n if (handler) {\n out.push(handlerEntry(functionNameFromPath(ctx.file) ?? 'serve', 'edge-function', handler.parameters, handler.body, ts, localSinks, bindings, ctx, spanOf(node)));\n }\n }\n }\n\n if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {\n const mname = node.expression.name.text;\n // (3a) Route registrations: `app.post('/path', …, handler)` (Express/Fastify/Hono/Koa) and the\n // chained `router.route('/x').get(handler)` idiom (path lives on the inner `.route()` call).\n if (ROUTE_REGISTER.has(mname)) {\n const args = node.arguments;\n const first = args[0];\n const route = first && ts.isStringLiteralLike(first) ? first.text : routeFromChain(node.expression.expression, ts);\n const handler = args[args.length - 1];\n if (route !== undefined && handler && isFnLike(handler, ts)) {\n out.push(handlerEntry(route, 'route-registration', handler.parameters, handler.body, ts, localSinks, bindings, ctx, {\n // `use`/`all` register handlers but are not HTTP methods — leave method undefined.\n method: HTTP_METHODS.has(mname.toUpperCase()) ? mname.toUpperCase() : undefined,\n route,\n ...spanOf(node),\n }));\n }\n }\n // (3b) Fastify object form: `app.route({ method, url, handler })` — one endpoint per method.\n if (mname === 'route') {\n const arg = node.arguments[0];\n if (arg && ts.isObjectLiteralExpression(arg)) {\n const reg = routeObject(arg, ts);\n if (reg.url && reg.handler) {\n for (const m of reg.methods.length ? reg.methods : [undefined]) {\n out.push(handlerEntry(reg.url, 'route-registration', reg.handler.parameters, reg.handler.body, ts, localSinks, bindings, ctx, { method: m, route: reg.url, ...spanOf(node) }));\n }\n }\n }\n }\n }\n\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return out;\n}\n\n// Next server actions: a `'use server'` directive at the top of a module (whole file) or a function body.\nfunction fileHasUseServer(sf: any, ts: TsModule): boolean {\n const first = sf.statements?.[0];\n return Boolean(first && ts.isExpressionStatement(first) && ts.isStringLiteralLike(first.expression) && first.expression.text === 'use server');\n}\nfunction hasUseServerDirective(fn: any, ts: TsModule): boolean {\n const first = fn.body?.statements?.[0];\n return Boolean(first && ts.isExpressionStatement(first) && ts.isStringLiteralLike(first.expression) && first.expression.text === 'use server');\n}\n\nfunction handlerEntry(\n name: string,\n kindLabel: string,\n params: any,\n body: any,\n ts: TsModule,\n localSinks: Map<string, Sink[]>,\n bindings: Bindings,\n ctx: SinkContext,\n extra: { method?: string; route?: string; line?: number; start?: number; end?: number } = {},\n): Omit<Endpoint, 'file'> {\n const entryKind = kindLabel === 'route-registration' || kindLabel === 'server-action' || kindLabel === 'edge-function'\n ? kindLabel\n : 'route-handler';\n // A server action receives its payload as the first argument; a route handler receives a Request.\n const payloadStyle = kindLabel === 'server-action';\n const inputs = inputsFromHandler(params, body, ts, bindings, {\n payloadParam: payloadStyle,\n validatorSource: payloadStyle ? 'server-fn-data' : 'json-body',\n });\n const sinks = sinksFrom({ body, parameters: params, isSyntheticBody: true }, ts, localSinks, bindings, ctx);\n return {\n name,\n entryKind,\n method: extra.method ?? (HTTP_METHODS.has(name) ? name : undefined),\n route: extra.route,\n line: extra.line,\n start: extra.start,\n end: extra.end,\n inputs,\n sinks,\n ...linkedFlows(body, params, inputs, sinks, ts),\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ImportedPackage, ImportSite, TsModule } from './types.js';\nimport { npmPackageOf } from './bindings.js';\nimport { recognizedSinkKinds } from './sinks.js';\n\n// The app's IMPORT inventory — \"which packages does this code pull in\", answered for every source file,\n// not just the ones that hold an entry point.\n//\n// Why it is separate from sink collection: a sink is only recorded for the few API families the extractor\n// models, and only inside a recognized handler. That makes sinks the wrong instrument for the question a\n// vulnerability correlator actually asks — \"does this app use package P at all?\" — because P may be used\n// heavily through an API we have no recognizer for, or from a file with no entry point in it. Answering\n// that question from the sink list yields a confident \"no\", which is the worst possible wrong answer:\n// it closes a real vulnerability as unreachable. So imports are collected on their own terms.\n//\n// Two fidelities, deliberately. Files with an entry-point signal are fully parsed anyway, so their imports\n// come from the AST (specifiers AND bound names). The rest — most of a project — are only scanned for\n// module specifiers, which is far cheaper than building a syntax tree for every file and is the half that\n// matters for correlation. The mixed fidelity is reported per package as `namesComplete` rather than\n// smoothed over.\n\n/** A `compilerOptions.paths` entry: `\"@/*\"` is a prefix, `\"foo\"` matches only the specifier `foo`. */\nexport interface PathAlias {\n prefix: string;\n wildcard: boolean;\n}\n\n/** One import edge as found in a single file. */\nexport interface RawImport {\n /** Module specifier exactly as written (`node:fs`, `lodash/merge`, `./db`). */\n specifier: string;\n /** Bound names: real named bindings, plus the markers `default`, `*`, `require`, `import()`. */\n names: string[];\n /** 1-based line of the import. */\n line?: number;\n}\n\n/** Cap per package: enough to point a reviewer at the usage, bounded so a big app can't bloat the map. */\nconst MAX_SITES = 5;\n\n/**\n * A bare specifier that is a legal npm package name. Bare does NOT mean \"package\": every AI-built app\n * configures a path alias (`@/components` → `./src/components`), and those are the app's OWN code. Letting\n * them into the inventory is not cosmetic — each one lands in the \"no recognized sink family\" bucket and\n * inflates the count a reviewer reads as unanalysable dependencies.\n */\nconst NPM_NAME = /^(?:@[^/@\\s~][^/@\\s]*\\/)?[^/@\\s.~][^/@\\s]*$/;\nfunction isNpmPackageName(pkg: string): boolean {\n return pkg.startsWith('node:') || NPM_NAME.test(pkg);\n}\n\n/**\n * Path-alias prefixes declared in `tsconfig.json` / `jsconfig.json` (`compilerOptions.paths`). Best-effort\n * and deliberately shallow: `extends` chains and bundler-config aliases (a `vite.config.ts` `resolve.alias`\n * is code, not data) are not followed, so the name check above remains the backstop. Reads tolerantly —\n * these files routinely carry comments and trailing commas, which `JSON.parse` rejects.\n */\nexport function readPathAliases(cwd: string): PathAlias[] {\n const aliases: PathAlias[] = [];\n for (const name of ['tsconfig.json', 'jsconfig.json']) {\n let paths: Record<string, unknown> | undefined;\n try {\n const raw = readFileSync(join(cwd, name), 'utf8');\n const parsed = JSON.parse(stripJsonComments(raw)) as { compilerOptions?: { paths?: Record<string, unknown> } };\n paths = parsed.compilerOptions?.paths;\n } catch {\n continue; // absent or unparseable: fall back to the name check\n }\n for (const key of Object.keys(paths ?? {})) {\n if (key.startsWith('.')) continue; // a relative alias is already excluded as a non-package\n // The wildcard has to be carried, not flattened into a prefix: an alias `\"foo\"` covers the\n // specifier `foo` and nothing else, so prefix-matching it would also swallow the real npm\n // package `foobar`. Only `\"foo/*\"` is a prefix.\n if (key.endsWith('*')) aliases.push({ prefix: key.slice(0, -1), wildcard: true });\n else aliases.push({ prefix: key, wildcard: false });\n }\n }\n return aliases;\n}\n\nfunction stripJsonComments(text: string): string {\n let out = '';\n let inString = false;\n let quote = '';\n for (let i = 0; i < text.length; i++) {\n const c = text[i];\n const next = text[i + 1];\n if (inString) {\n out += c;\n if (c === '\\\\') { out += next ?? ''; i++; continue; }\n if (c === quote) inString = false;\n continue;\n }\n if (c === '\"' || c === \"'\") { inString = true; quote = c; out += c; continue; }\n if (c === '/' && next === '/') { while (i < text.length && text[i] !== '\\n') i++; out += '\\n'; continue; }\n if (c === '/' && next === '*') { i += 2; while (i < text.length && !(text[i] === '*' && text[i + 1] === '/')) i++; i++; continue; }\n out += c;\n }\n return out.replace(/,(\\s*[}\\]])/g, '$1'); // trailing commas\n}\n\n/**\n * Import edges from a parsed source file: `import`/`export … from`, `require(…)` and dynamic `import(…)`.\n * Relative specifiers are included here and filtered later — the caller decides what counts as a package,\n * and keeping the raw edge makes this function reusable and easy to test.\n */\nexport function collectFileImports(sf: any, ts: TsModule): RawImport[] {\n const found: RawImport[] = [];\n const lineOf = (node: any): number | undefined => {\n try {\n return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;\n } catch {\n return undefined;\n }\n };\n\n const visit = (node: any) => {\n // import x, { a as b }, * as ns from 'mod' / import 'mod'\n if (ts.isImportDeclaration(node) && ts.isStringLiteralLike(node.moduleSpecifier)) {\n const names: string[] = [];\n const clause = node.importClause;\n if (clause?.name) names.push('default');\n const nb = clause?.namedBindings;\n if (nb) {\n if (ts.isNamespaceImport(nb)) names.push('*');\n else if (ts.isNamedImports(nb)) {\n // The EXPORTED name is what an advisory names; `import { merge as m }` is still `merge`.\n for (const el of nb.elements) names.push((el.propertyName ?? el.name).text);\n }\n }\n found.push({ specifier: node.moduleSpecifier.text, names, line: lineOf(node) });\n }\n // export { a } from 'mod' — an import edge that re-exports; the package is still pulled in.\n if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteralLike(node.moduleSpecifier)) {\n const names: string[] = [];\n const ec = node.exportClause;\n if (ec && ts.isNamedExports(ec)) for (const el of ec.elements) names.push((el.propertyName ?? el.name).text);\n else if (ec && ts.isNamespaceExport(ec)) names.push('*');\n else names.push('*'); // export * from 'mod'\n found.push({ specifier: node.moduleSpecifier.text, names, line: lineOf(node) });\n }\n // require('mod') and import('mod') — the call form carries no binding info at the call site, so the\n // marker name records HOW it was imported instead of inventing a binding.\n if (ts.isCallExpression(node)) {\n const arg = node.arguments[0];\n const isRequire = ts.isIdentifier(node.expression) && node.expression.text === 'require';\n const isDynamic = node.expression.kind === ts.SyntaxKind.ImportKeyword;\n if ((isRequire || isDynamic) && arg && ts.isStringLiteralLike(arg)) {\n found.push({ specifier: arg.text, names: [isRequire ? 'require' : 'import()'], line: lineOf(node) });\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return found;\n}\n\n/**\n * Module specifiers from raw text, without building a syntax tree — TypeScript's own pre-processor, the\n * same scan the compiler uses to discover a file's dependencies. Token-accurate (a specifier inside a\n * comment or string is not reported), and cheap enough to run over every file in a project.\n * Names are not recoverable this way; callers mark the result as name-incomplete.\n *\n * Returns **null** when the scan itself failed. That is deliberately distinct from an empty array: a file\n * we could not scan is not a file that imports nothing, and collapsing the two is what would let a server\n * conclude \"package absent\" from a gap in our own analysis.\n */\nexport function scanFileImports(text: string, ts: TsModule): RawImport[] | null {\n let refs: Array<{ fileName: string; pos: number }>;\n try {\n const pre = ts.preProcessFile(text, /* readImportFiles */ true, /* detectJavaScriptImports */ true);\n refs = pre.importedFiles ?? [];\n } catch {\n return null; // fail-open for the map, but the caller must record that the inventory is now partial\n }\n if (refs.length === 0) return [];\n const lineStarts = lineStartOffsets(text);\n return refs.map((r) => ({ specifier: r.fileName, names: [], line: lineAt(lineStarts, r.pos) }));\n}\n\n/**\n * Count imports whose module cannot be determined statically. Two shapes, one number — both feed\n * `coverage.importCoverageGaps.unresolvableImports`:\n *\n * 1. a COMPUTED specifier — `require(REGISTRY[kind])`, `import(name)`, `require(\"a\" + b)`\n * 2. an ESCAPED loader — `const r = require`, `(require)(x)`, `module.exports = require`\n *\n * The second is reported at the escape rather than at the later call: once the loader is behind another\n * name, what it loads is unknowable here whether or not the argument is a literal.\n *\n * `scanFileImports` cannot see these. It reads `ts.preProcessFile(...).importedFiles`, which reports\n * resolved literal specifiers only — a computed specifier produces no entry at all, so the import is\n * not merely unrecorded, it is invisible. That matters because the inventory's contract says a\n * package's ABSENCE is evidence when `importsComplete` is true, and `require(REGISTRY[kind])` makes\n * absence unprovable while leaving every read-and-scan check satisfied.\n *\n * Tokenised rather than parsed: this runs on files deliberately kept out of the AST pass, so it must\n * stay at scanner cost. Tokenising (rather than a regex) is what keeps `// require(x)` in a comment\n * and `\"require(y)\"` in a string from counting — a text match would clear the completeness flag on\n * prose about `require`, which trades a false negative for a permanent false alarm.\n */\nexport function countUnresolvableImports(text: string, ts: TsModule): number {\n let scanner: any;\n try {\n scanner = ts.createScanner(ts.ScriptTarget.Latest, /* skipTrivia */ true, undefined, text);\n } catch {\n return 0; // fail-open: the caller already treats an unscannable file as incomplete\n }\n\n // `require` does NOT arrive as an identifier: TypeScript scans it as the contextual `RequireKeyword`\n // (it appears in `import x = require(…)`). Keying on the token TEXT with a kind allowlist covers both\n // spellings, and survives a TS version that classifies it differently — which is worth the small\n // looseness here, because the failure mode of a missed kind is a silent zero count, i.e. exactly the\n // false \"complete\" this function exists to prevent.\n const CALLEE_KINDS = new Set<number>([\n ts.SyntaxKind.Identifier,\n ts.SyntaxKind.RequireKeyword,\n ts.SyntaxKind.ImportKeyword,\n ].filter((k) => k !== undefined) as number[]);\n\n // Three tokens of history, because one is not enough to identify the callee. The token that decides\n // whether this is CommonJS `require` sits on a different side of the name in each form:\n //\n // require(x) callee is the previous token\n // require?.(x) `?.` sits BETWEEN the name and `(` — the callee is two back\n // loader.require(x) an app method that merely shares the name — `.` sits BEFORE the callee\n // loader.require?.(x) both at once, so the qualifier is three back\n //\n // Getting either direction wrong is a real failure, and they fail in opposite ways: missing the\n // optional form leaves `importsComplete` true over an unresolvable import, while counting a member\n // method makes it permanently false for an app that named a method `require` — which trains a reader\n // to ignore the field. Hence a qualifier check rather than a looser name match.\n const DOT_KINDS = new Set<number>([ts.SyntaxKind.DotToken, ts.SyntaxKind.QuestionDotToken]\n .filter((k) => k !== undefined) as number[]);\n\n interface Token { kind: number | undefined; text: string }\n const EMPTY: Token = { kind: undefined, text: '' };\n // Most recent first: history[0] is the token before the current one.\n const history: [Token, Token, Token] = [EMPTY, EMPTY, EMPTY];\n const remember = (kind: number, text: string): void => {\n history[2] = history[1];\n history[1] = history[0];\n history[0] = { kind, text };\n };\n\n /**\n * Did the token just before `next` leave a bare `require` unresolvable?\n *\n * Deliberately asked about `require` only. `import` is a keyword that legitimately appears without a\n * following paren in every ESM file (`import qs from \"qs\"`, `import.meta.url`), so the same rule there\n * would report a gap for ordinary static imports — the exact always-false flag the member-method guard\n * exists to prevent.\n */\n const escapedLoaderReference = (next: number): boolean => {\n const callee = history[0];\n const qualifier = history[1];\n\n if (callee.kind === undefined || !CALLEE_KINDS.has(callee.kind) || callee.text !== 'require') return false;\n // Someone's method named `require` — not the loader.\n if (qualifier.kind !== undefined && DOT_KINDS.has(qualifier.kind)) return false;\n\n // Called in place (`require(…)` / `require?.(…)`) is the resolvable form the rest of this function\n // judges, and `require.resolve` / `require.cache` reach a property of the loader without loading a\n // module at all. Anything else means the loader itself became a value.\n return next !== ts.SyntaxKind.OpenParenToken\n && next !== ts.SyntaxKind.QuestionDotToken\n && next !== ts.SyntaxKind.DotToken;\n };\n\n let count = 0;\n\n try {\n for (let token = scanner.scan(); token !== ts.SyntaxKind.EndOfFileToken; token = scanner.scan()) {\n const text = scanner.getTokenText();\n\n // `require` used as a VALUE rather than called in place: `const r = require`, `(require)(x)`,\n // `module.exports = require`. Once the loader is behind another name, resolving what it loads\n // needs dataflow this scan does not do — so the honest answer is that the inventory has a gap,\n // and the conservative one is the same answer. Counted at the ESCAPE, not at the later call:\n // whatever `r(…)` loads is unknowable from here, literal argument or not.\n if (escapedLoaderReference(token)) count++;\n\n if (token !== ts.SyntaxKind.OpenParenToken) {\n remember(token, text);\n continue;\n }\n\n // `?.` immediately before the paren shifts both the callee and its qualifier one place back.\n const optionalCall = history[0].kind === ts.SyntaxKind.QuestionDotToken;\n const callee = optionalCall ? history[1] : history[0];\n const qualifier = optionalCall ? history[2] : history[1];\n\n const isRequireCall = callee.kind !== undefined\n && CALLEE_KINDS.has(callee.kind)\n && (callee.text === 'require' || callee.text === 'import')\n // A dot before the name means it is a property of something else, so this is that object's\n // method and says nothing about module loading.\n && !(qualifier.kind !== undefined && DOT_KINDS.has(qualifier.kind));\n\n if (!isRequireCall) {\n remember(token, text);\n continue;\n }\n\n remember(token, text);\n\n const argument = scanner.scan();\n const argumentText = scanner.getTokenText();\n remember(argument, argumentText);\n\n const isLiteral = argument === ts.SyntaxKind.StringLiteral\n || argument === ts.SyntaxKind.NoSubstitutionTemplateLiteral;\n\n if (!isLiteral) {\n // A template WITH substitutions (`require(\\`./\\${name}\\`)`) lands here too, correctly: its\n // value is not knowable statically either.\n count++;\n continue;\n }\n\n // Starting with a literal is not the same as BEING one: `require(\"node-\" + pkg)` opens with a\n // string and is still computed. The literal is the whole specifier only if the argument ends\n // right here — a `)`, or a `,` for `import(\"./m\", { with: … })`, where the literal is complete\n // and only import attributes follow. Anything else continues the expression.\n const following = scanner.scan();\n remember(following, scanner.getTokenText());\n\n const argumentEnded = following === ts.SyntaxKind.CloseParenToken\n || following === ts.SyntaxKind.CommaToken;\n\n if (!argumentEnded) count++;\n }\n\n // The loop exits on EOF without processing it, so a file ENDING in a bare `require`\n // (`module.exports = require`) would otherwise escape unnoticed.\n if (escapedLoaderReference(ts.SyntaxKind.EndOfFileToken)) count++;\n } catch {\n return count; // whatever was counted before the scanner gave up still clears the flag\n }\n\n return count;\n}\n\n/**\n * Aggregates per-file import edges into the per-package inventory. Order-independent: the output is\n * sorted, so two runs over the same tree produce byte-identical documents.\n */\nexport function createImportInventory(aliases: PathAlias[] = []) {\n interface Acc {\n specifiers: Set<string>;\n names: Set<string>;\n namesComplete: boolean;\n sites: ImportSite[];\n siteCount: number;\n }\n const byPackage = new Map<string, Acc>();\n\n return {\n /** @param parsed whether these edges came from a full parse (names are trustworthy) or the scan. */\n add(relFile: string, edges: RawImport[], parsed: boolean): void {\n for (const edge of edges) {\n const aliased = aliases.some((a) => (a.wildcard ? edge.specifier.startsWith(a.prefix) : edge.specifier === a.prefix));\n if (aliased) continue;\n const pkg = npmPackageOf(edge.specifier);\n if (!pkg) continue; // relative/absolute path: app code, not a dependency\n if (!isNpmPackageName(pkg)) continue; // an unaliased-but-bare path (`@/x`, `~/lib`)\n let acc = byPackage.get(pkg);\n if (!acc) {\n acc = { specifiers: new Set(), names: new Set(), namesComplete: true, sites: [], siteCount: 0 };\n byPackage.set(pkg, acc);\n }\n acc.specifiers.add(edge.specifier);\n for (const n of edge.names) acc.names.add(n);\n // One unparsed site makes the whole package's name set a subset — say so rather than imply\n // completeness from the names that happen to be present.\n if (!parsed) acc.namesComplete = false;\n acc.siteCount++;\n if (acc.sites.length < MAX_SITES) acc.sites.push({ file: relFile, line: edge.line });\n }\n },\n\n list(): ImportedPackage[] {\n return [...byPackage.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([pkg, acc]) => {\n const names = [...acc.names].sort();\n const entry: ImportedPackage = {\n package: pkg,\n specifiers: [...acc.specifiers].sort(),\n namesComplete: acc.namesComplete,\n sites: acc.sites,\n siteCount: acc.siteCount,\n recognizedSinkKinds: recognizedSinkKinds(pkg),\n };\n if (names.length > 0) entry.names = names;\n return entry;\n });\n },\n };\n}\n\nfunction lineStartOffsets(text: string): number[] {\n const starts = [0];\n for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) === 10) starts.push(i + 1);\n return starts;\n}\n\n/** 1-based line containing `pos`, by binary search over the line starts. */\nfunction lineAt(starts: number[], pos: number): number {\n let lo = 0;\n let hi = starts.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if ((starts[mid] ?? 0) <= pos) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1;\n}\n","import type { ApiInvocation, InvocationResolution, TsModule } from './types.js';\nimport { isShadowedByEnclosingBinding, rootIdentifier, spanOf } from './ast.js';\nimport { npmPackageOf, type Bindings } from './bindings.js';\nimport type { ModuleGraph } from './sinks.js';\n\n// Which dependency APIs the app actually CALLS — a different question from the sink analysis, and a much\n// cheaper one.\n//\n// A sink answers \"can request input reach a dangerous operation\". That is only askable for the handful of\n// API families the extractor models, which measured out at ~3.6% of real advisories. This answers \"is this\n// package's API invoked at all\", which is askable for every package and is the whole answer for an advisory\n// whose precondition is *calling* the vulnerable function rather than feeding it untrusted input.\n//\n// The discipline is the sink discipline, deliberately: a receiver we cannot trace to a dependency is not an\n// invocation of that dependency, no matter how suggestive the method name. `inferred` attribution — the\n// package guessed from another import in the same file — does not qualify at all here, because unlike a\n// sink there is no second signal (an argument role, a dangerous operation) to corroborate it.\n//\n// A record has two halves — the package and the API NAME — and tracing the value only establishes the first.\n// A name the APP chose is not part of the package's surface however faithfully the value traces: `loadConfig`\n// (a local function re-exported from a helper module) and `log` (`const log = createLogger()`) both trace to\n// a real dependency, and neither is an API that dependency has. Reporting one is worse than reporting\n// nothing: a consumer asking \"is the vulnerable function called\" gets a name that appears in no advisory,\n// while the call that IS in the advisory's surface goes unmentioned. So a name is reported only where it came\n// from the package itself, and calls we cannot name are counted, not invented.\n//\n// PARTIAL BY CONSTRUCTION, and that is not a parsing budget problem. Parsing every file would raise recall,\n// but dynamic property access (`client[method]()`), dynamic `import()`/`require()` with a computed\n// specifier, reflection, aliases we do not follow, generated code and syntax we cannot parse all remain\n// invisible. So absence here NEVER licenses \"the vulnerable API is not called\"; the document says so in\n// `coverage.apiInventoryLimitations` rather than carrying a boolean a consumer could misread.\n\n/** Sites kept per distinct invocation, so a hot API cannot dominate the document. */\nconst MAX_SITES = 3;\n\nexport interface InvocationContext {\n /** Absolute path of the file being analysed, for resolving relative re-exports. */\n file: string;\n /** The same file, repo-relative — part of the record's identity, so it must not vary by machine. */\n owner: string;\n graph: ModuleGraph;\n}\n\n/**\n * How the call expressions in a file classified. Four buckets rather than resolved-vs-not, because\n * \"resolved / everything else\" measures the APP, not the resolver: a codebase full of local helpers would\n * score badly through no fault of ours, and widening the parse would *lower* the number by finding more\n * local calls — precisely backwards for a metric meant to justify widening the parse.\n *\n * total every call/new expression seen — workload scale\n * dependency traced to a package AND nameable: exactly what the inventory records\n * local the callee is a known local binding or an enclosing parameter — correctly not a dependency\n * ambiguous a receiver we could not classify either way, a computed/dynamic callee, or a value that\n * traces to a package under a name the app chose (nothing to record — see `named` below)\n *\n * Resolver quality is `dependency / (dependency + ambiguous)`. `local` belongs in neither term: excluding a\n * local helper is a correct answer, not a miss.\n */\nexport interface CallCounts {\n total: number;\n dependency: number;\n local: number;\n ambiguous: number;\n}\n\n/** A value traced to a package, and how strong that trace is. */\ninterface Traced {\n pkg: string;\n specifier: string;\n resolution: InvocationResolution;\n /** Whether the name this value is known by here is the PACKAGE's own name for it. */\n named: boolean;\n /** The package's own name, when an intermediate module renamed the binding on import. */\n apiName?: string;\n}\n\n/** Collect resolved dependency calls from one parsed file, with the call classification alongside. */\nexport function collectInvocations(\n sf: any,\n ts: TsModule,\n bindings: Bindings,\n ctx: InvocationContext,\n): { invocations: ApiInvocation[]; counts: CallCounts } {\n const found: ApiInvocation[] = [];\n const counts: CallCounts = { total: 0, dependency: 0, local: 0, ambiguous: 0 };\n\n /** A name we can positively account for as app-local: declared in-file, or an enclosing parameter. */\n const isLocalName = (name: string, node: any): boolean =>\n bindings.locals.has(name) || isShadowedByEnclosingBinding(node, name, ts);\n\n const lineOf = (node: any): number | undefined => {\n try {\n return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;\n } catch {\n return undefined;\n }\n };\n\n /**\n * The package a local name traces to, and how — including one hop for a re-exported dependency value.\n *\n * `named` answers the second question a record needs: is this name the PACKAGE's, or the app's? It is\n * true only for a binding that came straight out of the package — an import/require here, or a\n * pass-through re-export from a local module. A value the app derived (`const log = createLogger()`, or a\n * local function whose return value happens to root in the package) carries a name the app invented, so\n * `named` is false and there is no API to report even though the package is certain. `apiName` carries the\n * package's own name for a pass-through, since an intermediate module may have renamed it on import.\n */\n const traceRoot = (root: string): Traced | null => {\n const specifier = bindings.resolve(root);\n if (specifier === undefined) return null;\n\n const direct = npmPackageOf(specifier);\n if (direct !== undefined) {\n // `direct` vs `factory` is already recorded by the bindings; default to direct when unknown so a\n // missing origin cannot silently upgrade a weaker claim.\n const resolution = bindings.originOf(root) ?? 'direct';\n return { pkg: direct, specifier, resolution, named: resolution === 'direct' };\n }\n\n // A relative specifier: the value may still be a dependency re-exported from a local module\n // (`export const db = createClient(...)` in lib/db.ts — the layout generated apps actually use).\n const exportName = bindings.exportNameOf(root) ?? root;\n const viaModule = ctx.graph.importedBinding(ctx.file, specifier, exportName);\n if (viaModule !== undefined) {\n return {\n pkg: viaModule.package,\n specifier,\n resolution: 'reexport',\n named: viaModule.origin === 'direct',\n apiName: viaModule.name,\n };\n }\n\n return null;\n };\n\n const push = (\n traced: Traced,\n api: string,\n receiver: string | undefined,\n kind: ApiInvocation['kind'],\n node: any,\n ) => {\n const span = spanOf(node);\n found.push({\n package: traced.pkg,\n specifiers: [traced.specifier],\n api,\n ...(receiver !== undefined ? { receiver } : {}),\n symbol: receiver !== undefined ? `${receiver}.${api}` : api,\n kind,\n // Only ever `import`: a global has no package to correlate against, and an inferred package is not\n // evidence about the value being called.\n attribution: 'import',\n resolution: traced.resolution,\n callCount: 1,\n sites: [{ file: ctx.owner, line: lineOf(node), start: span.start, end: span.end }],\n });\n };\n\n const visit = (node: any) => {\n if (ts.isCallExpression(node) || ts.isNewExpression(node)) {\n const callee = node.expression;\n counts.total++;\n\n if (ts.isIdentifier(callee)) {\n // `merge(a, b)` / `new Pool()` — the callee itself is the imported binding.\n const traced = traceRoot(callee.text);\n if (traced?.named) {\n // The package's own name for the binding: from the target module for a pass-through re-export,\n // otherwise this file's (`import { saveOrder as write }` → `saveOrder`).\n const api = traced.apiName ?? bindings.exportNameOf(callee.text) ?? callee.text;\n push(traced, api, undefined, ts.isNewExpression(node) ? 'construct' : 'call', node);\n counts.dependency++;\n } else if (traced) {\n // Traced to a package, under a name the app chose — `loadConfig()` from a helper module, or a\n // factory result called directly. The only name available is one the package does not export, so\n // there is nothing to record. Counted AMBIGUOUS rather than local or dependency: we failed to\n // name an API here, and filing that as either a correct exclusion or a recorded call would hide\n // the miss. (The real call is recorded where it is written — in the module that makes it.)\n counts.ambiguous++;\n } else if (isLocalName(callee.text, node)) {\n counts.local++;\n } else {\n counts.ambiguous++;\n }\n } else if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.name)) {\n // `pool.query(sql)` / `helper.exec(cmd)` — resolve the RECEIVER, never the method name. A\n // dangerous-looking method on an untraceable object is exactly the lookalike the corpus exists for.\n const root = rootIdentifier(callee.expression, ts);\n const traced = root !== undefined ? traceRoot(root) : null;\n if (traced && root !== undefined) {\n counts.dependency++;\n // A receiver name is only reported when the package itself supplies that name — a NAMED member\n // binding (`import { promises as fsp } from 'node:fs'` → `promises`). Everything else is the\n // app's own word for a value: `pool` re-exported from `./lib`, `Student` returned by\n // `sequelize.define()`, and — the quiet one — `JSON5` in `const JSON5 = require('json5')`, where\n // the module object's local name is pure convention. Reporting any of them makes `symbol` a\n // string no advisory contains: `JSON5.parse` where the advisory says `parse`.\n const receiver = traced.resolution === 'direct' && bindings.isPackageMember(root)\n ? bindings.exportNameOf(root) ?? root\n : undefined;\n push(traced, callee.name.text, receiver, 'member', node);\n } else if (root !== undefined && ts.isIdentifier(callee.expression) && isLocalName(root, node)) {\n // A method called DIRECTLY on a local binding or a handler parameter — `res.json()`,\n // `shape.build()`. Declining to attribute that to a package is a correct answer.\n counts.local++;\n } else {\n // Anything deeper is ambiguous even when the ROOT is local: in `res.locals.db.query()` the value\n // being called is whatever was stashed on `res.locals`, not the parameter itself, and a database\n // client is exactly what apps put there. Filing it as \"local\" would hide a real miss.\n counts.ambiguous++;\n }\n } else {\n counts.ambiguous++; // computed callee, IIFE, dynamic import — see the limitations note\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n\n return { invocations: found, counts };\n}\n\n/**\n * Aggregate invocations across files.\n *\n * Keyed by package + symbol + kind + resolution, so two call sites with DIFFERENT evidence stay separate\n * entries rather than being merged under whichever was seen first — the strength of the claim is part of\n * the record, not a detail to round off.\n */\nexport function createInvocationInventory() {\n const byKey = new Map<string, ApiInvocation>();\n\n return {\n add(invocations: ApiInvocation[]): void {\n for (const invocation of invocations) {\n const key = `${invocation.package}|${invocation.symbol}|${invocation.kind}|${invocation.resolution}`;\n const existing = byKey.get(key);\n if (existing === undefined) {\n byKey.set(key, { ...invocation });\n continue;\n }\n existing.callCount += invocation.callCount;\n for (const specifier of invocation.specifiers) {\n if (!existing.specifiers.includes(specifier)) existing.specifiers.push(specifier);\n }\n if (existing.sites.length < MAX_SITES) existing.sites.push(...invocation.sites.slice(0, MAX_SITES - existing.sites.length));\n }\n },\n\n list(): ApiInvocation[] {\n return [...byKey.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([, invocation]) => ({ ...invocation, specifiers: [...invocation.specifiers].sort() }));\n },\n };\n}\n","import { loadTypeScript } from './ts-loader.js';\nimport { extractInputMap, type ExtractOptions } from './extract.js';\nimport type { SiteInputMap } from './types.js';\n\nexport type { SiteInputMap, Endpoint, InputField, Sink, Flow, Coverage } from './types.js';\nexport type { ExtractOptions } from './extract.js';\n\n/**\n * Build the app's input-flow (\"attack surface\") map at build time. Resolves the target app's own\n * TypeScript to parse the source; returns { map: null, error } (never throws) when TS can't be\n * resolved, so the CLI can degrade with a clear message.\n */\nexport async function buildInputMap(\n cwd: string,\n options: ExtractOptions = {},\n): Promise<{ map: SiteInputMap | null; error?: string }> {\n const ts = await loadTypeScript(cwd);\n if (!ts) {\n return {\n map: null,\n error:\n 'Could not resolve a TypeScript compiler to parse the app. `map` uses your project’s own ' +\n '`typescript` (already a devDependency of a TypeScript app) — install it and retry.',\n };\n }\n const map = await extractInputMap(cwd, ts, options);\n return { map };\n}\n","import { readFileSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nimport type { PackageManager } from './guide.js';\nimport { runProtect, runVerify } from './protect/install/index.js';\nimport type { ProtectResult, VerifyReport } from './protect/install/types.js';\n\nconst SCAN_COMMAND = 'patchstack-connect scan';\nconst MARK_BUILD_COMMAND = 'patchstack-connect mark-build';\n\ninterface PackageJson {\n scripts?: Record<string, string>;\n [key: string]: unknown;\n}\n\nexport interface WireBuildScriptsResult {\n changed: boolean;\n strategy: 'build-chain' | 'lifecycle-hooks' | 'postinstall-only';\n detail: string;\n}\n\nexport interface SetupProtectionResult {\n install: ProtectResult;\n verification: VerifyReport;\n}\n\n/**\n * Install the runtime guard after setup has provisioned a site UUID, then inspect\n * the resulting seam. Verification is deliberately separate from the installer's\n * best-effort result: an adapter can scaffold files but still need a manual merge\n * when an existing framework seam cannot safely be overwritten.\n */\nexport function setupProtection(cwd: string): SetupProtectionResult {\n const install = runProtect(cwd);\n const verification = runVerify(cwd);\n return { install, verification };\n}\n\n/** Add `command` after an existing lifecycle hook without duplicating it. */\nfunction appendHook(existing: string | undefined, command: string): string {\n if (existing === undefined || existing.trim().length === 0) {\n return command;\n }\n if (existing.includes(command)) {\n return existing;\n }\n return `${existing} && ${command}`;\n}\n\n/**\n * Wire a scan after dependency installs and around the project's build without\n * invoking a shell. Bun skips npm-style pre/post build hooks, so Bun projects get\n * a direct build chain; other package managers get lifecycle hooks. Existing\n * commands are preserved and the operation is idempotent.\n */\nexport function wireBuildScripts(\n cwd: string,\n packageManager: PackageManager,\n): WireBuildScriptsResult {\n const target = path.join(cwd, 'package.json');\n const raw = readFileSync(target, 'utf8');\n const pkg = JSON.parse(raw) as PackageJson;\n const scripts = pkg.scripts ?? {};\n const build = scripts.build;\n const postinstall = appendHook(scripts.postinstall, SCAN_COMMAND);\n\n if (build === undefined || build.trim().length === 0) {\n if (postinstall === scripts.postinstall) {\n return {\n changed: false,\n strategy: 'postinstall-only',\n detail: 'dependency-install scan already wired; no build script to integrate.',\n };\n }\n scripts.postinstall = postinstall;\n } else if (packageManager === 'bun') {\n let nextBuild = build;\n if (!nextBuild.includes(SCAN_COMMAND)) {\n nextBuild = `${SCAN_COMMAND} && ${nextBuild}`;\n }\n if (!nextBuild.includes(MARK_BUILD_COMMAND)) {\n nextBuild = `${nextBuild} && ${MARK_BUILD_COMMAND}`;\n }\n if (nextBuild === build && postinstall === scripts.postinstall) {\n return {\n changed: false,\n strategy: 'build-chain',\n detail: 'dependency-install scan and build chain already wired.',\n };\n }\n scripts.postinstall = postinstall;\n scripts.build = nextBuild;\n } else {\n const prebuild = appendHook(scripts.prebuild, SCAN_COMMAND);\n const postbuild = appendHook(scripts.postbuild, MARK_BUILD_COMMAND);\n if (\n prebuild === scripts.prebuild &&\n postbuild === scripts.postbuild &&\n postinstall === scripts.postinstall\n ) {\n return {\n changed: false,\n strategy: 'lifecycle-hooks',\n detail: 'dependency-install, prebuild, and postbuild hooks are already wired.',\n };\n }\n scripts.postinstall = postinstall;\n scripts.prebuild = prebuild;\n scripts.postbuild = postbuild;\n }\n\n pkg.scripts = scripts;\n const indentMatch = raw.match(/^[\\t ]+(?=\")/m)?.[0];\n const indent = indentMatch?.includes('\\t') ? '\\t' : indentMatch?.length ?? 2;\n const trailingNewline = raw.endsWith('\\n') ? '\\n' : '';\n writeFileSync(target, `${JSON.stringify(pkg, null, indent)}${trailingNewline}`, 'utf8');\n\n if (build === undefined || build.trim().length === 0) {\n return {\n changed: true,\n strategy: 'postinstall-only',\n detail: 'added a dependency-install scan; package.json has no build script.',\n };\n }\n\n return packageManager === 'bun'\n ? {\n changed: true,\n strategy: 'build-chain',\n detail: 'added a dependency-install scan and chained scan/mark-build around the build.',\n }\n : {\n changed: true,\n strategy: 'lifecycle-hooks',\n detail: 'added scans to postinstall/prebuild and mark-build to postbuild.',\n };\n}\n"],"mappings":"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","names":["readFileSync","writeFileSync","path","readFile","path","readFile","path","readFile","path","path","readFile","readFile","readFile","readFile","path","readFile","path","path","path","path","readFile","readFile","readFile","path","path","path","readFile","path","path","walk","existsSync","readFileSync","readdirSync","statSync","path","existsSync","join","writeFileSync","existsSync","join","join","existsSync","writeFileSync","existsSync","mkdirSync","copyFileSync","join","join","existsSync","detect","wire","mkdirSync","copyFileSync","verify","join","existsSync","mkdirSync","copyFileSync","join","dirname","dirname","existsSync","join","mkdirSync","copyFileSync","detect","join","wire","verify","join","SPEC","detect","join","wire","verify","SPEC","detect","wire","verify","readFileSync","existsSync","readdirSync","join","dirname","walk","writeFileSync","existsSync","join","readFileSync","existsSync","mkdirSync","copyFileSync","readdirSync","lstatSync","join","existsSync","join","mkdirSync","copyFileSync","walk","readdirSync","lstatSync","readFileSync","join","changed","writeFileSync","existsSync","SPEC","SPEC","SPEC","existsSync","readFileSync","writeFileSync","path","WIDGET_NEEDLE","existsSync","path","readFileSync","walk","readdirSync","statSync","readFileSync","writeFileSync","path","createHash","createHash","path","writeFileSync","readFileSync","join","readFileSync","realpathSync","createHash","relative","readFileSync","readdirSync","statSync","join","relative","readFileSync","join","statSync","SKIP_DIRS","readdirSync","relative","path","readFileSync","join","createHash","relative","createHash","readFileSync","realpathSync","statSync","dirname","join","relative","readFileSync","realpathSync","relative","dirname","join","statSync","path","path","join2","read","readFileSync","join","readFileSync","join","lineOf","text","MAX_SITES","lineOf","realpathSync","readFileSync","relative","createHash","readFileSync","writeFileSync","path","path","readFileSync","writeFileSync","c","writeFileSync","readFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/parsers/index.ts","../src/types.ts","../src/parsers/consistency.ts","../src/parsers/npm.ts","../src/parsers/node_modules.ts","../src/parsers/pnpm.ts","../src/parsers/yarn.ts","../src/normalize.ts","../src/checksum.ts","../src/pulse-token.ts","../src/client.ts","../src/demo.ts","../src/config.ts","../src/mark-build.ts","../src/stack.ts","../src/guide.ts","../src/protect/install/util.ts","../src/protect/install/adapters/tanstack-supabase.ts","../src/protect/install/adapters/next.ts","../src/protect/install/adapters/sveltekit.ts","../src/protect/install/seam.ts","../src/protect/install/adapters/astro.ts","../src/protect/install/adapters/nuxt.ts","../src/protect/install/find-app.ts","../src/protect/install/register.ts","../src/protect/install/generic.ts","../src/protect/install/adapters/nestjs.ts","../src/protect/install/adapters/fastify.ts","../src/protect/install/adapters/express.ts","../src/protect/install/index.ts","../src/widget.ts","../src/login.ts","../src/map/ts-loader.ts","../src/map/extract.ts","../src/map/ast.ts","../src/map/bindings.ts","../src/map/sources.ts","../src/map/routes.ts","../src/map/surface.ts","../src/map/sinks.ts","../src/map/module-graph.ts","../src/map/coordinates.ts","../src/map/inputs.ts","../src/map/flows.ts","../src/map/entries.ts","../src/map/imports.ts","../src/map/invocations.ts","../src/map/index.ts","../src/setup.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\n\nimport { scanLockfile } from './parsers/index.js';\nimport { buildWirePayload } from './normalize.js';\nimport { computeManifestChecksum } from './checksum.js';\nimport {\n postInputMap,\n DEFAULT_ENDPOINT,\n buildClaimUrl,\n fetchSiteStatus,\n postManifest,\n postPackageRemoved,\n} from './client.js';\nimport {\n assertDemoDependency,\n assertPersistedSiteUuid,\n DemoError,\n inspectDemoDependency,\n readPersistedSiteUuid,\n renderDemoGuide,\n renderDemoTestCommands,\n resolveDemoScenario,\n waitForDemoRule,\n} from './demo.js';\nimport { persistApiKey, persistSiteUuid, resolveConfig, writeConfigFile } from './config.js';\nimport {\n buildInjectionSnippet,\n buildSourceMarkerSnippet,\n ensureSourceMarker,\n findHtmlFiles,\n hasJsxShell,\n injectMarker,\n productionGate,\n resolveBuildDir,\n} from './mark-build.js';\nimport {\n collectGuideState,\n countRemainingSteps,\n detectPackageManager,\n installCommand,\n renderGuideChecklist,\n resolveWidgetFileHint,\n} from './guide.js';\nimport { login, readPendingLogin, redeemIfApproved, startLogin, waitForApproval } from './login.js';\nimport { runProtect, runVerify } from './protect/install/index.js';\nimport { buildInputMap } from './map/index.js';\nimport { isProvenFlow } from './map/coordinates.js';\nimport { setupProtection, wireBuildScripts } from './setup.js';\nimport { detectStack, type StackDescriptor } from './stack.js';\nimport { PatchstackError } from './types.js';\nimport { buildWidgetTag, ensureSourceWidget, ensureWidgetInHtml } from './widget.js';\n\nconst HELP = `@patchstack/connect — scan your lockfile and report packages to Patchstack.\n\nUsage:\n patchstack-connect scan [options] Scan lockfile and POST to Patchstack.\n If no UUID is configured, the server\n provisions one and we persist it. After a\n successful post it also adds/updates the\n disclosure-widget <script> tag in the root\n HTML shell (index.html, public/index.html,\n or src/app.html) — opt out with\n \"widget\": false in .patchstackrc.json\n patchstack-connect setup [options] Finish the bounded project setup: run scan,\n manage the widget, install + verify runtime\n protection, and wire dependency/build scans.\n Never runs the project build\n patchstack-connect map [--dir <p>] [--out <f>] [--upload]\n Map the app's attack surface: entry points, the\n inputs each reads, the sinks it can reach, and\n evidence-backed input→sink flows (each labelled\n with how the link was established). Best-effort static\n analysis — reports the DETECTED surface, with\n coverage counters. Prints JSON (--out writes a\n file; --follow-symlinks leaves the project dir).\n Uses the app's own TypeScript\n patchstack-connect init <site-uuid> Optional: pre-seed .patchstackrc.json\n with an existing site UUID\n patchstack-connect status [options] Show current configuration and whether the\n site still exists on Patchstack (active /\n removed)\n patchstack-connect uninstall [options] Signal Patchstack that this package is being\n removed from the project. An unclaimed site\n record is deleted; a claimed site is flagged\n for its owner to remove in the dashboard.\n Does NOT touch local files — see the\n \"Uninstalling\" steps in AGENT-INSTALL.md\n patchstack-connect mark-build [options] Stamp built HTML with a production flag +\n build fingerprint, and ensure the widget\n tag in built pages (run as a postbuild step)\n patchstack-connect protect [--demo|--check] Install always-on runtime protection (the\n guard). Auto-wires supported server stacks;\n for others it scaffolds a\n generic guard + prints a wiring plan.\n --demo seeds a broad sample rule set (for\n demonstrations, not production).\n --check verifies the guard is wired (exit 1\n if not) — for the wire-then-verify loop.\n patchstack-connect demo node-serialize [--url URL] Run the production-backed node-serialize\n walkthrough: verify the vulnerable package,\n scan it, wait for live rule 18843, install +\n verify the guard, and print test requests.\n Does not install vulnerable dependencies.\n patchstack-connect demo-guide node-serialize Show a read-only, state-aware walkthrough for\n preparing, running, proving, and cleaning up\n the production-backed local demo.\n patchstack-connect guide [--full] Show this project's setup status (what's done,\n what's missing, with tailored commands), then\n print the full setup guide. --full prints the\n guide even when setup is complete\n patchstack-connect login [--wait] Recover this site's credential when\n .patchstackrc.json has been lost. Prints a link\n for the site's OWNER to approve in the dashboard.\n In a terminal it then waits. When the output is\n piped or captured — an assistant running it — it\n prints the link and EXITS, so the link is visible\n immediately. Run it AGAIN once the user confirms\n they approved: it resumes the same request rather\n than starting a new one, and finishes the flow.\n --wait blocks instead of returning. Use this\n instead of deleting\n .patchstackrc.json and re-scanning, which would\n provision a second site. Approving ROTATES the\n credential: CI, deploys and other machines using\n the old one must be updated. Not usable in CI\n patchstack-connect help Print this message\n\nOptions (for scan, setup, status, and uninstall):\n --site-uuid <uuid> Override the configured site UUID\n --endpoint <url> Override the API endpoint\n --dry-run (scan only) Show the payload without posting\n\nOptions (for mark-build):\n --dir <path> Build output directory (default: auto-detect\n dist/ build/ out/ .output/public)\n\nOptions (for demo and demo-guide):\n --url <url> Test endpoint printed at the end\n (default: http://localhost:3000/api/tasks)\n\nEnvironment:\n PATCHSTACK_SITE_UUID Site UUID\n PATCHSTACK_API_KEY WP-format site API key for block-log reporting (never put in the widget)\n PATCHSTACK_PULSE_AUTH Only if Pulse ingest uses a different credential from block-logs\n PATCHSTACK_TELEMETRY Set to off to disable block-log reporting\n PATCHSTACK_API_BASE API origin for /oauth/token and /api/logs/log (default: https://api.patchstack.com)\n PATCHSTACK_ENDPOINT API endpoint (default: https://api.patchstack.com/monitor/pulse/manifest)\n PATCHSTACK_TIMEOUT_MS Request timeout in ms (default: 30000)\n PATCHSTACK_ENVIRONMENT Manifest environment: production | sandbox (default: production)\n PATCHSTACK_MODE (protect) Runtime guard mode: block (default) | dry-run\n PATCHSTACK_ROUTE_WAF (protect) Set to 1 to also screen every request at the route level (opt-in)\n\nPrecedence: CLI flag > environment variable > .patchstackrc.json.\n\nExamples:\n npx @patchstack/connect setup\n npx @patchstack/connect scan\n npx @patchstack/connect scan --dry-run\n npx @patchstack/connect init 550e8400-e29b-41d4-a716-446655440000\n npx @patchstack/connect scan --site-uuid 550e8400-...-446655440000\n npx @patchstack/connect demo node-serialize\n npx @patchstack/connect demo-guide node-serialize\n`;\n\nconst VALUE_FLAGS = new Set(['site-uuid', 'endpoint', 'dir', 'url', 'out']);\n\ninterface ParsedArgs {\n command: string | null;\n positional: string[];\n flags: Map<string, string | true>;\n}\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const args = argv.slice(2);\n const positional: string[] = [];\n const flags = new Map<string, string | true>();\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!;\n if (!arg.startsWith('--')) {\n positional.push(arg);\n continue;\n }\n const stripped = arg.slice(2);\n const eqIdx = stripped.indexOf('=');\n if (eqIdx !== -1) {\n flags.set(stripped.slice(0, eqIdx), stripped.slice(eqIdx + 1));\n continue;\n }\n const next = args[i + 1];\n if (VALUE_FLAGS.has(stripped) && next !== undefined && !next.startsWith('--')) {\n flags.set(stripped, next);\n i++;\n } else {\n flags.set(stripped, true);\n }\n }\n\n return {\n command: positional.shift() ?? null,\n positional,\n flags,\n };\n}\n\nfunction getStringFlag(flags: Map<string, string | true>, name: string): string | undefined {\n const value = flags.get(name);\n return typeof value === 'string' ? value : undefined;\n}\n\nasync function runInit(args: ParsedArgs): Promise<number> {\n const uuid = args.positional[0];\n if (!uuid) {\n console.error('Error: site UUID is required.\\n');\n console.error('Usage: patchstack-connect init <site-uuid>');\n return 1;\n }\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(uuid)) {\n console.error(`Error: \"${uuid}\" does not look like a valid UUID.`);\n return 1;\n }\n\n const target = await writeConfigFile(process.cwd(), { siteUuid: uuid });\n console.log(`Wrote ${target}`);\n console.log('');\n console.log('Next: run `npx @patchstack/connect scan` to send your first manifest.');\n return 0;\n}\n\nasync function runLogin(args: ParsedArgs): Promise<number> {\n // CI has no browser and no human; build agents must not print credentials\n // into logs. Deploys use PATCHSTACK_PULSE_AUTH from the platform's secrets.\n if (process.env.CI !== undefined && process.env.CI !== '' && process.env.CI !== 'false') {\n console.error('`login` is interactive and cannot run in CI. Set PATCHSTACK_PULSE_AUTH instead.');\n return 1;\n }\n\n const config = await resolveConfig({\n cwd: process.cwd(),\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n\n const approved = () => {\n // The value itself is never printed — only that it landed.\n console.log('\\n ✓ Credential restored and saved to .patchstackrc.json.');\n console.log(' The previous credential no longer works. Update it anywhere else it was set:');\n console.log(' CI secrets, hosting env vars, preview environments, other checkouts.\\n');\n return 0;\n };\n\n // Resuming a request whose link has already been handed to the user.\n if (args.flags.has('wait')) {\n const pending = config.siteUuid === null ? null : readPendingLogin(config.siteUuid);\n\n if (pending === null) {\n console.error('\\n No login is waiting for approval. Run `patchstack-connect login` first.\\n');\n return 1;\n }\n\n const resumed = await waitForApproval(config, pending);\n if (resumed.status === 'approved') return approved();\n\n console.error(`\\n ${resumed.message ?? 'Login failed.'}\\n`);\n return 1;\n }\n\n const prompt = (userCode: string, verificationUri: string) => {\n console.log(`\\n Your code: ${userCode}`);\n console.log(` Approve at: ${verificationUri}\\n`);\n // Said before approval, not after: the person deciding needs to know it is\n // a rotation, and an assistant relaying this has to pass the warning on.\n console.log(\" Open that link and approve it as the site's owner. Approving issues a new\");\n console.log(' credential and stops the current one working — CI, deploys and any other');\n console.log(' machine using it will need the new value.\\n');\n };\n\n // Nobody is watching this stream. Blocking here would hide the link until the\n // command exits — by which time the code has expired — so hand it over and\n // let the caller decide when to wait.\n if (process.stdout.isTTY !== true) {\n // Running it again resumes rather than restarts. An assistant that comes\n // back after the user approves finishes the flow whether or not it\n // remembered --wait, and re-running never invalidates a link the user is\n // still looking at.\n const existing = config.siteUuid === null ? null : readPendingLogin(config.siteUuid);\n\n if (existing !== null && Date.now() < existing.expiresAt) {\n const outcome = await redeemIfApproved(config, existing);\n\n if (outcome === 'approved') return approved();\n\n if (outcome === 'pending') {\n const secondsLeft = Math.round((existing.expiresAt - Date.now()) / 1000);\n console.log(`\\n Still waiting for approval of code ${existing.userCode}.`);\n console.log(` Approve at: ${existing.verificationUri}`);\n console.log(` (valid for another ${secondsLeft}s — run this again once the user confirms)\\n`);\n return 0;\n }\n // 'expired' falls through and starts a fresh request below.\n }\n\n const started = await startLogin(config);\n\n if (started.status !== 'started' || started.pending === undefined) {\n console.error(`\\n ${started.message ?? 'Login failed.'}\\n`);\n return 1;\n }\n\n prompt(started.pending.userCode, started.pending.verificationUri);\n console.log(' Give that link to the user. When they confirm they have approved it, run');\n console.log(' this same command again (or `login --wait` to block until they do).\\n');\n\n return 0;\n }\n\n const result = await login(config, (userCode, verificationUri) => {\n prompt(userCode, verificationUri);\n console.log(' Waiting for approval (the code expires in 10 minutes)…');\n });\n\n if (result.status === 'approved') return approved();\n\n console.error(`\\n ${result.message ?? 'Login failed.'}\\n`);\n\n return 1;\n}\n\nasync function runMap(args: ParsedArgs): Promise<number> {\n const cwd = getStringFlag(args.flags, 'dir') ?? process.cwd();\n const { map, error } = await buildInputMap(cwd, {\n followSymlinks: args.flags.get('follow-symlinks') === true,\n });\n if (!map) {\n console.error(`patchstack: ${error}`);\n return 1;\n }\n // Human summary → stderr; the JSON → stdout (so it can be piped / written). Report PROVEN flows\n // separately from the inventories: only a proven tier is evidence that an input reaches a sink.\n const inputs = map.endpoints.reduce((n, e) => n + e.inputs.length, 0);\n const sinks = map.endpoints.reduce((n, e) => n + e.sinks.length, 0);\n const proven = map.endpoints.reduce((n, e) => n + e.flows.filter((f) => isProvenFlow(f.confidence)).length, 0);\n const c = map.coverage;\n console.error(\n `patchstack: ${map.endpoints.length} entry point(s), ${inputs} input(s), ${sinks} sink(s), ` +\n `${proven} proven input→sink flow(s) [${map.framework}].`,\n );\n console.error(\n // All three buckets, explicitly: \"6/66 parsed\" reads as \"91% unanalysed\" when the other 60 files\n // simply contain no server entry point (most of a project is client code). Only `skipped` is a\n // failure to analyse.\n `patchstack: ${c.filesDiscovered} file(s) found — ${c.filesParsed} analysed, ` +\n `${c.filesPreFiltered} skipped (no server entry point)` +\n (c.filesSkipped ? `, ${c.filesSkipped} could not be analysed` : '') +\n `. DETECTED surface only — static analysis is best-effort; every flow carries the tier it was ` +\n `established at (\"exact-local\" and \"transformed-local\" are proven; \"imported\", \"heuristic\" and ` +\n `\"unknown\" are not).`,\n );\n const invoked = map.apiInvocations ?? [];\n if (invoked.length > 0) {\n const c = map.coverage as unknown as Record<string, number>;\n const dependency = c.callsDependency ?? 0;\n const ambiguous = c.callsAmbiguous ?? 0;\n // Resolver quality, NOT \"share of all calls\": local helpers are excluded from both terms, because\n // declining to attribute `res.json()` to a package is a correct answer rather than a miss.\n const denominator = dependency + ambiguous;\n const quality = denominator > 0 ? Math.round((100 * dependency) / denominator) : 100;\n console.error(\n `patchstack: ${invoked.length} dependency API call(s) resolved across ${new Set(invoked.map((i) => i.package)).size} package(s) ` +\n `from ${c.callsTotal ?? 0} call site(s) — ${quality}% of dependency-candidate receivers resolved ` +\n `(${c.callsLocal ?? 0} local, ${ambiguous} ambiguous). Positive evidence only: absence here never ` +\n `means an API is not called.`,\n );\n }\n const imported = map.imports ?? [];\n if (imported.length > 0) {\n // The unmodelled count is the honest headline: it is how much of the dependency surface this map\n // cannot speak to at all, and a reader who only sees flows would never learn it.\n const unmodelled = imported.filter((d) => d.recognizedSinkKinds.length === 0).length;\n console.error(\n `patchstack: ${imported.length} package(s) imported — ${unmodelled} with no recognized sink family, ` +\n `so a vulnerability in those cannot be judged reachable or unreachable from this map.`,\n );\n }\n const json = JSON.stringify(map, null, 2);\n const out = getStringFlag(args.flags, 'out');\n if (out) {\n writeFileSync(out, json);\n console.error(`patchstack: wrote ${out}`);\n } else if (args.flags.get('upload') !== true) {\n // With --upload the map goes to Patchstack instead of stdout: printing a full structural document\n // AND sending it is noise, and the interesting output becomes what the server did with it.\n console.log(json);\n }\n\n // Opt-in, never implied. This is the only path that sends anything derived from source code, so it\n // takes an explicit flag rather than happening because a site UUID exists.\n if (args.flags.get('upload') === true) {\n if (map.endpoints.length === 0) {\n console.error('patchstack: nothing to upload — no server entry points were detected.');\n return 0;\n }\n // Same resolution order as every other network path: CLI flags, then env, then `.patchstackrc.json`.\n const config = await resolveConfig({\n cwd,\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n const outcome = await postInputMap(config, map);\n if (outcome.result === 'stored') {\n console.error(`patchstack: uploaded the attack surface (revision ${outcome.revision}).`);\n } else if (outcome.result === 'unchanged') {\n console.error(`patchstack: attack surface unchanged since revision ${outcome.revision} — nothing to store.`);\n } else if (outcome.result === 'skipped') {\n console.error(`patchstack: did not upload the attack surface — ${outcome.message}`);\n } else {\n // Fail-open: this runs inside someone's build, so a Patchstack problem must not fail it.\n console.error(`patchstack: could not upload the attack surface — ${outcome.message}`);\n }\n }\n return 0;\n}\n\nasync function runScan(\n args: ParsedArgs,\n options: { showRemainingSetup?: boolean } = {},\n): Promise<number> {\n const dryRun = args.flags.get('dry-run') === true;\n const config = await resolveConfig({\n cwd: process.cwd(),\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n const manifest = await scanLockfile(process.cwd());\n for (const warning of manifest.warnings ?? []) {\n console.warn(`patchstack: ${warning}`);\n }\n const { payload, stats } = buildWirePayload(manifest);\n\n console.log(\n `Found ${payload.packages.length} unique package versions across ${stats.uniqueNames} package names (${manifest.ecosystem} ecosystem).`,\n );\n console.log(\n `Reporting under the ${config.environment} environment (override with PATCHSTACK_ENVIRONMENT).`,\n );\n if (config.endpoint !== DEFAULT_ENDPOINT) {\n console.log(\n `Using endpoint override: ${config.endpoint} (set via --endpoint, PATCHSTACK_ENDPOINT, or .patchstackrc.json).`,\n );\n }\n if (stats.duplicateNames.length > 0) {\n const sample = stats.duplicateNames.slice(0, 10).join(', ');\n const more =\n stats.duplicateNames.length > 10 ? `, +${stats.duplicateNames.length - 10} more` : '';\n console.log(\n `${stats.duplicateNames.length} package(s) appear at multiple versions: ${sample}${more}`,\n );\n }\n\n if (dryRun) {\n console.log('');\n if (config.siteUuid === null) {\n console.log('--dry-run: no site UUID configured. A real run would provision one.');\n } else {\n console.log(`--dry-run: not posting to Patchstack (site UUID ${config.siteUuid}).`);\n }\n console.log('Payload preview:');\n const preview = JSON.stringify(payload, null, 2).split('\\n');\n console.log(preview.slice(0, Math.min(preview.length, 30)).join('\\n'));\n if (preview.length > 30) {\n console.log(` ... (${preview.length - 30} more lines)`);\n }\n return 0;\n }\n\n // Ahead of the post deliberately. The marker carries no site UUID and needs no\n // server round-trip, while `scan` is commonly chained as `scan || true`, so a\n // failed or offline post must not be what decides whether a published build\n // gets its production flag. --dry-run has already returned by here.\n if (config.widget) {\n reportSourceMarker(detectStack(payload.packages).framework);\n }\n\n const provisioning = config.siteUuid === null;\n if (provisioning) {\n console.log('No site UUID configured — provisioning a new Patchstack site from this manifest…');\n }\n\n const response = await postManifest(config, payload);\n\n // The server always returns the UUID. If we didn't have one, persist it so\n // every subsequent scan targets the same site.\n if (provisioning && response.uuid !== undefined && response.uuid.length > 0) {\n const target = await persistSiteUuid(process.cwd(), response.uuid);\n console.log(`Provisioned site ${response.uuid}. Saved UUID to ${target}.`);\n }\n if (typeof response.api_key === 'string' && response.api_key.length > 0) {\n // One credential for both paths: Pulse resolution falls back to apiKey, so\n // a second copy under pulseAuth bought nothing except an obligation to keep\n // the two in step. Never printed — only the path it landed in.\n const target = await persistApiKey(process.cwd(), response.api_key);\n console.log(`Saved API key to ${target} (authenticates Pulse ingest and block-log reporting; keep out of the public widget).`);\n }\n\n if (response.stored) {\n console.log(`Stored manifest #${response.manifest_id} (checksum ${response.checksum}).`);\n } else if (response.reason === 'duplicate') {\n console.log('Manifest unchanged since last scan — nothing to store.');\n } else {\n console.log(`Server response: ${response.message ?? JSON.stringify(response)}`);\n }\n\n // With a UUID in hand (existing or freshly provisioned), ensure the\n // disclosure widget's managed tag in the source HTML shell so the very next\n // preview reload shows the \"Report a vulnerability\" button. Best-effort and\n // opt-out-able; a failed post never reaches this point, and --dry-run\n // returned above.\n const effectiveUuid = config.siteUuid ?? response.uuid ?? null;\n if (config.widget && effectiveUuid !== null && effectiveUuid.length > 0) {\n reportSourceWidget(effectiveUuid);\n }\n\n // On the first scan (provisioning), surface the dashboard URL so the user can\n // attach this site to their Patchstack account. `npx @patchstack/connect status`\n // re-displays it any time.\n if (provisioning && response.uuid !== undefined && response.uuid.length > 0) {\n console.log('');\n console.log('Open this dashboard link to view vulnerability reports:');\n console.log(` ${buildClaimUrl(config.endpoint, response.uuid)}`);\n if (config.endpoint !== DEFAULT_ENDPOINT) {\n console.log(' (this URL inherits the endpoint override above)');\n }\n }\n\n // A scan can't wire the build hooks itself — an agent that runs `scan` but not\n // `guide` (a common shortcut) otherwise sees the widget + claim URL and assumes\n // setup is finished. Surface whatever is still missing so the loop actually closes.\n if (options.showRemainingSetup !== false) {\n try {\n const state = await collectGuideState(process.cwd());\n const remaining = countRemainingSteps(state);\n if (remaining > 0) {\n const hooksMissing = !(state.prebuildWired && state.postbuildWired);\n console.log('');\n console.log(\n `Setup not complete — ${remaining} step(s) remaining${hooksMissing ? \", including the package.json build hooks (which scan can't wire)\" : ''}.`,\n );\n console.log('Run `npx @patchstack/connect guide` for the exact steps to finish for this project.');\n }\n } catch {\n // Best-effort: never turn a successful scan into a failure over this nudge.\n }\n }\n\n return 0;\n}\n\n/**\n * Run the source-widget pass for `scan` and narrate the outcome. Never throws:\n * widget management is a convenience layered on top of a successful scan and\n * must not turn one into a failure.\n */\nfunction reportSourceWidget(siteUuid: string): void {\n try {\n const result = ensureSourceWidget(process.cwd(), siteUuid);\n switch (result.action) {\n case 'added':\n console.log(`Widget: added the \"Report a vulnerability\" tag to ${result.shell}. Reload your preview to see it.`);\n break;\n case 'updated':\n console.log(`Widget: updated the managed tag in ${result.shell} to site ${siteUuid}.`);\n break;\n case 'unchanged':\n console.log(`Widget: already installed in ${result.shell}.`);\n break;\n case 'manual':\n console.log(`Widget: found an existing (manual) install in ${result.shell} — left untouched.`);\n break;\n case 'no-body':\n console.log(`Widget: ${result.shell} has no </body> tag to anchor on. Add this tag to your root layout manually:`);\n console.log(` ${buildWidgetTag(siteUuid)}`);\n break;\n case 'no-shell':\n console.log('Widget: no plain HTML shell found (index.html / public/index.html / src/app.html).');\n console.log('Add this tag to your root layout before </body> (run `guide` for framework-specific placement):');\n console.log(` ${buildWidgetTag(siteUuid)}`);\n break;\n }\n if (result.action === 'added' || result.action === 'updated') {\n console.log(' (opt out any time with \"widget\": false in .patchstackrc.json)');\n }\n } catch (err) {\n console.warn(`Widget: skipped (${(err as Error).message}).`);\n }\n}\n\n/**\n * Run the production-marker pass for `scan` and narrate the outcome. Never\n * throws, for the same reason the widget pass doesn't: this is a convenience on\n * top of a successful scan and must not turn one into a failure.\n *\n * `scan` is a pre-build hook, so an edit here is compiled into the build that\n * follows. On a server-rendered root that is the only way the marker reaches\n * production — `mark-build` runs after the build and has no HTML to stamp.\n */\nfunction reportSourceMarker(framework: string | null): void {\n try {\n const shell = resolveWidgetFileHint(process.cwd(), framework);\n if (shell === null || shell.toLowerCase().endsWith('.html')) {\n // An HTML shell needs nothing here: mark-build stamps the built copy.\n return;\n }\n\n const result = ensureSourceMarker(process.cwd(), shell, framework);\n switch (result.action) {\n case 'added':\n console.log(`Production marker: added to ${shell} (guarded by ${productionGate(framework)}).`);\n console.log(' This root is server-rendered, so the marker ships in source rather than built HTML.');\n break;\n case 'manual':\n console.log(`Production marker: already set in ${shell} — left untouched.`);\n break;\n case 'no-anchor':\n case 'unsupported':\n console.log(\n `Production marker: ${shell} needs it by hand — without it the widget reads the published site as build mode.`,\n );\n if (hasJsxShell(framework)) {\n for (const line of buildSourceMarkerSnippet(framework).split('\\n')) {\n console.log(` ${line}`);\n }\n } else {\n console.log(\n ` Emit <script>window.__PATCHSTACK_PROD__=true;</script> only when ${productionGate(framework)}.`,\n );\n }\n break;\n }\n } catch (err) {\n console.warn(`Production marker: skipped (${(err as Error).message}).`);\n }\n}\n\nasync function runProtectCommand(args: ParsedArgs): Promise<number> {\n // `--check`: verify the guard is wired (for the agent/CI loop). Non-zero exit if not.\n if (args.flags.get('check') === true) {\n const report = runVerify(process.cwd());\n console.log(`patchstack protect --check (${report.stack}):`);\n for (const c of report.checks) {\n console.log(` ${c.ok ? '✓' : '✗'} ${c.label}${!c.ok && c.hint ? ` — ${c.hint}` : ''}`);\n }\n console.log(report.wired ? 'guard is wired ✓' : 'guard is NOT fully wired ✗');\n return report.wired ? 0 : 1;\n }\n // Best-effort: like mark-build, this runs during builds and must never fail one.\n const demo = args.flags.get('demo') === true;\n try {\n runProtect(process.cwd(), { demo });\n } catch (err) {\n console.warn(`patchstack protect: skipped (${(err as Error).message}).`);\n }\n return 0;\n}\n\nasync function runDemoCommand(args: ParsedArgs): Promise<number> {\n try {\n const scenario = resolveDemoScenario(args.positional[0]);\n const cwd = process.cwd();\n const config = await resolveConfig({\n cwd,\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n requireSiteUuid: true,\n });\n if (config.environment !== 'production') {\n throw new DemoError(\n 'The production-backed demo requires PATCHSTACK_ENVIRONMENT=production. Unset the sandbox override and try again.',\n );\n }\n\n await assertPersistedSiteUuid(cwd, config.siteUuid!);\n await assertDemoDependency(cwd, scenario);\n console.log(`Patchstack production demo — ${scenario.packageName}@${scenario.packageVersion}`);\n console.log(` Site: ${config.siteUuid}`);\n console.log('');\n console.log('1. Report the current npm manifest');\n const scanCode = await runScan(args, { showRemainingSetup: false });\n if (scanCode !== 0) return scanCode;\n\n console.log('');\n console.log(`2. Wait for live virtual-patch rule ${scenario.ruleId}`);\n const rule = await waitForDemoRule(config.endpoint, config.siteUuid!, scenario, {\n requestTimeoutMs: config.timeoutMs,\n });\n console.log(`Rule ready: ${rule.id}${rule.title ? ` — ${rule.title}` : ''}`);\n\n console.log('');\n console.log('3. Install and verify the runtime guard');\n const result = runProtect(cwd);\n if (result.status === 'unsupported') {\n throw new DemoError(\n `Runtime protection is not supported for this stack. Supported: ${result.supported.join(', ')}.`,\n );\n }\n console.log(`Guard installer: ${result.adapter} (${result.status})`);\n const report = runVerify(cwd);\n for (const check of report.checks) {\n console.log(` ${check.ok ? '✓' : '✗'} ${check.label}${!check.ok && check.hint ? ` — ${check.hint}` : ''}`);\n }\n if (!report.wired) {\n throw new DemoError(\n `The ${report.stack} guard is not fully wired. Complete the failed check above, then run this command again.`,\n );\n }\n\n console.log('');\n console.log('Production virtual patch is ready.');\n console.log('');\n console.log(\n renderDemoTestCommands(\n getStringFlag(args.flags, 'url') ?? 'http://localhost:3000/api/tasks',\n scenario,\n ),\n );\n return 0;\n } catch (error) {\n if (error instanceof DemoError) {\n console.error(`Demo error: ${error.message}`);\n return 1;\n }\n throw error;\n }\n}\n\nasync function runDemoGuideCommand(args: ParsedArgs): Promise<number> {\n try {\n const scenario = resolveDemoScenario(args.positional[0]);\n const cwd = process.cwd();\n const config = await resolveConfig({ cwd });\n const [siteUuid, dependency] = await Promise.all([\n readPersistedSiteUuid(cwd),\n inspectDemoDependency(cwd, scenario),\n ]);\n console.log(\n renderDemoGuide({\n scenario,\n packageManager: detectPackageManager(cwd),\n siteUuid,\n dependency,\n environment: config.environment,\n url: getStringFlag(args.flags, 'url') ?? 'http://localhost:3000/api/tasks',\n }),\n );\n return 0;\n } catch (error) {\n if (error instanceof DemoError) {\n console.error(`Demo guide error: ${error.message}`);\n return 1;\n }\n throw error;\n }\n}\n\nasync function runGuide(args: ParsedArgs): Promise<number> {\n // The live checklist first: what this project already has and what's missing,\n // with commands tailored to it. Best-effort — a project we can't inspect\n // still gets the reference doc.\n let allDone = false;\n try {\n const state = await collectGuideState(process.cwd());\n const useColor = process.stdout.isTTY === true && process.env.NO_COLOR === undefined;\n console.log(renderGuideChecklist(state, useColor));\n allDone = countRemainingSteps(state) === 0;\n } catch {\n // fall through to the static guide\n }\n\n // A fully green project doesn't need the ~90-line manual again on every\n // re-run — point at it instead. `--full` always prints it.\n if (allDone && args.flags.get('full') !== true) {\n console.log('');\n console.log(\n 'Full reference guide: `npx @patchstack/connect guide --full` (or read node_modules/@patchstack/connect/AGENT-INSTALL.md).',\n );\n return 0;\n }\n\n console.log('');\n console.log('———— Full reference guide (ships as AGENT-INSTALL.md) ————');\n console.log('');\n\n // AGENT-INSTALL.md ships at the package root, one level above dist/ (and\n // above src/ when running unbundled), so the same relative path works in both.\n const guidePath = new URL('../AGENT-INSTALL.md', import.meta.url);\n console.log(readFileSync(guidePath, 'utf8'));\n return 0;\n}\n\nasync function runSetup(args: ParsedArgs): Promise<number> {\n if (args.flags.get('dry-run') === true) {\n console.error('Error: setup does not support --dry-run. Use `scan --dry-run` to preview the manifest.');\n return 1;\n }\n\n const before = await collectGuideState(process.cwd());\n if (!before.hasPackageJson) {\n console.error('Error: no package.json found. Run setup from the project root.');\n return 1;\n }\n if (before.installed === null) {\n console.error(\n `Error: @patchstack/connect is not declared in package.json.\\nRun: ${installCommand(before.packageManager)}`,\n );\n return 1;\n }\n\n console.log('Patchstack setup — applying bounded project changes');\n console.log(' 1. Scan dependencies, provision/reuse the site, and manage the source widget');\n const scanCode = await runScan(args, { showRemainingSetup: false });\n if (scanCode !== 0) {\n return scanCode;\n }\n\n console.log('');\n console.log(' 2. Install and verify runtime protection');\n const protection = setupProtection(process.cwd());\n if (protection.verification.wired) {\n console.log(`Runtime protection: wired (${protection.verification.stack}).`);\n } else {\n console.log(`Runtime protection: manual wiring remains (${protection.verification.stack}):`);\n for (const check of protection.verification.checks) {\n console.log(` ${check.ok ? '✓' : '✗'} ${check.label}${!check.ok && check.hint ? ` — ${check.hint}` : ''}`);\n }\n console.log('Run `npx @patchstack/connect protect --check` after completing the failed checks.');\n }\n\n console.log('');\n console.log(' 3. Wire dependency-install and production-build scans into package.json');\n const wired = wireBuildScripts(process.cwd(), before.packageManager);\n console.log(`Build integration: ${wired.detail}`);\n\n console.log('');\n console.log(' 4. Verify setup status');\n const after = await collectGuideState(process.cwd());\n const useColor = process.stdout.isTTY === true && process.env.NO_COLOR === undefined;\n console.log(renderGuideChecklist(after, useColor));\n\n const remaining = countRemainingSteps(after);\n if (remaining > 0) {\n console.log('');\n console.log(`Setup applied its bounded changes; ${remaining} manual step(s) remain above.`);\n }\n return 0;\n}\n\nasync function runStatus(args: ParsedArgs): Promise<number> {\n const config = await resolveConfig({\n cwd: process.cwd(),\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n console.log(`Site UUID: ${config.siteUuid ?? '(none yet — the next `scan` will provision one)'}`);\n console.log(\n `Endpoint: ${config.endpoint}${config.endpoint === DEFAULT_ENDPOINT ? '' : ' (override)'}`,\n );\n console.log(`Timeout: ${config.timeoutMs}ms`);\n console.log(`Environment: ${config.environment}`);\n if (config.siteUuid !== null) {\n console.log(`Dashboard URL: ${buildClaimUrl(config.endpoint, config.siteUuid)}`);\n\n switch (await fetchSiteStatus(config)) {\n case 'active':\n console.log('Site status: active on Patchstack');\n break;\n case 'removed':\n console.log('Site status: removed from Patchstack');\n console.log(\n ' The site record no longer exists (deleted from the dashboard or via the',\n );\n console.log(\n ' widget uninstall flow). The local integration files are still in this',\n );\n console.log(\n ' project — see \"Uninstalling\" in AGENT-INSTALL.md to remove them.',\n );\n break;\n case 'unknown':\n console.log('Site status: could not be verified (Patchstack unreachable)');\n break;\n }\n }\n return 0;\n}\n\nasync function runUninstall(args: ParsedArgs): Promise<number> {\n const config = await resolveConfig({\n cwd: process.cwd(),\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n cliEndpoint: getStringFlag(args.flags, 'endpoint'),\n });\n\n if (config.siteUuid === null) {\n console.log('No site UUID configured — there is no site record to signal about.');\n console.log('Continue with the local removal steps in AGENT-INSTALL.md (\"Uninstalling\").');\n return 0;\n }\n\n console.log(`Signalling Patchstack that @patchstack/connect is being removed (site ${config.siteUuid})…`);\n const outcome = await postPackageRemoved(config);\n\n switch (outcome.result) {\n case 'deleted':\n console.log('Site record removed from Patchstack (the site was unclaimed).');\n break;\n case 'flagged':\n console.log('This site is claimed by a Patchstack account, so its record was kept and flagged.');\n console.log('Its owner can remove it at https://app.patchstack.com to free the site slot.');\n break;\n case 'gone':\n console.log('The site record no longer exists on Patchstack — nothing to signal.');\n break;\n case 'failed':\n console.warn(`Could not signal Patchstack${outcome.message !== null ? ` (${outcome.message})` : ''}.`);\n console.warn('The site record may remain — it can always be removed from the dashboard at https://app.patchstack.com.');\n break;\n }\n\n console.log('');\n console.log('This command only signals Patchstack. The local integration files must still be');\n console.log('removed — follow the \"Uninstalling\" steps in AGENT-INSTALL.md.');\n // Never fail the uninstall flow over the signal: local removal must proceed.\n return 0;\n}\n\n/** One-line, human-readable summary of a detected stack for CLI output. */\nfunction describeStack(stack: StackDescriptor): string | null {\n const parts = [stack.builder, stack.framework, stack.ui, stack.runtime].filter(\n (part): part is string => part !== null,\n );\n if (stack.hostingEnvKeys.length > 0) {\n parts.push(`${stack.hostingEnvKeys.length} hosting env key(s)`);\n }\n return parts.length > 0 ? parts.join(' · ') : null;\n}\n\nasync function runMarkBuild(args: ParsedArgs): Promise<number> {\n const cwd = process.cwd();\n\n // Compute the build fingerprint and stack descriptor from the lockfile.\n // Best-effort: mark-build is a postbuild step and must never fail the build, so\n // a missing/unreadable lockfile just means we stamp the production flag without\n // a fingerprint or stack.\n let checksum: string | null = null;\n let stack: StackDescriptor | null = null;\n try {\n const manifest = await scanLockfile(cwd);\n for (const warning of manifest.warnings ?? []) {\n console.warn(`mark-build: ${warning}`);\n }\n const { payload } = buildWirePayload(manifest);\n checksum = computeManifestChecksum(payload.packages);\n stack = detectStack(payload.packages);\n } catch (err) {\n console.warn(\n `mark-build: could not compute the build fingerprint (${(err as Error).message}). Stamping the production flag only.`,\n );\n }\n\n // The widget pass needs the configured UUID; best-effort for the same reason.\n let widgetUuid: string | null = null;\n try {\n const config = await resolveConfig({\n cwd,\n cliSiteUuid: getStringFlag(args.flags, 'site-uuid'),\n });\n if (config.widget) {\n widgetUuid = config.siteUuid;\n }\n } catch (err) {\n console.warn(\n `mark-build: could not resolve the site UUID (${(err as Error).message}). Skipping the widget pass.`,\n );\n }\n\n const dir = resolveBuildDir(cwd, getStringFlag(args.flags, 'dir'));\n if (dir === null) {\n console.warn(\n 'mark-build: no build output directory found (looked for dist/, build/, out/, .output/public). Pass --dir <path> if it is elsewhere. Nothing to mark.',\n );\n return 0;\n }\n\n const files = findHtmlFiles(dir);\n if (files.length === 0) {\n // A build directory with no HTML in it is the signature of a server-rendered\n // app: the document is produced per request, so there is no file to stamp and\n // the marker only reaches production if it ships in the source shell. Silence\n // here reads as success, and the widget then treats the live site as a build.\n console.warn(`mark-build: found ${dir} but no HTML files in it.`);\n console.warn(\n 'mark-build: this build looks server-rendered, so the production flag has nothing to stamp.',\n );\n console.warn(\n 'mark-build: add the marker to your root shell instead — run `patchstack-connect guide` for the snippet.',\n );\n return 0;\n }\n\n const snippet = buildInjectionSnippet(checksum, stack);\n let marked = 0;\n let widgetTouched = 0;\n for (const file of files) {\n const before = readFileSync(file, 'utf8');\n let after = injectMarker(before, snippet);\n // Built HTML that came through a shell scan already edited carries the\n // managed tag; this covers output whose source shell we couldn't edit.\n // Manual installs are adopted (left untouched), same as in scan.\n if (widgetUuid !== null) {\n const ensured = ensureWidgetInHtml(after, widgetUuid);\n if (ensured.action === 'added' || ensured.action === 'updated') {\n widgetTouched += 1;\n }\n after = ensured.html;\n }\n if (after !== before) {\n writeFileSync(file, after);\n marked += 1;\n }\n }\n\n const stackSummary = stack !== null ? describeStack(stack) : null;\n console.log(\n `mark-build: marked ${marked} HTML file(s) in ${dir}` +\n `${checksum !== null ? ` (build ${checksum})` : ''}` +\n `${widgetTouched > 0 ? `, widget tag ensured in ${widgetTouched}` : ''}` +\n `${stackSummary !== null ? ` [${stackSummary}]` : ''}.`,\n );\n return 0;\n}\n\nasync function main(): Promise<number> {\n const args = parseArgs(process.argv);\n\n if (args.flags.has('help') || args.command === 'help' || args.command === null) {\n console.log(HELP);\n return 0;\n }\n\n switch (args.command) {\n case 'init':\n return runInit(args);\n case 'scan':\n return runScan(args);\n case 'status':\n return runStatus(args);\n case 'uninstall':\n return runUninstall(args);\n case 'mark-build':\n return runMarkBuild(args);\n case 'protect':\n return runProtectCommand(args);\n case 'demo':\n return runDemoCommand(args);\n case 'demo-guide':\n return runDemoGuideCommand(args);\n case 'guide':\n return runGuide(args);\n case 'setup':\n return runSetup(args);\n case 'map':\n return runMap(args);\n case 'login':\n return runLogin(args);\n default:\n console.error(`Unknown command: ${args.command}\\n`);\n console.error(HELP);\n return 1;\n }\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err: unknown) => {\n if (err instanceof PatchstackError) {\n console.error(`Error (${err.code}): ${err.message}`);\n process.exit(1);\n }\n console.error('Unexpected error:', err);\n process.exit(2);\n });\n","import { access } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type Manifest, type PackageEntry } from '../types.js';\nimport { missingDependencies, readDeclaredDependencyNames } from './consistency.js';\nimport { parseNpmLockfile } from './npm.js';\nimport { walkNodeModules } from './node_modules.js';\nimport { parsePnpmLockfile } from './pnpm.js';\nimport { parseYarnLockfile } from './yarn.js';\n\ntype LockfileFilename =\n | 'package-lock.json'\n | 'bun.lock'\n | 'bun.lockb'\n | 'yarn.lock'\n | 'pnpm-lock.yaml';\n\ntype DetectionStrategy =\n | 'npm-lockfile'\n | 'node-modules-walk'\n | 'pnpm-lockfile'\n | 'yarn-lockfile';\n\ninterface DetectedLockfile {\n ecosystem: 'npm';\n filePath: string;\n filename: LockfileFilename;\n strategy: DetectionStrategy;\n}\n\ninterface LockfileCandidate {\n filename: LockfileFilename;\n strategy: DetectionStrategy;\n}\n\n// Checked in priority order: the first candidate present in `cwd` wins.\nconst LOCKFILE_CANDIDATES: readonly LockfileCandidate[] = [\n { filename: 'package-lock.json', strategy: 'npm-lockfile' },\n { filename: 'bun.lock', strategy: 'node-modules-walk' },\n { filename: 'bun.lockb', strategy: 'node-modules-walk' },\n { filename: 'pnpm-lock.yaml', strategy: 'pnpm-lockfile' },\n { filename: 'yarn.lock', strategy: 'yarn-lockfile' },\n];\n\nexport async function detectLockfile(cwd: string): Promise<DetectedLockfile> {\n // Probe every candidate concurrently, then resolve by declaration order so\n // the result is identical to a sequential first-match scan — but bounded by a\n // single I/O round-trip instead of up to one `stat` per candidate.\n const probed = await Promise.all(\n LOCKFILE_CANDIDATES.map(async (candidate) => {\n const filePath = path.join(cwd, candidate.filename);\n return { ...candidate, filePath, present: await exists(filePath) };\n }),\n );\n\n const match = probed.find((candidate) => candidate.present);\n if (match) {\n return {\n ecosystem: 'npm',\n filePath: match.filePath,\n filename: match.filename,\n strategy: match.strategy,\n };\n }\n\n const expected = LOCKFILE_CANDIDATES.map((candidate) => candidate.filename).join(', ');\n throw new PatchstackError(\n `No lockfile found in ${cwd}. Expected one of: ${expected}.`,\n 'LOCKFILE_NOT_FOUND',\n );\n}\n\nexport async function scanLockfile(cwd: string): Promise<Manifest> {\n const candidates = await presentLockfiles(cwd);\n if (candidates.length === 0) {\n // Preserve the exact historical error for the no-lockfile case.\n await detectLockfile(cwd);\n }\n\n // Validate each source against package.json before trusting it. A lockfile\n // missing declared dependencies is a fossil — e.g. `npm install` planted a\n // package-lock.json once on a bun-managed platform (Lovable), and the native\n // dependency flow never updates it again. Trusting it would freeze the\n // manifest and the build fingerprint while the real dependency set drifts.\n const declared = await readDeclaredDependencyNames(cwd);\n const warnings: string[] = [];\n let firstParsed: { packages: PackageEntry[]; filename: string } | null = null;\n let walkTried = false;\n\n for (const candidate of candidates) {\n let packages: PackageEntry[];\n try {\n packages = await runStrategy(candidate, cwd);\n } catch {\n continue;\n }\n walkTried ||= candidate.strategy === 'node-modules-walk';\n firstParsed ??= { packages, filename: candidate.filename };\n\n const missing = missingDependencies(declared, packages);\n if (missing.length === 0) {\n return manifestWith(packages, warnings);\n }\n warnings.push(staleWarning(candidate.filename, missing));\n }\n\n // Last resort: the installed truth. node_modules reflects what the build\n // actually compiles against, whichever package manager wrote it.\n if (!walkTried) {\n try {\n const packages = await walkNodeModules(cwd);\n const missing = missingDependencies(declared, packages);\n if (missing.length > 0) {\n warnings.push(staleWarning('node_modules/', missing));\n }\n warnings.push('Scanned node_modules/ instead. Delete the stale lockfile to silence this warning.');\n return manifestWith(packages, warnings);\n } catch {\n // fall through to the best lockfile we managed to parse\n }\n }\n\n if (firstParsed === null) {\n const expected = LOCKFILE_CANDIDATES.map((candidate) => candidate.filename).join(', ');\n throw new PatchstackError(\n `No readable lockfile found in ${cwd}. Expected one of: ${expected}.`,\n 'LOCKFILE_NOT_FOUND',\n );\n }\n\n warnings.push(\n `No fully-consistent source found; reporting ${firstParsed.filename}. The manifest may understate the real dependency set.`,\n );\n\n return manifestWith(firstParsed.packages, warnings);\n}\n\nfunction manifestWith(packages: PackageEntry[], warnings: string[]): Manifest {\n return warnings.length > 0\n ? { ecosystem: 'npm', packages, warnings }\n : { ecosystem: 'npm', packages };\n}\n\nfunction staleWarning(source: string, missing: string[]): string {\n const sample = missing.slice(0, 3).join(', ');\n const suffix = missing.length > 3 ? `, +${missing.length - 3} more` : '';\n return `${source} looks stale: package.json declares ${missing.length} dependenc${missing.length === 1 ? 'y' : 'ies'} it does not contain (${sample}${suffix}).`;\n}\n\nasync function presentLockfiles(cwd: string): Promise<DetectedLockfile[]> {\n const probed = await Promise.all(\n LOCKFILE_CANDIDATES.map(async (candidate) => {\n const filePath = path.join(cwd, candidate.filename);\n return { ...candidate, filePath, present: await exists(filePath) };\n }),\n );\n\n return probed\n .filter((candidate) => candidate.present)\n .map(({ filename, strategy, filePath }) => ({ ecosystem: 'npm' as const, filename, strategy, filePath }));\n}\n\nasync function runStrategy(\n detected: DetectedLockfile,\n cwd: string,\n): Promise<PackageEntry[]> {\n switch (detected.strategy) {\n case 'npm-lockfile':\n return parseNpmLockfile(detected.filePath);\n case 'pnpm-lockfile':\n return parsePnpmLockfile(detected.filePath);\n case 'yarn-lockfile':\n return parseYarnLockfile(detected.filePath);\n case 'node-modules-walk':\n return walkNodeModules(cwd);\n }\n}\n\nasync function exists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","export type Ecosystem = 'npm' | 'composer';\n\n/**\n * Which environment a manifest was captured in. The connector reports from real\n * builds (prebuild scan / build hooks), so it defaults to 'production'. Override\n * with PATCHSTACK_ENVIRONMENT=sandbox (or \"environment\" in .patchstackrc.json)\n * for test manifests.\n */\nexport type Environment = 'production' | 'sandbox';\n\nexport interface PackageEntry {\n name: string;\n version: string;\n path?: string;\n direct?: boolean;\n}\n\nexport interface Manifest {\n ecosystem: Ecosystem;\n packages: PackageEntry[];\n /**\n * Human-readable scan diagnostics — set when the preferred lockfile looked\n * stale (missing dependencies declared in package.json) and another source\n * was used, or when no fully-consistent source existed. Never fatal.\n */\n warnings?: string[];\n}\n\nexport interface Config {\n /**\n * The site UUID. `null` means we don't have one yet — `postManifest` will then\n * post to the bare endpoint, the server will provision a fresh site, and the\n * UUID it returns should be persisted via `persistSiteUuid()`.\n */\n siteUuid: string | null;\n /**\n * WP-format site API key (`{oauth.secret}-{oauth.id}`) for authenticated\n * block-log reporting via connector `/api/logs/log`. Issued once as `api_key`\n * on first provision. Prefer `PATCHSTACK_API_KEY` in production deploys.\n */\n apiKey: string | null;\n /**\n * Credential for the authenticated Pulse endpoints (ADR-0018). Exchanged for\n * a short-lived bearer token at `monitor/pulse/token`; never sent directly.\n * Falls back to `apiKey` when unset. Prefer `PATCHSTACK_PULSE_AUTH`.\n */\n pulseAuth: string | null;\n endpoint: string;\n timeoutMs: number;\n /** Environment to report the manifest under. Defaults to 'production'. */\n environment: Environment;\n /**\n * Whether the connector manages the disclosure-widget tag (source shell on\n * `scan`, built HTML on `mark-build`). Defaults to true; persist\n * `\"widget\": false` in .patchstackrc.json for dependency-scanning only.\n */\n widget: boolean;\n}\n\nexport interface StoreManifestResponse {\n /** The UUID of the site the manifest was stored against. Always returned. */\n uuid?: string;\n /**\n * WP-format API key for connector log ingest. Present only when oauth\n * credentials are created in this request (first provision / backfill).\n */\n api_key?: string;\n stored: boolean;\n manifest_id?: number;\n checksum?: string;\n reason?: string;\n message?: string;\n error?: string;\n}\n\nexport class PatchstackError extends Error {\n constructor(\n message: string,\n public readonly code:\n | 'CONFIG_MISSING'\n | 'CONFIG_INVALID'\n | 'LOCKFILE_NOT_FOUND'\n | 'LOCKFILE_UNSUPPORTED'\n | 'LOCKFILE_PARSE_ERROR'\n | 'NETWORK_ERROR'\n | 'NETWORK_TIMEOUT'\n | 'SITE_NOT_FOUND'\n | 'UNAUTHORIZED'\n | 'VALIDATION_ERROR'\n | 'SERVER_ERROR',\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = 'PatchstackError';\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { PackageEntry } from '../types.js';\n\n/**\n * Registry-installable dependency names declared in package.json\n * (dependencies + devDependencies). Non-registry specifiers (file:, link:,\n * workspace:, portal:) are excluded — lockfile parsers skip those too, so\n * their absence from a parsed set says nothing about staleness. Returns []\n * when package.json is missing or unreadable (nothing to validate against).\n */\nexport async function readDeclaredDependencyNames(cwd: string): Promise<string[]> {\n let raw: string;\n try {\n raw = await readFile(path.join(cwd, 'package.json'), 'utf8');\n } catch {\n return [];\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return [];\n }\n if (typeof parsed !== 'object' || parsed === null) {\n return [];\n }\n\n const names = new Set<string>();\n for (const group of ['dependencies', 'devDependencies'] as const) {\n const deps = (parsed as Record<string, unknown>)[group];\n if (typeof deps !== 'object' || deps === null) {\n continue;\n }\n for (const [name, spec] of Object.entries(deps as Record<string, unknown>)) {\n if (typeof spec === 'string' && /^(file|link|workspace|portal):/.test(spec)) {\n continue;\n }\n names.add(name);\n }\n }\n\n return [...names];\n}\n\n/**\n * Declared names absent from a parsed package set. A non-empty result means\n * the source predates package.json — the fossil-lockfile failure mode where\n * e.g. `npm install` planted a package-lock.json once and the platform's\n * native package manager (bun on Lovable) never updates it again.\n */\nexport function missingDependencies(declared: string[], packages: PackageEntry[]): string[] {\n const present = new Set(packages.map((entry) => entry.name));\n return declared.filter((name) => !present.has(name));\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type PackageEntry } from '../types.js';\n\ninterface LockfileV2Package {\n name?: string;\n version?: string;\n link?: boolean;\n resolved?: string;\n}\n\ninterface LockfileV2 {\n lockfileVersion: number;\n packages?: Record<string, LockfileV2Package>;\n dependencies?: Record<string, LockfileV1Dependency>;\n}\n\ninterface LockfileV1Dependency {\n version: string;\n dependencies?: Record<string, LockfileV1Dependency>;\n}\n\nexport async function parseNpmLockfile(lockfilePath: string): Promise<PackageEntry[]> {\n let raw: string;\n try {\n raw = await readFile(lockfilePath, 'utf8');\n } catch (cause) {\n throw new PatchstackError(`Could not read lockfile at ${lockfilePath}`, 'LOCKFILE_NOT_FOUND', cause);\n }\n\n let parsed: LockfileV2;\n try {\n parsed = JSON.parse(raw) as LockfileV2;\n } catch (cause) {\n throw new PatchstackError(`Lockfile at ${lockfilePath} is not valid JSON`, 'LOCKFILE_PARSE_ERROR', cause);\n }\n\n if (parsed.packages) {\n return extractFromV2(parsed.packages);\n }\n\n if (parsed.dependencies) {\n return extractFromV1(parsed.dependencies);\n }\n\n throw new PatchstackError(\n `Lockfile at ${lockfilePath} has no \"packages\" or \"dependencies\" key`,\n 'LOCKFILE_PARSE_ERROR',\n );\n}\n\nfunction extractFromV2(packages: Record<string, LockfileV2Package>): PackageEntry[] {\n const entries: PackageEntry[] = [];\n\n for (const [pkgPath, pkg] of Object.entries(packages)) {\n if (pkgPath === '') {\n continue;\n }\n if (pkg.link === true) {\n continue;\n }\n if (typeof pkg.version !== 'string' || pkg.version.length === 0) {\n continue;\n }\n\n const name = pkg.name ?? extractNameFromPath(pkgPath);\n if (name === null) {\n continue;\n }\n\n entries.push({\n name,\n version: pkg.version,\n path: pkgPath,\n direct: isDirectV2(pkgPath),\n });\n }\n\n return entries;\n}\n\nfunction extractFromV1(\n deps: Record<string, LockfileV1Dependency>,\n acc: PackageEntry[] = [],\n depth = 0,\n): PackageEntry[] {\n for (const [name, dep] of Object.entries(deps)) {\n if (typeof dep.version === 'string' && dep.version.length > 0) {\n acc.push({ name, version: dep.version, direct: depth === 0 });\n }\n if (dep.dependencies) {\n extractFromV1(dep.dependencies, acc, depth + 1);\n }\n }\n return acc;\n}\n\nfunction extractNameFromPath(pkgPath: string): string | null {\n const segments = pkgPath.split('node_modules' + path.sep === pkgPath ? path.sep : '/');\n const parts = pkgPath.split('/');\n const nmIndex = parts.lastIndexOf('node_modules');\n if (nmIndex === -1 || nmIndex >= parts.length - 1) {\n return segments[segments.length - 1] ?? null;\n }\n const tail = parts.slice(nmIndex + 1);\n if (tail.length === 0) {\n return null;\n }\n const first = tail[0];\n if (first !== undefined && first.startsWith('@') && tail.length >= 2) {\n return `${first}/${tail[1]}`;\n }\n return first ?? null;\n}\n\nfunction isDirectV2(pkgPath: string): boolean {\n const parts = pkgPath.split('/');\n const nmCount = parts.filter((p) => p === 'node_modules').length;\n return nmCount === 1;\n}\n","import { lstat, readFile, readdir, stat } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type PackageEntry } from '../types.js';\n\nexport async function walkNodeModules(cwd: string): Promise<PackageEntry[]> {\n const root = path.join(cwd, 'node_modules');\n\n try {\n const info = await stat(root);\n if (!info.isDirectory()) {\n throw new PatchstackError(\n `${root} exists but is not a directory.`,\n 'LOCKFILE_NOT_FOUND',\n );\n }\n } catch (cause) {\n if (cause instanceof PatchstackError) {\n throw cause;\n }\n throw new PatchstackError(\n `node_modules/ not found at ${cwd}. Install dependencies first (e.g. \\`bun install\\` or \\`npm install\\`).`,\n 'LOCKFILE_NOT_FOUND',\n cause,\n );\n }\n\n const entries: PackageEntry[] = [];\n await walk(root, entries, 0);\n return entries;\n}\n\nasync function walk(dir: string, acc: PackageEntry[], depth: number): Promise<void> {\n let names: string[];\n try {\n names = await readdir(dir);\n } catch {\n return;\n }\n\n for (const name of names) {\n if (name.startsWith('.')) {\n continue;\n }\n\n const fullPath = path.join(dir, name);\n if (!(await isPlainDirectory(fullPath))) {\n continue;\n }\n\n if (name.startsWith('@')) {\n let subNames: string[];\n try {\n subNames = await readdir(fullPath);\n } catch {\n continue;\n }\n for (const sub of subNames) {\n if (sub.startsWith('.')) {\n continue;\n }\n const scopedDir = path.join(fullPath, sub);\n if (!(await isPlainDirectory(scopedDir))) {\n continue;\n }\n await readPackage(scopedDir, depth, acc);\n await walkNested(scopedDir, acc, depth);\n }\n continue;\n }\n\n await readPackage(fullPath, depth, acc);\n await walkNested(fullPath, acc, depth);\n }\n}\n\nasync function readPackage(\n pkgDir: string,\n depth: number,\n acc: PackageEntry[],\n): Promise<void> {\n let raw: string;\n try {\n raw = await readFile(path.join(pkgDir, 'package.json'), 'utf8');\n } catch {\n return;\n }\n\n let parsed: { name?: unknown; version?: unknown };\n try {\n parsed = JSON.parse(raw) as { name?: unknown; version?: unknown };\n } catch {\n return;\n }\n\n if (typeof parsed.name !== 'string' || parsed.name.length === 0) {\n return;\n }\n if (typeof parsed.version !== 'string' || parsed.version.length === 0) {\n return;\n }\n\n acc.push({\n name: parsed.name,\n version: parsed.version,\n direct: depth === 0,\n });\n}\n\nasync function walkNested(\n pkgDir: string,\n acc: PackageEntry[],\n depth: number,\n): Promise<void> {\n const nested = path.join(pkgDir, 'node_modules');\n if (!(await isPlainDirectory(nested))) {\n return;\n }\n await walk(nested, acc, depth + 1);\n}\n\nasync function isPlainDirectory(dir: string): Promise<boolean> {\n try {\n const info = await lstat(dir);\n return info.isDirectory() && !info.isSymbolicLink();\n } catch {\n return false;\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { PatchstackError, type PackageEntry } from '../types.js';\n\n/**\n * Parses pnpm-lock.yaml without pulling in a YAML library. We don't need full\n * YAML semantics — only the `packages:` block (the canonical list of every\n * installed package) and, for direct-dep marking, the dependency sections under\n * `importers:` (v9+) or at the top level (v6-v8 single-project).\n *\n * Supported pnpm-lock key formats:\n * v5: /pkg/1.0.0 /@scope/pkg/1.0.0\n * v6-v8: /pkg@1.0.0 /@scope/pkg@1.0.0 (optional `(peer@x)` suffix)\n * v9: pkg@1.0.0 @scope/pkg@1.0.0 (optional `(peer@x)` suffix, may be quoted)\n */\nexport async function parsePnpmLockfile(lockfilePath: string): Promise<PackageEntry[]> {\n let raw: string;\n try {\n raw = await readFile(lockfilePath, 'utf8');\n } catch (cause) {\n throw new PatchstackError(\n `Could not read lockfile at ${lockfilePath}`,\n 'LOCKFILE_NOT_FOUND',\n cause,\n );\n }\n\n const lines = raw.split(/\\r?\\n/);\n const directNames = collectDirectDepNames(lines);\n const packageKeys = collectPackagesBlockKeys(lines);\n\n if (packageKeys.length === 0) {\n throw new PatchstackError(\n `Lockfile at ${lockfilePath} has no \"packages\" entries`,\n 'LOCKFILE_PARSE_ERROR',\n );\n }\n\n const entries: PackageEntry[] = [];\n for (const key of packageKeys) {\n const parsed = parsePackageKey(key);\n if (parsed === null) {\n continue;\n }\n entries.push({\n name: parsed.name,\n version: parsed.version,\n direct: directNames.has(parsed.name),\n });\n }\n\n return entries;\n}\n\ninterface ParsedKey {\n name: string;\n version: string;\n}\n\nexport function parsePackageKey(rawKey: string): ParsedKey | null {\n let k = rawKey.trim();\n if (k.length === 0) {\n return null;\n }\n\n if (\n (k.startsWith(\"'\") && k.endsWith(\"'\")) ||\n (k.startsWith('\"') && k.endsWith('\"'))\n ) {\n k = k.slice(1, -1);\n }\n\n if (k.startsWith('/')) {\n k = k.slice(1);\n }\n\n // Strip peer-dependency suffix used by v6+: `pkg@1.0.0(peer@1.0.0)(other@2)`.\n const parenIdx = k.indexOf('(');\n if (parenIdx >= 0) {\n k = k.slice(0, parenIdx);\n }\n\n // Split off the optional `@scope/` prefix so the remaining \"body\" contains\n // exactly one separator between the bare name and the version. npm forbids\n // both `@` and `/` inside the bare-name portion, so the first occurrence of\n // either character in the body is unambiguously the name/version separator.\n let scopePrefix = '';\n let body = k;\n if (k.startsWith('@')) {\n const firstSlash = k.indexOf('/');\n if (firstSlash <= 0) {\n return null;\n }\n scopePrefix = k.slice(0, firstSlash + 1);\n body = k.slice(firstSlash + 1);\n }\n\n const slashIdx = body.indexOf('/');\n const atIdx = body.indexOf('@');\n\n let sepIdx: number;\n if (slashIdx < 0 && atIdx < 0) {\n return null;\n } else if (slashIdx < 0) {\n sepIdx = atIdx;\n } else if (atIdx < 0) {\n sepIdx = slashIdx;\n } else {\n sepIdx = Math.min(slashIdx, atIdx);\n }\n\n const name = scopePrefix + body.slice(0, sepIdx);\n let version = body.slice(sepIdx + 1);\n\n // v5 peer suffix uses `_`: `1.0.0_react@18.2.0`.\n const underscoreIdx = version.indexOf('_');\n if (underscoreIdx >= 0) {\n version = version.slice(0, underscoreIdx);\n }\n\n if (name.length === 0 || version.length === 0) {\n return null;\n }\n\n return { name, version };\n}\n\nfunction indentOf(line: string): number {\n let i = 0;\n while (i < line.length && line[i] === ' ') {\n i++;\n }\n return i;\n}\n\nfunction isBlankOrComment(line: string): boolean {\n const trimmed = line.trim();\n return trimmed.length === 0 || trimmed.startsWith('#');\n}\n\n/**\n * Collects keys directly nested under the top-level `packages:` block. Stops\n * when another top-level key (e.g. `snapshots:`) appears.\n */\nfunction collectPackagesBlockKeys(lines: string[]): string[] {\n const keys: string[] = [];\n let inBlock = false;\n let childIndent: number | null = null;\n\n for (const line of lines) {\n if (isBlankOrComment(line)) {\n continue;\n }\n\n const indent = indentOf(line);\n\n if (!inBlock) {\n if (indent === 0 && line.trim() === 'packages:') {\n inBlock = true;\n }\n continue;\n }\n\n if (indent === 0) {\n break;\n }\n\n if (childIndent === null) {\n childIndent = indent;\n }\n\n if (indent !== childIndent) {\n continue;\n }\n\n const content = line.slice(indent);\n if (!content.endsWith(':')) {\n continue;\n }\n\n keys.push(content.slice(0, -1));\n }\n\n return keys;\n}\n\n/**\n * Collects direct dependency names. Looks in two places, since the format\n * differs across lockfile versions and workspaces:\n *\n * 1. `importers:` > `<importer>:` > `{dependencies,devDependencies,optionalDependencies}:`\n * (v9 always, v6-v8 in workspaces)\n * 2. Top-level `{dependencies,devDependencies,optionalDependencies}:`\n * (v6-v8 single-project lockfiles)\n *\n * Direct-dep marking is best-effort: a name absent from both is simply left as\n * not-direct, matching the npm parser's behaviour for transitive packages.\n */\nfunction collectDirectDepNames(lines: string[]): Set<string> {\n const names = new Set<string>();\n collectFromImporters(lines, names);\n for (const section of ['dependencies', 'devDependencies', 'optionalDependencies']) {\n collectFromTopLevelSection(lines, section, names);\n }\n return names;\n}\n\nconst DEP_SECTIONS = new Set([\n 'dependencies',\n 'devDependencies',\n 'optionalDependencies',\n]);\n\nfunction collectFromImporters(lines: string[], out: Set<string>): void {\n let inImporters = false;\n let importerIndent: number | null = null;\n let inDepSection = false;\n let depSectionIndent: number | null = null;\n let leafIndent: number | null = null;\n\n for (const line of lines) {\n if (isBlankOrComment(line)) {\n continue;\n }\n const indent = indentOf(line);\n const trimmed = line.trim();\n\n if (!inImporters) {\n if (indent === 0 && trimmed === 'importers:') {\n inImporters = true;\n }\n continue;\n }\n\n if (indent === 0) {\n break;\n }\n\n // Track the indent at which importer entries (e.g. `.:`, `packages/foo:`) sit.\n if (importerIndent === null) {\n importerIndent = indent;\n }\n\n if (indent === importerIndent) {\n inDepSection = false;\n depSectionIndent = null;\n leafIndent = null;\n continue;\n }\n\n if (!inDepSection) {\n const key = stripTrailingColon(trimmed);\n if (key !== null && DEP_SECTIONS.has(key)) {\n inDepSection = true;\n depSectionIndent = indent;\n }\n continue;\n }\n\n if (depSectionIndent !== null && indent <= depSectionIndent) {\n // Reset — we've exited the dep section. Reconsider this line.\n inDepSection = false;\n depSectionIndent = null;\n leafIndent = null;\n const key = stripTrailingColon(trimmed);\n if (key !== null && DEP_SECTIONS.has(key)) {\n inDepSection = true;\n depSectionIndent = indent;\n }\n continue;\n }\n\n if (leafIndent === null) {\n leafIndent = indent;\n }\n\n if (indent !== leafIndent) {\n continue;\n }\n\n const name = extractLeafName(trimmed);\n if (name !== null) {\n out.add(name);\n }\n }\n}\n\nfunction collectFromTopLevelSection(\n lines: string[],\n section: string,\n out: Set<string>,\n): void {\n let inSection = false;\n let leafIndent: number | null = null;\n\n for (const line of lines) {\n if (isBlankOrComment(line)) {\n continue;\n }\n const indent = indentOf(line);\n const trimmed = line.trim();\n\n if (!inSection) {\n if (indent === 0 && trimmed === `${section}:`) {\n inSection = true;\n }\n continue;\n }\n\n if (indent === 0) {\n break;\n }\n\n if (leafIndent === null) {\n leafIndent = indent;\n }\n\n if (indent !== leafIndent) {\n continue;\n }\n\n const name = extractLeafName(trimmed);\n if (name !== null) {\n out.add(name);\n }\n }\n}\n\nfunction stripTrailingColon(s: string): string | null {\n if (!s.endsWith(':')) {\n return null;\n }\n return s.slice(0, -1).trim();\n}\n\n/**\n * Extracts the package name from a dependency-section leaf, handling both the\n * short form (`pkg: 1.0.0`) and the v9 expanded form (`pkg:` followed by\n * `specifier:` / `version:` children). Quoted scoped names like `'@scope/pkg':`\n * are unquoted.\n */\nfunction extractLeafName(trimmed: string): string | null {\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx < 0) {\n return null;\n }\n let name = trimmed.slice(0, colonIdx).trim();\n if (name.length === 0) {\n return null;\n }\n if (\n (name.startsWith(\"'\") && name.endsWith(\"'\")) ||\n (name.startsWith('\"') && name.endsWith('\"'))\n ) {\n name = name.slice(1, -1);\n }\n return name.length > 0 ? name : null;\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type PackageEntry } from '../types.js';\n\n/**\n * Parses yarn.lock (yarn classic v1 and yarn berry v2+) without a YAML\n * dependency. Both generations share the same block structure — a top-level\n * mapping of comma-separated descriptor lists to a block containing a\n * `version` field — so we walk them with the same scanner and only branch on\n * the `version` syntax (`version \"x\"` for v1, `version: x` for berry).\n *\n * Direct vs transitive can't be derived from yarn.lock alone (yarn does not\n * record an importer manifest the way pnpm v9 does), so we cross-reference\n * the sibling `package.json` when present.\n */\nexport async function parseYarnLockfile(lockfilePath: string): Promise<PackageEntry[]> {\n let raw: string;\n try {\n raw = await readFile(lockfilePath, 'utf8');\n } catch (cause) {\n throw new PatchstackError(\n `Could not read lockfile at ${lockfilePath}`,\n 'LOCKFILE_NOT_FOUND',\n cause,\n );\n }\n\n const blocks = parseBlocks(raw);\n if (blocks.length === 0) {\n throw new PatchstackError(\n `Lockfile at ${lockfilePath} contains no package entries`,\n 'LOCKFILE_PARSE_ERROR',\n );\n }\n\n const directNames = await readDirectDepNames(path.dirname(lockfilePath));\n\n const entries: PackageEntry[] = [];\n const seen = new Set<string>();\n for (const block of blocks) {\n if (block.version.length === 0 || block.names.size === 0) {\n continue;\n }\n for (const name of block.names) {\n const dedupKey = `${name}@${block.version}`;\n if (seen.has(dedupKey)) {\n continue;\n }\n seen.add(dedupKey);\n entries.push({\n name,\n version: block.version,\n direct: directNames.has(name),\n });\n }\n }\n\n return entries;\n}\n\ninterface Block {\n names: Set<string>;\n version: string;\n}\n\nfunction parseBlocks(raw: string): Block[] {\n const lines = raw.split(/\\r?\\n/);\n const blocks: Block[] = [];\n let current: Block | null = null;\n\n const finalize = () => {\n if (current !== null && current.version.length > 0 && current.names.size > 0) {\n blocks.push(current);\n }\n current = null;\n };\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.length === 0 || trimmed.startsWith('#')) {\n continue;\n }\n\n const indent = countLeadingSpaces(line);\n\n if (indent === 0) {\n finalize();\n if (!trimmed.endsWith(':')) {\n continue;\n }\n // `__metadata:` (yarn berry header) has no `@` in any descriptor and\n // produces an empty names set, so it's naturally skipped on finalize.\n const keyLine = trimmed.slice(0, -1);\n const names = new Set<string>();\n for (const spec of splitDescriptors(keyLine)) {\n const name = extractName(spec);\n if (name !== null) {\n names.add(name);\n }\n }\n current = { names, version: '' };\n continue;\n }\n\n if (current === null) {\n continue;\n }\n\n const version = parseVersionField(trimmed);\n if (version !== null) {\n current.version = version;\n }\n }\n\n finalize();\n return blocks;\n}\n\nfunction countLeadingSpaces(line: string): number {\n let i = 0;\n while (i < line.length && line[i] === ' ') {\n i++;\n }\n return i;\n}\n\n/**\n * Splits a yarn descriptor key list on top-level commas. yarn quotes any\n * descriptor that contains characters needing escaping, so we respect quotes\n * while splitting to avoid breaking on commas inside (rare in practice but\n * cheap to handle).\n */\nexport function splitDescriptors(keyLine: string): string[] {\n const parts: string[] = [];\n let current = '';\n let quote: '\"' | \"'\" | null = null;\n\n for (let i = 0; i < keyLine.length; i++) {\n const c = keyLine[i];\n if (quote !== null) {\n current += c;\n if (c === quote) {\n quote = null;\n }\n continue;\n }\n if (c === '\"' || c === \"'\") {\n quote = c;\n current += c;\n continue;\n }\n if (c === ',') {\n const piece = current.trim();\n if (piece.length > 0) {\n parts.push(piece);\n }\n current = '';\n continue;\n }\n current += c;\n }\n const tail = current.trim();\n if (tail.length > 0) {\n parts.push(tail);\n }\n return parts;\n}\n\n/**\n * Extracts the package name from a yarn descriptor like `axios@^1.6.0`,\n * `\"@scope/pkg@^2.1.0\"`, or `\"@scope/pkg@npm:2.1.0\"`. The descriptor's\n * range portion is discarded — we only need the name, since the resolved\n * version comes from the `version` field of the block.\n */\nexport function extractName(rawSpec: string): string | null {\n let s = rawSpec.trim();\n if (s.length === 0) {\n return null;\n }\n if (\n (s.startsWith('\"') && s.endsWith('\"')) ||\n (s.startsWith(\"'\") && s.endsWith(\"'\"))\n ) {\n s = s.slice(1, -1);\n }\n // Position-0 `@` belongs to a scope, so we want the last `@` after it.\n const atIdx = s.lastIndexOf('@');\n if (atIdx <= 0) {\n return null;\n }\n const name = s.slice(0, atIdx);\n return name.length > 0 ? name : null;\n}\n\nfunction parseVersionField(content: string): string | null {\n if (!content.startsWith('version')) {\n return null;\n }\n const after = content.slice('version'.length);\n // yarn v1: `version \"1.2.3\"` (whitespace then quoted)\n // yarn berry: `version: 1.2.3` or `version: \"1.2.3\"`\n const firstChar = after.charAt(0);\n if (firstChar !== ' ' && firstChar !== '\\t' && firstChar !== ':') {\n return null;\n }\n let rest = firstChar === ':' ? after.slice(1) : after;\n rest = rest.trim();\n if (rest.length === 0) {\n return null;\n }\n if (\n (rest.startsWith('\"') && rest.endsWith('\"')) ||\n (rest.startsWith(\"'\") && rest.endsWith(\"'\"))\n ) {\n rest = rest.slice(1, -1);\n }\n return rest.length > 0 ? rest : null;\n}\n\nasync function readDirectDepNames(cwd: string): Promise<Set<string>> {\n const names = new Set<string>();\n let raw: string;\n try {\n raw = await readFile(path.join(cwd, 'package.json'), 'utf8');\n } catch {\n return names;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return names;\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n return names;\n }\n const obj = parsed as Record<string, unknown>;\n\n for (const field of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) {\n const section = obj[field];\n if (typeof section !== 'object' || section === null) {\n continue;\n }\n for (const name of Object.keys(section)) {\n names.add(name);\n }\n }\n\n return names;\n}\n","import type { Manifest, PackageEntry } from './types.js';\n\nexport interface WirePackage {\n name: string;\n version: string;\n}\n\nexport interface WirePayload {\n ecosystem: Manifest['ecosystem'];\n packages: WirePackage[];\n}\n\nexport interface NormalizeStats {\n uniqueNames: number;\n duplicateNames: string[];\n totalEntries: number;\n}\n\nexport interface NormalizeResult {\n payload: WirePayload;\n stats: NormalizeStats;\n}\n\nexport function buildWirePayload(manifest: Manifest): NormalizeResult {\n const seen = new Map<string, Set<string>>();\n const wirePackages: WirePackage[] = [];\n\n for (const entry of manifest.packages) {\n const versions = seen.get(entry.name);\n if (versions) {\n if (versions.has(entry.version)) {\n continue;\n }\n versions.add(entry.version);\n } else {\n seen.set(entry.name, new Set([entry.version]));\n }\n wirePackages.push({ name: entry.name, version: entry.version });\n }\n\n wirePackages.sort((a, b) => {\n if (a.name === b.name) {\n return compareVersions(a.version, b.version);\n }\n return a.name < b.name ? -1 : 1;\n });\n\n const duplicateNames: string[] = [];\n for (const [name, versions] of seen) {\n if (versions.size > 1) {\n duplicateNames.push(name);\n }\n }\n\n return {\n payload: { ecosystem: manifest.ecosystem, packages: wirePackages },\n stats: {\n uniqueNames: seen.size,\n duplicateNames,\n totalEntries: manifest.packages.length,\n },\n };\n}\n\nexport function compareVersions(a: string, b: string): number {\n if (a === b) {\n return 0;\n }\n\n const [aBase, aPre] = splitPrerelease(a);\n const [bBase, bPre] = splitPrerelease(b);\n\n const baseCmp = compareSegments(aBase.split('.'), bBase.split('.'));\n if (baseCmp !== 0) {\n return baseCmp;\n }\n\n if (aPre === null && bPre === null) {\n return 0;\n }\n if (aPre === null) {\n return 1;\n }\n if (bPre === null) {\n return -1;\n }\n return compareSegments(aPre.split('.'), bPre.split('.'));\n}\n\nfunction splitPrerelease(version: string): [string, string | null] {\n const cleaned = version.replace(/^[v=]+/, '').split('+')[0]!;\n const dashIndex = cleaned.indexOf('-');\n if (dashIndex === -1) {\n return [cleaned, null];\n }\n return [cleaned.slice(0, dashIndex), cleaned.slice(dashIndex + 1)];\n}\n\nfunction compareSegments(a: string[], b: string[]): number {\n const max = Math.max(a.length, b.length);\n for (let i = 0; i < max; i++) {\n const aPart = a[i];\n const bPart = b[i];\n if (aPart === undefined) {\n return -1;\n }\n if (bPart === undefined) {\n return 1;\n }\n const aNum = /^\\d+$/.test(aPart);\n const bNum = /^\\d+$/.test(bPart);\n if (aNum && bNum) {\n const diff = Number(aPart) - Number(bPart);\n if (diff !== 0) {\n return diff < 0 ? -1 : 1;\n }\n continue;\n }\n if (aNum) {\n return -1;\n }\n if (bNum) {\n return 1;\n }\n if (aPart < bPart) {\n return -1;\n }\n if (aPart > bPart) {\n return 1;\n }\n }\n return 0;\n}\n\nexport function findPackageInManifest(\n manifest: Manifest,\n name: string,\n): PackageEntry[] {\n return manifest.packages.filter((p) => p.name === name);\n}\n","import { createHash } from 'node:crypto';\n\nimport type { WirePackage } from './normalize.js';\n\n/**\n * Fingerprint of a manifest's package set, byte-for-byte identical to the\n * checksum Patchstack stores server-side (PulseController::storeManifest): the\n * first 12 hex chars of sha256 over the JSON of the packages sorted by\n * `[name, version]` with plain lexicographic (byte) ordering.\n *\n * This mirrors PHP's `usort(..., fn($a,$b) => [$a['name'],$a['version']] <=> ...)`\n * followed by `json_encode(..., JSON_UNESCAPED_SLASHES)`. Two deliberate details:\n *\n * - The sort is lexicographic, NOT the semver-aware ordering `buildWirePayload`\n * uses for display. The server re-sorts lexicographically before hashing, so\n * the fingerprint must too (e.g. `1.10.0` sorts before `1.9.0`).\n * - npm/composer package names and versions are ASCII, so JS `JSON.stringify`\n * and PHP `json_encode` produce identical bytes (no unicode escaping, and\n * neither escapes `/`, so scoped names like `@babel/core` match).\n *\n * Injected into built HTML by `mark-build` and reported by the disclosure widget\n * so Patchstack can compare the live build against the last reported manifest.\n */\nexport function computeManifestChecksum(packages: WirePackage[]): string {\n const canonical = packages\n .map((pkg) => ({ name: pkg.name, version: pkg.version }))\n .sort((a, b) => {\n if (a.name !== b.name) {\n return a.name < b.name ? -1 : 1;\n }\n if (a.version !== b.version) {\n return a.version < b.version ? -1 : 1;\n }\n return 0;\n });\n\n return createHash('sha256').update(JSON.stringify(canonical)).digest('hex').slice(0, 12);\n}\n","import type { Config } from './types.js';\n\n/**\n * Bearer tokens for the authenticated Pulse endpoints (ADR-0018).\n *\n * Deliberately separate from the block-log token flow in\n * `src/protect/firewall-log.js`: that path talks to the auth/ Lambda's\n * /oauth/token and must keep working exactly as it does today.\n */\n\nconst TOKEN_SKEW_MS = 60_000;\n\n/** Build the Pulse token URL corresponding to a manifest endpoint override. */\nexport function buildTokenUrl(manifestEndpoint: string): string {\n const url = new URL(manifestEndpoint);\n const path = url.pathname.replace(/\\/$/, '');\n url.pathname = path.endsWith('/manifest')\n ? `${path.slice(0, -'/manifest'.length)}/token`\n : '/monitor/pulse/token';\n url.search = '';\n url.hash = '';\n return url.toString();\n}\n\n/** Split the WP-format `{secret}-{oauth.id}` credential on its last hyphen. */\nexport function parsePulseAuth(credential: string): { clientId: string; clientSecret: string } | null {\n const index = credential.lastIndexOf('-');\n if (index <= 0 || index === credential.length - 1) return null;\n\n const clientId = credential.slice(index + 1);\n if (!/^\\d+$/.test(clientId)) return null;\n\n return { clientId, clientSecret: credential.slice(0, index) };\n}\n\nlet cached: { token: string; expiresAt: number } | null = null;\nlet inflight: Promise<string | null> | null = null;\n\n/** Drops the cached token. Exported for tests and for 401 handling. */\nexport function clearPulseToken(): void {\n cached = null;\n}\n\n/**\n * Resolve a bearer token for `config.pulseAuth`, exchanging one if needed.\n *\n * Returns null whenever a token cannot be obtained — no credential, a rejected\n * exchange, a network failure. Callers then send the request unauthenticated,\n * which the server still accepts while it runs dual-accept.\n */\nexport async function getPulseToken(\n config: Config,\n fetchImpl: typeof fetch = fetch,\n): Promise<string | null> {\n // Not `=== null`: Config is public, so callers can hand us an object that\n // predates this field, and an unusable credential must never throw here.\n if (typeof config.pulseAuth !== 'string' || config.pulseAuth.length === 0) return null;\n\n if (cached !== null && Date.now() < cached.expiresAt - TOKEN_SKEW_MS) {\n return cached.token;\n }\n if (inflight !== null) return inflight;\n\n const credentials = parsePulseAuth(config.pulseAuth);\n if (credentials === null) return null;\n\n inflight = (async () => {\n try {\n const response = await fetchImpl(buildTokenUrl(config.endpoint), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'User-Agent': '@patchstack/connect',\n },\n body: JSON.stringify({\n grant_type: 'client_credentials',\n client_id: credentials.clientId,\n client_secret: credentials.clientSecret,\n }),\n signal: AbortSignal.timeout(config.timeoutMs),\n });\n\n if (!response.ok) return null;\n\n const body = (await response.json()) as { access_token?: unknown; expires_in?: unknown };\n if (typeof body.access_token !== 'string' || body.access_token.length === 0) return null;\n\n const expiresIn = Number(body.expires_in);\n const ttlMs = Number.isFinite(expiresIn) && expiresIn > 0 ? expiresIn * 1000 : 3600_000;\n cached = { token: body.access_token, expiresAt: Date.now() + ttlMs };\n\n return body.access_token;\n } catch {\n return null;\n } finally {\n inflight = null;\n }\n })();\n\n return inflight;\n}\n\n/**\n * `Authorization` header for a Pulse request, or `{}` when unauthenticated.\n * Spread into an existing header object so call sites stay one line.\n */\nexport async function pulseAuthHeader(\n config: Config,\n fetchImpl: typeof fetch = fetch,\n): Promise<Record<string, string>> {\n const token = await getPulseToken(config, fetchImpl);\n return token === null ? {} : { Authorization: `Bearer ${token}` };\n}\n\n/**\n * Send a Pulse request, attaching the bearer token and retrying once if the\n * server rejects it.\n *\n * A cached token can stop being valid before it expires — the credential may\n * have been rotated or revoked meanwhile — so the server's 401 is authoritative\n * over our own clock. Without this a long-running process would keep presenting\n * a dead token until its local expiry.\n *\n * Only 401 retries: a 403 is a scope or site mismatch, which a fresh token\n * would not fix.\n */\nexport async function pulseFetch(\n config: Config,\n url: string,\n init: RequestInit,\n fetchImpl: typeof fetch = fetch,\n): Promise<Response> {\n const send = async () => {\n const auth = await pulseAuthHeader(config, fetchImpl);\n const response = await fetchImpl(url, {\n ...init,\n headers: { ...(init.headers as Record<string, string> | undefined), ...auth },\n });\n\n return { response, authenticated: auth.Authorization !== undefined };\n };\n\n const first = await send();\n\n // Retrying an unauthenticated request would just repeat it: the 401 was\n // about something other than our token.\n if (first.response.status === 401 && first.authenticated) {\n clearPulseToken();\n\n return (await send()).response;\n }\n\n return first.response;\n}\n","import { PatchstackError, type Config, type StoreManifestResponse } from './types.js';\nimport type { WirePayload } from './normalize.js';\nimport { pulseFetch } from './pulse-token.js';\n\nexport const DEFAULT_ENDPOINT = 'https://api.patchstack.com/monitor/pulse/manifest';\nexport const DEFAULT_TIMEOUT_MS = 30_000;\n\nexport function buildEndpointUrl(base: string, siteUuid?: string | null): string {\n const trimmed = base.replace(/\\/$/, '');\n return siteUuid !== undefined && siteUuid !== null && siteUuid.length > 0\n ? `${trimmed}/${encodeURIComponent(siteUuid)}`\n : trimmed;\n}\n\n/**\n * What a refusal means, in terms someone can act on.\n *\n * Every Pulse route that addresses an existing site requires a credential, so a rejection is now the\n * most likely failure a misconfigured project hits — and the three causes have three different fixes.\n * Reporting them as `Patchstack returned 401` names none of them, and this output is frequently read by\n * an AI agent that has no other way to find out what to do next.\n *\n * The distinction 401 cannot make on its own is whether we HELD a credential. Having none is a setup\n * step that was never run; having one rejected is a credential that has expired, been revoked, or whose\n * site no longer exists. A 403 is different again: the credential is valid and simply is not for this\n * site, which usually means a `.patchstackrc.json` carrying someone else's UUID.\n *\n * @returns the message, or null when the status is not an authentication failure\n */\nexport function authFailureMessage(status: number, config: Config): string | null {\n const hasCredential = typeof config.pulseAuth === 'string' && config.pulseAuth.length > 0;\n\n if (status === 401 && !hasCredential) {\n return 'Patchstack requires an API credential for this site and none is configured. Run `npx patchstack-connect login`, or set PATCHSTACK_API_KEY.';\n }\n if (status === 401) {\n return 'Patchstack rejected this API credential. It may have expired, been revoked, or the site may no longer exist. Run `npx patchstack-connect login` to issue a new one.';\n }\n if (status === 403) {\n return 'This API credential is not permitted to act on this site. Check that siteUuid in .patchstackrc.json matches the credential (a credential is issued for one site).';\n }\n\n return null;\n}\n\n/** Build the live Pulse rules URL corresponding to a manifest endpoint override. */\nexport function buildRulesUrl(manifestEndpoint: string, siteUuid: string): string {\n const url = new URL(manifestEndpoint);\n const path = url.pathname.replace(/\\/$/, '');\n url.pathname = path.endsWith('/manifest')\n ? `${path.slice(0, -'/manifest'.length)}/rules/${encodeURIComponent(siteUuid)}`\n : `/monitor/pulse/rules/${encodeURIComponent(siteUuid)}`;\n url.search = '';\n url.hash = '';\n return url.toString();\n}\n\n/**\n * Build the claim URL for a site. The claim page lives on the same origin as\n * the API endpoint, at `/monitor/claim?site=<uuid>`. Using the API endpoint's\n * origin (rather than a hard-coded https://api.patchstack.com) means staging,\n * ngrok tunnels and local dev environments all produce a claim URL on the same\n * host the connector is already talking to.\n */\nexport function buildClaimUrl(endpoint: string, siteUuid: string): string {\n const origin = new URL(endpoint).origin;\n return `${origin}/monitor/claim?site=${encodeURIComponent(siteUuid)}`;\n}\n\n/**\n * Build the public widget-settings URL for a site. Like the claim URL, it\n * lives on the API endpoint's origin, at `/monitor/widget/settings/<uuid>`.\n */\nexport function buildSettingsUrl(endpoint: string, siteUuid: string): string {\n const origin = new URL(endpoint).origin;\n return `${origin}/monitor/widget/settings/${encodeURIComponent(siteUuid)}`;\n}\n\n/** Build the package-removed signal URL corresponding to a manifest endpoint override. */\nexport function buildPackageRemovedUrl(manifestEndpoint: string, siteUuid: string): string {\n const url = new URL(manifestEndpoint);\n const path = url.pathname.replace(/\\/$/, '');\n url.pathname = path.endsWith('/manifest')\n ? `${path.slice(0, -'/manifest'.length)}/package-removed/${encodeURIComponent(siteUuid)}`\n : `/monitor/pulse/package-removed/${encodeURIComponent(siteUuid)}`;\n url.search = '';\n url.hash = '';\n return url.toString();\n}\n\n/** Build the input-map ingest URL corresponding to a manifest endpoint override. */\nexport function buildInputMapUrl(manifestEndpoint: string, siteUuid: string): string {\n const url = new URL(manifestEndpoint);\n const path = url.pathname.replace(/\\/$/, '');\n url.pathname = path.endsWith('/manifest')\n ? `${path.slice(0, -'/manifest'.length)}/input-map/${encodeURIComponent(siteUuid)}`\n : `/monitor/pulse/input-map/${encodeURIComponent(siteUuid)}`;\n url.search = '';\n url.hash = '';\n return url.toString();\n}\n\n/**\n * Outcome of uploading an attack-surface map. `unchanged` is a first-class result, not a failure: most\n * builds do not change the surface, and the server keeps one revision per distinct surface rather than\n * one per deploy. `skipped` covers the cases where there is nothing to send or nowhere to send it.\n */\nexport type InputMapUploadOutcome =\n | { result: 'stored'; revision: number }\n | { result: 'unchanged'; revision: number }\n | { result: 'skipped'; message: string }\n | { result: 'failed'; message: string };\n\n/**\n * Upload an attack-surface map for this site.\n *\n * Fail-open by construction: every failure path returns a result rather than throwing, because this runs\n * during someone's build and a Patchstack outage must never break it. The caller decides what to print.\n */\nexport async function postInputMap(\n config: Config,\n map: { version: number; endpoints: unknown[] },\n): Promise<InputMapUploadOutcome> {\n if (config.siteUuid === null) {\n return { result: 'skipped', message: 'No site UUID configured — run `patchstack-connect scan` first.' };\n }\n\n const url = buildInputMapUrl(config.endpoint, config.siteUuid);\n try {\n const response = await pulseFetch(config, url, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'User-Agent': '@patchstack/connect',\n },\n body: JSON.stringify(map),\n signal: AbortSignal.timeout(config.timeoutMs),\n });\n if (response.status === 404) {\n return { result: 'failed', message: 'Site not found — the configured site UUID is unknown to Patchstack.' };\n }\n if (response.status === 422) {\n // The server implements a different map schema than this client emits. Say so plainly: it means\n // one side is out of date, and guessing at compatibility is how a consumer misreads a document.\n return { result: 'failed', message: `Patchstack does not accept this map schema (version ${map.version}). Update @patchstack/connect.` };\n }\n const refused = authFailureMessage(response.status, config);\n if (refused !== null) {\n return { result: 'failed', message: refused };\n }\n if (!response.ok) {\n return { result: 'failed', message: `Patchstack returned ${response.status}.` };\n }\n const body = (await response.json()) as { result?: string; revision?: number };\n // The revision is part of the contract, not decoration: \"stored, revision 0\" is not a state the server\n // can be in, so accepting it would report a successful upload that cannot be pointed at afterwards.\n const revision = Number(body.revision);\n if ((body.result === 'stored' || body.result === 'unchanged') && Number.isInteger(revision) && revision > 0) {\n return { result: body.result, revision };\n }\n return { result: 'failed', message: 'Patchstack returned an unexpected response.' };\n } catch {\n return { result: 'failed', message: `Could not reach Patchstack at ${url}.` };\n }\n}\n\n/**\n * Outcome of the package-removed signal. 'deleted' — the site was unclaimed\n * and its record was removed; 'flagged' — the site is claimed, so it was only\n * marked for its owner to confirm removal in the dashboard; 'gone' — the\n * record no longer existed; 'failed' — Patchstack could not be reached or\n * returned an unexpected response.\n */\nexport interface PackageRemovedOutcome {\n result: 'deleted' | 'flagged' | 'gone' | 'failed';\n message: string | null;\n}\n\n/**\n * Tell Patchstack the @patchstack/connect package is being uninstalled from\n * this project. The site UUID is the only credential, so the server deletes\n * only unclaimed (anonymous) sites; claimed sites are merely flagged for\n * their owner. Never throws — an unreachable server must not block the local\n * uninstall.\n */\nexport async function postPackageRemoved(config: Config): Promise<PackageRemovedOutcome> {\n if (config.siteUuid === null) {\n return { result: 'failed', message: 'No site UUID configured.' };\n }\n\n const url = buildPackageRemovedUrl(config.endpoint, config.siteUuid);\n try {\n const response = await pulseFetch(config, url, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'User-Agent': '@patchstack/connect',\n },\n signal: AbortSignal.timeout(config.timeoutMs),\n });\n if (response.status === 404) {\n return { result: 'gone', message: null };\n }\n // A site that has been deleted answers 401 here, not 404: this route resolves the site FROM the\n // credential, so once the site record is gone the credential resolves to nothing. Reporting that as\n // an auth failure would tell someone to re-run `login` over a site that no longer exists, so the\n // question is put to the endpoint that can still answer it — widget settings, which needs no\n // credential and 404s for a removed site.\n if (response.status === 401 && (await fetchSiteStatus(config)) === 'removed') {\n return { result: 'gone', message: null };\n }\n const refused = authFailureMessage(response.status, config);\n if (refused !== null) {\n return { result: 'failed', message: refused };\n }\n if (!response.ok) {\n return { result: 'failed', message: `Patchstack returned ${response.status}.` };\n }\n const body = (await response.json()) as { status?: string; message?: string };\n if (body.status === 'deleted' || body.status === 'flagged') {\n return { result: body.status, message: body.message ?? null };\n }\n return { result: 'failed', message: 'Patchstack returned an unexpected response.' };\n } catch {\n return { result: 'failed', message: `Could not reach Patchstack at ${url}.` };\n }\n}\n\n/**\n * Whether the site record still exists on Patchstack's side. Removing a site\n * (dashboard delete or the widget's uninstall flow) only deletes the remote\n * record — the local integration files stay in the project — so this is the\n * signal that distinguishes \"removed from Patchstack\" from \"still active\".\n */\nexport type SiteStatus = 'active' | 'removed' | 'unknown';\n\n/**\n * Check the remote site status via the public widget-settings endpoint:\n * 200 means the site record exists, 404 means it was removed. Any other\n * response or a network failure is 'unknown' — never throws. The endpoint's\n * 200 responses are cacheable for an hour, so a cache-busting query param\n * keeps intermediaries from reporting a just-removed site as active.\n */\nexport async function fetchSiteStatus(config: Config): Promise<SiteStatus> {\n if (config.siteUuid === null) return 'unknown';\n\n const url = new URL(buildSettingsUrl(config.endpoint, config.siteUuid));\n url.searchParams.set('t', Date.now().toString());\n\n try {\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'Cache-Control': 'no-cache',\n 'User-Agent': '@patchstack/connect',\n },\n signal: AbortSignal.timeout(config.timeoutMs),\n });\n if (response.status === 404) return 'removed';\n if (response.ok) return 'active';\n return 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nexport async function postManifest(\n config: Config,\n payload: WirePayload,\n): Promise<StoreManifestResponse> {\n const url = buildEndpointUrl(config.endpoint, config.siteUuid);\n const timeoutMs = config.timeoutMs;\n\n let response: Response;\n try {\n // Unauthenticated on the bootstrap POST: there is no credential until this\n // request issues one.\n response = await pulseFetch(config, url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'User-Agent': '@patchstack/connect',\n },\n body: JSON.stringify({ ...payload, environment: config.environment }),\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (cause) {\n if (isTimeoutError(cause)) {\n throw new PatchstackError(\n `Patchstack request to ${url} timed out after ${timeoutMs}ms. Override with PATCHSTACK_TIMEOUT_MS.`,\n 'NETWORK_TIMEOUT',\n cause,\n );\n }\n throw new PatchstackError(\n `Could not reach Patchstack at ${url}. Check your network connection.`,\n 'NETWORK_ERROR',\n cause,\n );\n }\n\n const text = await response.text();\n let body: StoreManifestResponse | null = null;\n try {\n body = text.length > 0 ? (JSON.parse(text) as StoreManifestResponse) : null;\n } catch {\n body = null;\n }\n\n if (response.status === 404) {\n throw new PatchstackError(\n body?.error ?? 'Site not found. Check that your site UUID is correct and that the app is registered as a Pulse app in your Patchstack dashboard.',\n 'SITE_NOT_FOUND',\n );\n }\n\n if (response.status === 422) {\n throw new PatchstackError(\n body?.message ?? 'Patchstack rejected the manifest payload (validation failed).',\n 'VALIDATION_ERROR',\n );\n }\n\n const refused = authFailureMessage(response.status, config);\n if (refused !== null) {\n throw new PatchstackError(refused, 'UNAUTHORIZED');\n }\n\n if (response.status < 200 || response.status >= 300) {\n throw new PatchstackError(\n `Patchstack returned ${response.status}: ${text.slice(0, 200)}`,\n 'SERVER_ERROR',\n );\n }\n\n if (body === null) {\n throw new PatchstackError('Patchstack returned an empty response.', 'SERVER_ERROR');\n }\n\n return body;\n}\n\nfunction isTimeoutError(cause: unknown): boolean {\n if (cause instanceof Error) {\n return cause.name === 'TimeoutError' || cause.name === 'AbortError';\n }\n return false;\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { scanLockfile } from './parsers/index.js';\nimport { buildRulesUrl } from './client.js';\nimport type { PackageManager } from './guide.js';\n\nexport interface DemoScenario {\n name: string;\n packageName: string;\n packageVersion: string;\n ruleId: number;\n maliciousBody: Record<string, string>;\n benignBody: Record<string, string>;\n}\n\nexport interface PulseRule {\n id?: string | number;\n title?: string;\n rule_v2?: unknown[];\n}\n\nexport const NODE_SERIALIZE_DEMO: DemoScenario = {\n name: 'node-serialize',\n packageName: 'node-serialize',\n packageVersion: '0.0.4',\n ruleId: 18843,\n maliciousBody: {\n text: \"_$$ND_FUNC$$_function(){require('child_process').exec('id')}()\",\n },\n benignBody: { text: 'buy milk' },\n};\n\nconst SCENARIOS = new Map([[NODE_SERIALIZE_DEMO.name, NODE_SERIALIZE_DEMO]]);\n\nexport class DemoError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DemoError';\n }\n}\n\nexport interface DemoDependencyState {\n ready: boolean;\n versions: string[];\n}\n\nexport interface DemoGuideState {\n scenario: DemoScenario;\n packageManager: PackageManager;\n siteUuid: string | null;\n dependency: DemoDependencyState;\n environment: 'production' | 'sandbox';\n url: string;\n}\n\nconst DEMO_INSTALL_COMMANDS: Record<PackageManager, string> = {\n npm: 'npm install --save-exact node-serialize@0.0.4',\n pnpm: 'pnpm add --save-exact node-serialize@0.0.4',\n yarn: 'yarn add --exact node-serialize@0.0.4',\n bun: 'bun add --exact node-serialize@0.0.4',\n};\n\nconst DEMO_REMOVE_COMMANDS: Record<PackageManager, string> = {\n npm: 'npm uninstall node-serialize',\n pnpm: 'pnpm remove node-serialize',\n yarn: 'yarn remove node-serialize',\n bun: 'bun remove node-serialize',\n};\n\nexport function resolveDemoScenario(name: string | undefined): DemoScenario {\n if (!name) {\n throw new DemoError(\n 'A demo scenario is required. Available scenario: node-serialize.\\n' +\n 'Usage: patchstack-connect demo node-serialize',\n );\n }\n const scenario = SCENARIOS.get(name);\n if (!scenario) {\n throw new DemoError(`Unknown demo scenario \"${name}\". Available scenario: node-serialize.`);\n }\n return scenario;\n}\n\nasync function collectDemoDependency(\n cwd: string,\n scenario: DemoScenario,\n): Promise<DemoDependencyState> {\n const manifest = await scanLockfile(cwd);\n const versions = [\n ...new Set(\n manifest.packages\n .filter((entry) => entry.name === scenario.packageName)\n .map((entry) => entry.version),\n ),\n ].sort();\n return { ready: versions.includes(scenario.packageVersion), versions };\n}\n\nexport async function inspectDemoDependency(\n cwd: string,\n scenario: DemoScenario,\n): Promise<DemoDependencyState> {\n try {\n return await collectDemoDependency(cwd, scenario);\n } catch {\n return { ready: false, versions: [] };\n }\n}\n\nexport async function assertDemoDependency(cwd: string, scenario: DemoScenario): Promise<void> {\n const { ready, versions } = await collectDemoDependency(cwd, scenario);\n if (ready) return;\n\n const found = versions.length > 0 ? ` Found: ${versions.join(', ')}.` : '';\n throw new DemoError(\n `${scenario.packageName}@${scenario.packageVersion} is not installed in the lockfile.${found}\\n` +\n `Add this deliberately vulnerable package first: npm install --save-exact ${scenario.packageName}@${scenario.packageVersion}`,\n );\n}\n\nexport async function readPersistedSiteUuid(cwd: string): Promise<string | null> {\n try {\n const value = JSON.parse(await readFile(join(cwd, '.patchstackrc.json'), 'utf8')).siteUuid;\n return typeof value === 'string' && value.length > 0 ? value : null;\n } catch {\n return null;\n }\n}\n\nexport async function assertPersistedSiteUuid(cwd: string, expectedUuid: string): Promise<void> {\n const persisted = await readPersistedSiteUuid(cwd);\n if (persisted === null) {\n throw new DemoError(\n 'The demo requires the Host-connected .patchstackrc.json. Connect Patchstack in Bolt first, then try again.',\n );\n }\n if (persisted !== expectedUuid) {\n throw new DemoError(\n `The active site UUID (${expectedUuid}) does not match .patchstackrc.json (${String(persisted)}). ` +\n 'Remove the UUID override or reconnect this Bolt project before running the demo.',\n );\n }\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nexport function renderDemoGuide(state: DemoGuideState): string {\n const { scenario } = state;\n const install = DEMO_INSTALL_COMMANDS[state.packageManager].replace(\n 'node-serialize@0.0.4',\n `${scenario.packageName}@${scenario.packageVersion}`,\n );\n const remove = DEMO_REMOVE_COMMANDS[state.packageManager].replace(\n 'node-serialize',\n scenario.packageName,\n );\n const demo =\n state.url === 'http://localhost:3000/api/tasks'\n ? `npx @patchstack/connect demo ${scenario.name}`\n : `npx @patchstack/connect demo ${scenario.name} --url ${shellQuote(state.url)}`;\n const siteReady = state.siteUuid !== null;\n const envReady = state.environment === 'production';\n const dependencyDetail = state.dependency.ready\n ? `${scenario.packageName}@${scenario.packageVersion} is in the lockfile`\n : state.dependency.versions.length > 0\n ? `found ${scenario.packageName}@${state.dependency.versions.join(', ')}; ${scenario.packageVersion} is required`\n : `${scenario.packageName}@${scenario.packageVersion} is not in the lockfile`;\n\n let next: string;\n if (!siteReady) {\n next = 'Click “Connect Patchstack” in Bolt, then run this guide again.';\n } else if (!envReady) {\n next = 'Unset PATCHSTACK_ENVIRONMENT (or set it to production), then run this guide again.';\n } else if (!state.dependency.ready) {\n next = install;\n } else {\n next = demo;\n }\n\n return [\n `Patchstack demo guide — ${scenario.name}`,\n '',\n 'Goal: prove that a live Patchstack virtual patch blocks the vulnerable payload while normal traffic still succeeds.',\n 'Deployment required: no. Keep the app running locally; the connector and generated guard contact Patchstack’s production API.',\n '',\n `1. ${siteReady ? '✓' : '○'} Connect this project from Bolt’s Host account dropdown`,\n siteReady\n ? ` Ready — .patchstackrc.json contains site ${state.siteUuid}.`\n : ' Click “Connect Patchstack” in Bolt. This creates .patchstackrc.json; no separate CLI login is needed.',\n '',\n `2. ${state.dependency.ready ? '✓' : '○'} Add the deliberately vulnerable demo dependency`,\n ` ${dependencyDetail}.`,\n ` ${install}`,\n ' Do not import or execute this package; its lockfile entry is enough for detection.',\n '',\n '3. ○ Run the production-backed demo setup',\n ` ${demo}`,\n ...(envReady\n ? []\n : [' Blocked for now: this walkthrough needs PATCHSTACK_ENVIRONMENT=production.']),\n ` This scans the npm manifest, waits for live rule ${scenario.ruleId}, installs the server guard, verifies its wiring, and prints two test requests.`,\n ' It does not start the server or send the requests.',\n '',\n '4. ○ Restart the local dev server',\n ' Restart after the demo command so the application loads the generated guard.',\n '',\n '5. ○ Run both requests printed by the demo command',\n ` Exploit: expect HTTP 403 with Patchstack rule ${scenario.ruleId}.`,\n ' Control (“buy milk”): expect HTTP 201. This proves normal traffic is not blocked.',\n '',\n '6. ○ Clean up the throwaway vulnerability after the demonstration',\n ` ${remove}`,\n ' Re-run `npx @patchstack/connect scan` so the clean manifest is reported.',\n '',\n `Next: ${next}`,\n ].join('\\n');\n}\n\ninterface WaitForRuleOptions {\n timeoutMs?: number;\n pollIntervalMs?: number;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n sleep?: (ms: number) => Promise<void>;\n now?: () => number;\n}\n\nexport async function waitForDemoRule(\n manifestEndpoint: string,\n siteUuid: string,\n scenario: DemoScenario,\n options: WaitForRuleOptions = {},\n): Promise<PulseRule> {\n const timeoutMs = options.timeoutMs ?? 30_000;\n const pollIntervalMs = options.pollIntervalMs ?? 1_000;\n const requestTimeoutMs = options.requestTimeoutMs ?? 10_000;\n const fetchFn = options.fetchFn ?? fetch;\n const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));\n const now = options.now ?? Date.now;\n const started = now();\n const rulesUrl = buildRulesUrl(manifestEndpoint, siteUuid);\n let lastDetail = 'the rule list was empty';\n\n do {\n try {\n const response = await fetchFn(rulesUrl, {\n headers: { Accept: 'application/json', 'User-Agent': '@patchstack/connect' },\n signal: AbortSignal.timeout(requestTimeoutMs),\n });\n if (response.ok) {\n const data = (await response.json()) as { firewall?: PulseRule[] };\n const rules = Array.isArray(data.firewall) ? data.firewall : [];\n const matched = rules.find((rule) => String(rule.id) === String(scenario.ruleId));\n if (matched) return matched;\n lastDetail = `${rules.length} firewall rule(s) returned without rule ${scenario.ruleId}`;\n } else {\n lastDetail = `the rules API returned HTTP ${response.status}`;\n }\n } catch (error) {\n lastDetail = `the rules request failed: ${(error as Error).message}`;\n }\n\n const remaining = timeoutMs - (now() - started);\n if (remaining <= 0) break;\n await sleep(Math.min(pollIntervalMs, remaining));\n } while (now() - started <= timeoutMs);\n\n throw new DemoError(\n `Timed out waiting for Patchstack rule ${scenario.ruleId} for site ${siteUuid}; ${lastDetail}.`,\n );\n}\n\nexport function renderDemoTestCommands(url: string, scenario: DemoScenario): string {\n const shellUrl = shellQuote(url);\n const command = (body: Record<string, string>) => {\n const encoded = Buffer.from(JSON.stringify(body)).toString('base64');\n return `node -e \"process.stdout.write(Buffer.from('${encoded}','base64'))\" | curl -i -X POST --url ${shellUrl} -H \"Content-Type: application/json\" --data-binary @-`;\n };\n return [\n 'Restart the dev server so it loads the generated guard, then run:',\n '',\n `Blocked exploit (expect HTTP 403 and rule ${scenario.ruleId}):`,\n command(scenario.maliciousBody),\n '',\n 'Benign request (expect HTTP 201):',\n command(scenario.benignBody),\n ].join('\\n');\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { PatchstackError, type Config, type Environment } from './types.js';\nimport { DEFAULT_ENDPOINT, DEFAULT_TIMEOUT_MS } from './client.js';\n\nconst CONFIG_FILENAME = '.patchstackrc.json';\n\nexport const DEFAULT_ENVIRONMENT: Environment = 'production';\n\ninterface ConfigFile {\n siteUuid?: string;\n /** WP-format `{secret}-{oauth.id}` for connector /api/logs/log. Server-only. */\n apiKey?: string;\n /**\n * Credential for the authenticated Pulse endpoints (ADR-0018). Same format as\n * `apiKey` and today the same value, but kept as its own field so the Pulse\n * and block-log paths can diverge without disturbing each other. Server-only.\n */\n pulseAuth?: string;\n endpoint?: string;\n timeoutMs?: number;\n environment?: string;\n widget?: boolean;\n}\n\nexport interface ResolveConfigOptions {\n cwd: string;\n cliSiteUuid?: string;\n cliEndpoint?: string;\n /**\n * When true, resolveConfig throws CONFIG_MISSING if no site UUID is configured.\n * Defaults to false: callers that can run without a UUID (the first `scan` after\n * `npm install`) just get `siteUuid: null` back and learn the UUID from the\n * server response.\n */\n requireSiteUuid?: boolean;\n}\n\nexport async function resolveConfig(options: ResolveConfigOptions): Promise<Config> {\n const fromFile = await readConfigFile(options.cwd);\n const fromEnv = readEnv();\n\n const siteUuid =\n options.cliSiteUuid ??\n fromEnv.siteUuid ??\n fromFile.siteUuid ??\n null;\n\n const endpoint =\n options.cliEndpoint ??\n fromEnv.endpoint ??\n fromFile.endpoint ??\n DEFAULT_ENDPOINT;\n\n const timeoutMs = fromEnv.timeoutMs ?? fromFile.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n const environmentRaw = fromEnv.environment ?? fromFile.environment;\n if (environmentRaw !== undefined && !isEnvironment(environmentRaw)) {\n throw new PatchstackError(\n `Environment must be \"production\" or \"sandbox\"; got \"${environmentRaw}\".`,\n 'CONFIG_INVALID',\n );\n }\n const environment: Environment = environmentRaw ?? DEFAULT_ENVIRONMENT;\n\n if (siteUuid !== null && siteUuid.length > 0 && !isUuid(siteUuid)) {\n throw new PatchstackError(\n `Site UUID \"${siteUuid}\" does not look like a valid UUID.`,\n 'CONFIG_INVALID',\n );\n }\n\n if (options.requireSiteUuid && (siteUuid === null || siteUuid.length === 0)) {\n throw new PatchstackError(\n 'No site UUID configured. Run `patchstack-connect scan` to provision one, or set PATCHSTACK_SITE_UUID.',\n 'CONFIG_MISSING',\n );\n }\n\n const apiKeyRaw = fromEnv.apiKey ?? fromFile.apiKey ?? null;\n // Falls back to apiKey so sites provisioned before ADR-0018 authenticate\n // without re-provisioning: today both hold the same credential.\n const pulseAuthRaw = fromEnv.pulseAuth ?? fromFile.pulseAuth ?? apiKeyRaw;\n\n return {\n siteUuid: siteUuid === null || siteUuid.length === 0 ? null : siteUuid,\n apiKey: apiKeyRaw === null || apiKeyRaw.length === 0 ? null : apiKeyRaw,\n pulseAuth: pulseAuthRaw === null || pulseAuthRaw.length === 0 ? null : pulseAuthRaw,\n endpoint,\n timeoutMs,\n environment,\n widget: fromFile.widget !== false,\n };\n}\n\nexport async function writeConfigFile(cwd: string, config: ConfigFile): Promise<string> {\n const target = path.join(cwd, CONFIG_FILENAME);\n const content = JSON.stringify(config, null, 2) + '\\n';\n await writeFile(target, content, 'utf8');\n return target;\n}\n\n/**\n * Merge a new siteUuid into the existing `.patchstackrc.json` (or create it).\n * Preserves any `endpoint` / `timeoutMs` / `apiKey` the user already wrote.\n */\nexport async function persistSiteUuid(cwd: string, siteUuid: string): Promise<string> {\n const existing = await readConfigFile(cwd);\n return writeConfigFile(cwd, { ...existing, siteUuid });\n}\n\n/**\n * Persist the WP-format api_key issued at provision. Authenticates both the\n * Pulse endpoints and connector log reporting. Never embed it in the public\n * disclosure widget.\n *\n * Drops any `pulseAuth` written by an earlier version. That field resolves\n * ahead of `apiKey`, so leaving a copy behind after the credential changes\n * would leave Pulse authenticating with the value the server just replaced.\n */\nexport async function persistApiKey(cwd: string, apiKey: string): Promise<string> {\n const { pulseAuth: _dropped, ...existing } = await readConfigFile(cwd);\n return writeConfigFile(cwd, { ...existing, apiKey });\n}\n\n/**\n * Persist a Pulse-specific credential.\n *\n * Only needed when Pulse ingest and block-log reporting must use *different*\n * credentials; they share one today, so `persistApiKey` covers both. Retained\n * for callers that separate them.\n */\nexport async function persistPulseAuth(cwd: string, pulseAuth: string): Promise<string> {\n const existing = await readConfigFile(cwd);\n return writeConfigFile(cwd, { ...existing, pulseAuth });\n}\n\nasync function readConfigFile(cwd: string): Promise<ConfigFile> {\n const target = path.join(cwd, CONFIG_FILENAME);\n let raw: string;\n try {\n raw = await readFile(target, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return {};\n }\n throw new PatchstackError(\n `Could not read ${target}: ${(err as Error).message}`,\n 'CONFIG_INVALID',\n err,\n );\n }\n\n try {\n return JSON.parse(raw) as ConfigFile;\n } catch (err) {\n throw new PatchstackError(\n `Config file ${target} contains invalid JSON.`,\n 'CONFIG_INVALID',\n err,\n );\n }\n}\n\nfunction readEnv(): ConfigFile {\n const timeoutRaw = process.env.PATCHSTACK_TIMEOUT_MS;\n let timeoutMs: number | undefined;\n if (timeoutRaw !== undefined && timeoutRaw.length > 0) {\n const parsed = Number(timeoutRaw);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new PatchstackError(\n `PATCHSTACK_TIMEOUT_MS must be a positive number; got \"${timeoutRaw}\".`,\n 'CONFIG_INVALID',\n );\n }\n timeoutMs = parsed;\n }\n const environmentRaw = process.env.PATCHSTACK_ENVIRONMENT;\n return {\n siteUuid: process.env.PATCHSTACK_SITE_UUID ?? undefined,\n apiKey: process.env.PATCHSTACK_API_KEY ?? undefined,\n pulseAuth: process.env.PATCHSTACK_PULSE_AUTH ?? undefined,\n endpoint: process.env.PATCHSTACK_ENDPOINT ?? undefined,\n timeoutMs,\n environment:\n environmentRaw !== undefined && environmentRaw.length > 0 ? environmentRaw : undefined,\n };\n}\n\nfunction isUuid(value: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);\n}\n\nfunction isEnvironment(value: string): value is Environment {\n return value === 'production' || value === 'sandbox';\n}\n","import { existsSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nimport { isEmptyStack, type StackDescriptor } from './stack.js';\n\n/** Attribute that tags our injected <script> so re-runs replace it instead of stacking. */\nexport const MARKER_ATTR = 'data-patchstack-build';\n\n/** Build output directories we look for, in priority order (Vite, CRA, Next export, Nuxt). */\nexport const BUILD_DIR_CANDIDATES = ['dist', 'build', 'out', '.output/public'];\n\n/**\n * Resolve the directory holding the built HTML. Honours an explicit `--dir`\n * override, otherwise picks the first known build directory that exists.\n * Returns null when nothing is found (mark-build then no-ops without failing).\n */\nexport function resolveBuildDir(cwd: string, override?: string): string | null {\n if (override !== undefined && override !== '') {\n const abs = path.resolve(cwd, override);\n return existsSync(abs) && statSync(abs).isDirectory() ? abs : null;\n }\n\n for (const candidate of BUILD_DIR_CANDIDATES) {\n const abs = path.resolve(cwd, candidate);\n if (existsSync(abs) && statSync(abs).isDirectory()) {\n return abs;\n }\n }\n\n return null;\n}\n\n/** Recursively collect every `.html` file under `dir`. */\nexport function findHtmlFiles(dir: string): string[] {\n const out: string[] = [];\n\n const walk = (current: string): void => {\n for (const entry of readdirSync(current, { withFileTypes: true })) {\n const full = path.join(current, entry.name);\n if (entry.isDirectory()) {\n walk(full);\n } else if (entry.isFile() && entry.name.toLowerCase().endsWith('.html')) {\n out.push(full);\n }\n }\n };\n\n walk(dir);\n return out;\n}\n\n/**\n * The <script> we inject into built HTML. Always marks the build as production\n * (so the widget hides the connect/claim prompt on the published site) and, when\n * available, exposes the build fingerprint (for the parity heartbeat) and the\n * detected stack descriptor (so the widget can report how the site was built).\n */\nexport function buildInjectionSnippet(\n checksum: string | null,\n stack?: StackDescriptor | null,\n): string {\n const statements = ['window.__PATCHSTACK_PROD__=true;'];\n if (checksum !== null && checksum !== '') {\n statements.push(`window.__PATCHSTACK_BUILD__=${JSON.stringify(checksum)};`);\n }\n if (stack != null && !isEmptyStack(stack)) {\n statements.push(`window.__PATCHSTACK_STACK__=${JSON.stringify(stack)};`);\n }\n return `<script ${MARKER_ATTR}>${statements.join('')}</script>`;\n}\n\n/**\n * Insert (or replace) the marker script in a single HTML document. Idempotent:\n * a prior marker is stripped first so repeated builds don't stack tags. Prefers\n * `</head>`, falls back to `</body>`, then appends.\n */\nexport function injectMarker(html: string, snippet: string): string {\n const stripped = html.replace(\n new RegExp(`\\\\s*<script ${MARKER_ATTR}[^>]*>[\\\\s\\\\S]*?</script>`, 'gi'),\n '',\n );\n\n if (/<\\/head>/i.test(stripped)) {\n return stripped.replace(/<\\/head>/i, `${snippet}</head>`);\n }\n if (/<\\/body>/i.test(stripped)) {\n return stripped.replace(/<\\/body>/i, `${snippet}</body>`);\n }\n return stripped + snippet;\n}\n\n/* ------------------------------------------------------------------ */\n/* Source-shell marking (server-rendered roots) */\n/* ------------------------------------------------------------------ */\n\n/**\n * Frameworks whose root shell is JSX. These get a literal snippet; every other\n * code shell gets the requirement described instead, because its head mechanism\n * (`useHead`, `<svelte:head>`, Astro frontmatter) is not a plain script tag and\n * a wrong snippet costs more than an accurate sentence.\n */\nconst JSX_SHELL_FRAMEWORKS = new Set([\n 'next',\n 'remix',\n 'react-router',\n 'tanstack-start',\n 'gatsby',\n]);\n\n/**\n * How each framework spells \"this is a production build\" in source. Vite-built\n * roots use `import.meta.env.PROD`, which the bundler statically replaces;\n * bundlers that don't define it fall back to NODE_ENV.\n *\n * The gate is load-bearing: an ungated marker also fires in the hosted builder's\n * dev preview, which is exactly where the owner still needs the claim flow.\n */\nconst PRODUCTION_GATES: Record<string, string> = {\n next: \"process.env.NODE_ENV === 'production'\",\n gatsby: \"process.env.NODE_ENV === 'production'\",\n nuxt: '!import.meta.dev',\n};\n\nconst DEFAULT_PRODUCTION_GATE = 'import.meta.env.PROD';\n\n/** The build-time expression that must guard the marker for this framework. */\nexport function productionGate(framework: string | null): string {\n const mapped = framework !== null ? PRODUCTION_GATES[framework] : undefined;\n return mapped ?? DEFAULT_PRODUCTION_GATE;\n}\n\n/** True when `guide` can print a literal marker snippet for this framework. */\nexport function hasJsxShell(framework: string | null): boolean {\n return framework !== null && JSX_SHELL_FRAMEWORKS.has(framework);\n}\n\n/**\n * The production marker as it belongs in a JSX root shell.\n *\n * Server-rendered roots never produce a static HTML file for `mark-build` to\n * stamp, so on those stacks this is the only path the marker has to production.\n * It stays an inline document script rather than a module-level assignment: the\n * widget tag is `defer`, and only a parser-executed inline script is ordered\n * ahead of it for certain.\n */\nexport function buildSourceMarkerSnippet(framework: string | null): string {\n const gate = productionGate(framework);\n return (\n `{${gate} && (\\n` +\n ` <script\\n` +\n ` ${MARKER_ATTR}=\"true\"\\n` +\n ` dangerouslySetInnerHTML={{ __html: 'window.__PATCHSTACK_PROD__=true;' }}\\n` +\n ` />\\n` +\n `)}`\n );\n}\n\n/** Global the widget reads to decide it is running on a published build. */\nconst PROD_MARKER_GLOBAL = '__PATCHSTACK_PROD__';\n\n/**\n * JSX comment fence around the injected marker. Mirrors the `#region` fence the\n * protect installer uses on server entries: it makes the block obviously ours,\n * and lets a re-run replace it instead of stacking copies.\n */\nconst REGION_OPEN = '{/* #region patchstack (managed by patchstack-connect — do not edit) */}';\nconst REGION_CLOSE = '{/* #endregion patchstack */}';\nconst REGION_RE = /[ \\t]*\\{\\/\\* #region patchstack[\\s\\S]*?#endregion patchstack \\*\\/\\}\\n?/g;\n\nexport type SourceMarkerAction =\n /** The managed block was inserted (or refreshed in place). */\n | 'added'\n /** A marker is already present and not ours — adopted, left untouched. */\n | 'manual'\n /** No JSX anchor to attach to; the caller falls back to printing the snippet. */\n | 'no-anchor'\n /** This framework's root shell is not JSX, so there is no snippet to insert. */\n | 'unsupported';\n\nexport interface SourceMarkerResult {\n source: string;\n action: SourceMarkerAction;\n}\n\n/**\n * Insert the production marker into a JSX root shell, idempotently.\n *\n * Anchors on the widget tag when one is present, so the marker is ordered ahead\n * of it in the document; otherwise on `<head>`, then `<body>`. A marker the\n * developer placed themselves is adopted rather than duplicated.\n */\nexport function ensureMarkerInJsxShell(source: string, framework: string | null): SourceMarkerResult {\n if (!hasJsxShell(framework)) {\n return { source, action: 'unsupported' };\n }\n\n const stripped = source.replace(REGION_RE, '');\n if (stripped.includes(PROD_MARKER_GLOBAL)) {\n return { source, action: 'manual' };\n }\n\n const block = (indent: string): string =>\n [REGION_OPEN, ...buildSourceMarkerSnippet(framework).split('\\n'), REGION_CLOSE]\n .map((line) => `${indent}${line}`)\n .join('\\n');\n\n const widget = stripped.match(/^([ \\t]*).*patchstack-widget.*$/m);\n if (widget?.index !== undefined) {\n const indent = widget[1] ?? '';\n return {\n source: `${stripped.slice(0, widget.index)}${block(indent)}\\n${stripped.slice(widget.index)}`,\n action: 'added',\n };\n }\n\n for (const anchor of [/^([ \\t]*)<head>[ \\t]*$/m, /^([ \\t]*)<body>[ \\t]*$/m]) {\n const match = stripped.match(anchor);\n if (match?.index === undefined) {\n continue;\n }\n const end = match.index + match[0].length;\n const indent = `${match[1] ?? ''} `;\n return {\n source: `${stripped.slice(0, end)}\\n${block(indent)}${stripped.slice(end)}`,\n action: 'added',\n };\n }\n\n return { source, action: 'no-anchor' };\n}\n\nexport interface EnsureSourceMarkerResult extends SourceMarkerResult {\n /** Project-relative shell that was inspected, or null when there is none. */\n shell: string | null;\n}\n\n/**\n * Ensure the production marker in the project's JSX root shell. Runs during\n * `scan`, which is a pre-build hook, so the edit is picked up by the build that\n * follows — the marker reaches production without anyone pasting anything.\n */\nexport function ensureSourceMarker(\n cwd: string,\n shell: string | null,\n framework: string | null,\n): EnsureSourceMarkerResult {\n if (shell === null) {\n return { shell: null, source: '', action: 'no-anchor' };\n }\n const file = path.resolve(cwd, shell);\n const before = readFileSync(file, 'utf8');\n const result = ensureMarkerInJsxShell(before, framework);\n if (result.source !== before && result.action === 'added') {\n writeFileSync(file, result.source);\n }\n return { ...result, shell };\n}\n","import type { WirePackage } from './normalize.js';\n\n/**\n * A best-effort description of the stack a build was produced with, derived\n * entirely from the lockfile (ground truth) plus the build-time environment.\n *\n * The disclosure widget reads this from `window.__PATCHSTACK_STACK__` (injected\n * by `mark-build`) and reports it to Patchstack, so we learn how the sites we\n * protect are actually built and hosted — across every \"vibe\" platform — without\n * shipping a runtime probe onto the host server. Every field is a coarse label\n * or a bare key *name*: no versions beyond the framework, and never an env value.\n */\nexport interface StackDescriptor {\n /** App / meta-framework, e.g. \"next\", \"nuxt\", \"tanstack-start\", \"remix\". */\n framework: string | null;\n /** UI runtime, e.g. \"react\", \"vue\", \"svelte\", \"solid\". */\n ui: string | null;\n /** Build tool / bundler, e.g. \"vite\", \"webpack\", \"rspack\". */\n bundler: string | null;\n /** Deployment-runtime hint from deps, e.g. \"cloudflare-workers\", \"vercel\". */\n runtime: string | null;\n /** The vibe/builder platform that generated the project, e.g. \"lovable\". */\n builder: string | null;\n /** Package ecosystem the manifest came from. */\n ecosystem: 'npm';\n /** Hosting-related build-environment variable NAMES (never their values). */\n hostingEnvKeys: string[];\n}\n\ntype Category = 'framework' | 'ui' | 'bundler' | 'runtime' | 'builder';\n\ninterface StackRule {\n category: Category;\n /** Exact package name that signals this label. */\n pkg: string;\n label: string;\n}\n\n/**\n * Package → stack-label registry. First match per category wins, so order\n * within a category is priority order (most specific first). Add a row to teach\n * the connector a new framework, bundler, or vibe platform.\n */\nconst STACK_RULES: readonly StackRule[] = [\n // Meta-frameworks (most specific first).\n { category: 'framework', pkg: '@tanstack/react-start', label: 'tanstack-start' },\n { category: 'framework', pkg: '@tanstack/start', label: 'tanstack-start' },\n { category: 'framework', pkg: 'next', label: 'next' },\n { category: 'framework', pkg: 'nuxt', label: 'nuxt' },\n { category: 'framework', pkg: '@remix-run/react', label: 'remix' },\n { category: 'framework', pkg: '@remix-run/node', label: 'remix' },\n { category: 'framework', pkg: 'react-router', label: 'react-router' },\n { category: 'framework', pkg: 'astro', label: 'astro' },\n { category: 'framework', pkg: '@sveltejs/kit', label: 'sveltekit' },\n { category: 'framework', pkg: '@builder.io/qwik-city', label: 'qwik-city' },\n { category: 'framework', pkg: 'gatsby', label: 'gatsby' },\n { category: 'framework', pkg: 'express', label: 'express' },\n { category: 'framework', pkg: 'fastify', label: 'fastify' },\n\n // UI runtimes.\n { category: 'ui', pkg: '@angular/core', label: 'angular' },\n { category: 'ui', pkg: 'react-dom', label: 'react' },\n { category: 'ui', pkg: 'react', label: 'react' },\n { category: 'ui', pkg: 'vue', label: 'vue' },\n { category: 'ui', pkg: 'svelte', label: 'svelte' },\n { category: 'ui', pkg: 'solid-js', label: 'solid' },\n { category: 'ui', pkg: 'preact', label: 'preact' },\n\n // Bundlers / build tools.\n { category: 'bundler', pkg: 'vite', label: 'vite' },\n { category: 'bundler', pkg: '@rspack/core', label: 'rspack' },\n { category: 'bundler', pkg: 'webpack', label: 'webpack' },\n { category: 'bundler', pkg: 'parcel', label: 'parcel' },\n { category: 'bundler', pkg: 'rollup', label: 'rollup' },\n { category: 'bundler', pkg: 'esbuild', label: 'esbuild' },\n\n // Deployment-runtime hints from build deps.\n { category: 'runtime', pkg: 'wrangler', label: 'cloudflare-workers' },\n { category: 'runtime', pkg: '@cloudflare/workers-types', label: 'cloudflare-workers' },\n { category: 'runtime', pkg: '@cloudflare/vite-plugin', label: 'cloudflare-workers' },\n { category: 'runtime', pkg: '@vercel/node', label: 'vercel' },\n { category: 'runtime', pkg: '@netlify/functions', label: 'netlify' },\n { category: 'runtime', pkg: '@netlify/blobs', label: 'netlify' },\n\n // Vibe / builder platforms — the \"learn from each platform\" signal.\n { category: 'builder', pkg: 'lovable-tagger', label: 'lovable' },\n { category: 'builder', pkg: '@replit/vite-plugin-runtime-error-modal', label: 'replit' },\n { category: 'builder', pkg: '@replit/vite-plugin-cartographer', label: 'replit' },\n];\n\n/** Build-environment variable-name patterns that fingerprint a host, from server-insight. */\nconst HOSTING_ENV_PATTERNS: readonly RegExp[] = [\n /^CF_/,\n /^CLOUDFLARE_/,\n /^VERCEL/,\n /^NETLIFY/,\n /^AWS_(LAMBDA|REGION|EXECUTION)/,\n /^FLY_/,\n /^RENDER/,\n /^RAILWAY_/,\n /^DENO_/,\n /^EDGE_RUNTIME/,\n /^DYNO$/,\n /^K_SERVICE$/,\n /^GAE_/,\n /^FUNCTION_/,\n];\n\n/**\n * Return the sorted NAMES of hosting-related environment variables present in\n * `env`. Only names are surfaced — never values — so a build fingerprint can\n * distinguish \"deployed on Cloudflare\" from \"deployed on Vercel\" without ever\n * disclosing a secret.\n */\nexport function collectHostingEnvKeys(env: NodeJS.ProcessEnv = process.env): string[] {\n return Object.keys(env)\n .filter((key) => HOSTING_ENV_PATTERNS.some((pattern) => pattern.test(key)))\n .sort();\n}\n\n/**\n * Derive a {@link StackDescriptor} from the wire packages and the build\n * environment. Never throws: an unrecognised stack just yields nulls.\n */\nexport function detectStack(\n packages: readonly WirePackage[],\n env: NodeJS.ProcessEnv = process.env,\n): StackDescriptor {\n const present = new Set(packages.map((pkg) => pkg.name));\n\n const firstMatch = (category: Category): string | null => {\n for (const rule of STACK_RULES) {\n if (rule.category === category && present.has(rule.pkg)) {\n return rule.label;\n }\n }\n return null;\n };\n\n return {\n framework: firstMatch('framework'),\n ui: firstMatch('ui'),\n bundler: firstMatch('bundler'),\n runtime: firstMatch('runtime'),\n builder: firstMatch('builder'),\n ecosystem: 'npm',\n hostingEnvKeys: collectHostingEnvKeys(env),\n };\n}\n\n/** True when the descriptor carries no useful signal (nothing worth injecting). */\nexport function isEmptyStack(stack: StackDescriptor): boolean {\n return (\n stack.framework === null &&\n stack.ui === null &&\n stack.bundler === null &&\n stack.runtime === null &&\n stack.builder === null &&\n stack.hostingEnvKeys.length === 0\n );\n}\n","// `patchstack-connect guide` — a state-aware setup checklist.\n//\n// Instead of only printing the generic AGENT-INSTALL.md, the guide first inspects\n// the current project (package.json, lockfile, .patchstackrc.json, source tree)\n// and renders a checklist of what is already done and what is still missing, with\n// the exact commands/snippets for THIS project (right package manager, real site\n// UUID, framework-specific widget placement). Every probe is best-effort: an\n// unreadable project degrades to an all-todo checklist, never a crash.\n\nimport { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport path from 'node:path';\n\nimport { DEFAULT_ENDPOINT, buildClaimUrl } from './client.js';\nimport { resolveConfig } from './config.js';\nimport { runVerify } from './protect/install/index.js';\nimport type { VerifyCheck } from './protect/install/types.js';\nimport {\n buildSourceMarkerSnippet,\n hasJsxShell,\n productionGate,\n} from './mark-build.js';\nimport { detectStack } from './stack.js';\nimport { buildWidgetTag } from './widget.js';\n\n/** Global the widget reads to decide it is running on a published build. */\nconst PROD_MARKER_NEEDLE = '__PATCHSTACK_PROD__';\n\n/** Substring that marks the widget as installed anywhere in the source tree. */\nconst WIDGET_NEEDLE = 'patchstack-widget';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nexport interface GuideState {\n /** package.json `name`, when readable. */\n projectName: string | null;\n hasPackageJson: boolean;\n packageManager: PackageManager;\n /** Version + section when @patchstack/connect is declared, else null. */\n installed: { version: string; section: 'devDependencies' | 'dependencies' } | null;\n siteUuid: string | null;\n claimUrl: string | null;\n /** Non-default API endpoint in effect (rc file, env, or flag), else null. */\n endpointOverride: string | null;\n hasBuildScript: boolean;\n installScanWired: boolean;\n prebuildWired: boolean;\n postbuildWired: boolean;\n widgetInstalled: boolean;\n /** False when the widget is present but its site UUID isn't this project's. */\n widgetTokenMatches: boolean | null;\n /** True when .patchstackrc.json opts out of widget management (\"widget\": false). */\n widgetOptOut: boolean;\n /** Framework label from the declared dependencies (e.g. \"next\"), best-effort. */\n framework: string | null;\n /** Existing file the widget snippet belongs in, best-effort. */\n widgetFileHint: string | null;\n /**\n * True when the root shell already sets `__PATCHSTACK_PROD__`. Only meaningful\n * for code shells: HTML shells get the marker stamped by `mark-build` instead.\n */\n productionMarkerWired: boolean;\n /** Result of the same local inspection used by `protect --check`. */\n protectionWired: boolean;\n protectionStack: string;\n protectionChecks: VerifyCheck[];\n}\n\nconst INSTALL_COMMANDS: Record<PackageManager, string> = {\n npm: 'npm install --save @patchstack/connect',\n pnpm: 'pnpm add @patchstack/connect',\n yarn: 'yarn add @patchstack/connect',\n bun: 'bun add @patchstack/connect',\n};\n\n/**\n * Lockfile → package manager for build-script semantics. Platform-native\n * lockfiles win over package-lock.json because agents often use npm as a\n * fallback inside Bun/pnpm/yarn projects, creating a secondary npm lockfile\n * without changing the platform's actual build runner.\n */\nconst PM_BY_LOCKFILE: ReadonlyArray<{ filename: string; pm: PackageManager }> = [\n { filename: 'bun.lock', pm: 'bun' },\n { filename: 'bun.lockb', pm: 'bun' },\n { filename: 'pnpm-lock.yaml', pm: 'pnpm' },\n { filename: 'yarn.lock', pm: 'yarn' },\n { filename: 'package-lock.json', pm: 'npm' },\n];\n\n/**\n * Framework → candidate layout files the widget snippet belongs in, most\n * specific first. The first candidate that exists in the project wins.\n */\nconst WIDGET_FILE_CANDIDATES: Record<string, string[]> = {\n next: [\n 'app/layout.tsx',\n 'app/layout.jsx',\n 'src/app/layout.tsx',\n 'src/app/layout.jsx',\n 'pages/_document.tsx',\n 'pages/_document.jsx',\n 'src/pages/_document.tsx',\n ],\n nuxt: ['app.vue', 'src/app.vue', 'app/app.vue'],\n remix: ['app/root.tsx', 'app/root.jsx'],\n 'react-router': ['app/root.tsx', 'src/root.tsx'],\n 'tanstack-start': ['src/routes/__root.tsx', 'app/routes/__root.tsx'],\n sveltekit: ['src/app.html'],\n astro: ['src/layouts/Layout.astro'],\n gatsby: ['src/html.js'],\n};\n\n/** Fallback candidates for plain Vite / CRA / static projects. */\nconst GENERIC_WIDGET_FILES = ['index.html', 'public/index.html'];\n\n/** Directories never worth searching for the widget snippet. */\nconst SKIPPED_DIRS = new Set([\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n 'out',\n '.output',\n '.next',\n '.nuxt',\n '.svelte-kit',\n '.vercel',\n '.netlify',\n 'coverage',\n 'vendor',\n]);\n\n/** Source extensions that can carry the widget <script> tags. */\nconst WIDGET_EXTENSIONS = new Set([\n '.html',\n '.htm',\n '.tsx',\n '.jsx',\n '.ts',\n '.js',\n '.mjs',\n '.cjs',\n '.vue',\n '.svelte',\n '.astro',\n '.ejs',\n '.hbs',\n]);\n\nconst WIDGET_SCAN_MAX_FILES = 4000;\nconst WIDGET_SCAN_MAX_DEPTH = 6;\nconst WIDGET_SCAN_MAX_BYTES = 512 * 1024;\n\ninterface PackageJson {\n name?: string;\n packageManager?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n}\n\nexport function detectPackageManager(cwd: string): PackageManager {\n const declared = readPackageJson(cwd)?.packageManager?.split('@')[0];\n if (declared === 'npm' || declared === 'pnpm' || declared === 'yarn' || declared === 'bun') {\n return declared;\n }\n for (const { filename, pm } of PM_BY_LOCKFILE) {\n if (existsSync(path.join(cwd, filename))) {\n return pm;\n }\n }\n return 'npm';\n}\n\nexport function installCommand(pm: PackageManager): string {\n return INSTALL_COMMANDS[pm];\n}\n\nfunction readPackageJson(cwd: string): PackageJson | null {\n try {\n return JSON.parse(readFileSync(path.join(cwd, 'package.json'), 'utf8')) as PackageJson;\n } catch {\n return null;\n }\n}\n\n/** Prefer the actually-installed version over the declared range. */\nfunction installedVersion(cwd: string, declaredRange: string): string {\n try {\n const pkg = JSON.parse(\n readFileSync(path.join(cwd, 'node_modules', '@patchstack', 'connect', 'package.json'), 'utf8'),\n ) as { version?: string };\n if (typeof pkg.version === 'string' && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // fall through to the declared range\n }\n return declaredRange;\n}\n\nexport interface WidgetScanResult {\n found: boolean;\n /**\n * When a site UUID is known: does any file carrying the widget also carry\n * that UUID as its userToken? null when the widget is absent or no UUID is\n * known yet. A stale/wrong userToken makes the widget silently no-op, so a\n * mismatch is worth surfacing rather than passing the check.\n */\n uuidMatches: boolean | null;\n}\n\n/**\n * Bounded recursive search for the widget marker in the source tree. Depth,\n * file-count and file-size capped so the guide stays instant on big projects.\n */\nexport function findWidgetMarker(cwd: string, siteUuid?: string | null): WidgetScanResult {\n let budget = WIDGET_SCAN_MAX_FILES;\n let sawWidget = false;\n let sawTokenMatch = false;\n\n // Stop early only once the answer can't improve: with no UUID to match, the\n // first hit settles it; with a UUID, keep looking until a matching file shows.\n const settled = (): boolean => sawTokenMatch || (sawWidget && siteUuid == null);\n\n const walk = (dir: string, depth: number): void => {\n if (depth > WIDGET_SCAN_MAX_DEPTH || budget <= 0) {\n return;\n }\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (budget <= 0 || settled()) {\n return;\n }\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (SKIPPED_DIRS.has(entry.name) || entry.name.startsWith('.')) {\n continue;\n }\n walk(full, depth + 1);\n continue;\n }\n if (!entry.isFile() || !WIDGET_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) {\n continue;\n }\n budget -= 1;\n try {\n if (statSync(full).size > WIDGET_SCAN_MAX_BYTES) {\n continue;\n }\n const content = readFileSync(full, 'utf8');\n if (!content.includes(WIDGET_NEEDLE)) {\n continue;\n }\n sawWidget = true;\n if (siteUuid != null && content.includes(siteUuid)) {\n sawTokenMatch = true;\n }\n } catch {\n // unreadable file — skip\n }\n }\n };\n\n walk(cwd, 0);\n return {\n found: sawWidget,\n uuidMatches: sawWidget && siteUuid != null ? sawTokenMatch : null,\n };\n}\n\n/**\n * Whether the root shell already carries the production marker. Reads only the\n * file the snippet belongs in — the marker has one correct home, so a tree walk\n * would cost more and answer no better.\n */\nfunction findProductionMarker(cwd: string, widgetFileHint: string | null): boolean {\n if (widgetFileHint === null) {\n return false;\n }\n try {\n return readFileSync(path.join(cwd, widgetFileHint), 'utf8').includes(PROD_MARKER_NEEDLE);\n } catch {\n return false;\n }\n}\n\nexport function resolveWidgetFileHint(cwd: string, framework: string | null): string | null {\n const candidates = [\n ...(framework !== null ? WIDGET_FILE_CANDIDATES[framework] ?? [] : []),\n ...GENERIC_WIDGET_FILES,\n ];\n for (const candidate of candidates) {\n if (existsSync(path.join(cwd, candidate))) {\n return candidate;\n }\n }\n return null;\n}\n\nexport async function collectGuideState(cwd: string): Promise<GuideState> {\n const pkg = readPackageJson(cwd);\n const packageManager = detectPackageManager(cwd);\n\n let installed: GuideState['installed'] = null;\n if (pkg?.devDependencies?.['@patchstack/connect'] !== undefined) {\n installed = {\n version: installedVersion(cwd, pkg.devDependencies['@patchstack/connect']),\n section: 'devDependencies',\n };\n } else if (pkg?.dependencies?.['@patchstack/connect'] !== undefined) {\n installed = {\n version: installedVersion(cwd, pkg.dependencies['@patchstack/connect']),\n section: 'dependencies',\n };\n }\n\n let siteUuid: string | null = null;\n let claimUrl: string | null = null;\n let endpointOverride: string | null = null;\n let widgetOptOut = false;\n try {\n const config = await resolveConfig({ cwd });\n siteUuid = config.siteUuid;\n if (siteUuid !== null) {\n claimUrl = buildClaimUrl(config.endpoint, siteUuid);\n }\n if (config.endpoint !== DEFAULT_ENDPOINT) {\n endpointOverride = config.endpoint;\n }\n widgetOptOut = !config.widget;\n } catch {\n // invalid config — the checklist just shows the site as not provisioned\n }\n\n // Framework detection needs only the declared top-level dependencies, so we\n // read package.json instead of the (much heavier) lockfile scan.\n const declaredNames = Object.keys({ ...pkg?.dependencies, ...pkg?.devDependencies });\n const stack = detectStack(\n declaredNames.map((name) => ({ name, version: '' })),\n {},\n );\n\n const widget = findWidgetMarker(cwd, siteUuid);\n const widgetFileHint = resolveWidgetFileHint(cwd, stack.framework);\n const protection = runVerify(cwd);\n\n return {\n projectName: pkg?.name ?? null,\n hasPackageJson: pkg !== null,\n packageManager,\n installed,\n siteUuid,\n claimUrl,\n endpointOverride,\n hasBuildScript: Boolean(pkg?.scripts?.build?.trim()),\n installScanWired: (pkg?.scripts?.postinstall ?? '').includes('patchstack-connect scan'),\n // bun run doesn't execute npm-style pre/post scripts, so chaining inside\n // the build script itself also counts as wired (and is what we suggest on bun).\n prebuildWired:\n (pkg?.scripts?.prebuild ?? '').includes('patchstack-connect scan') ||\n (pkg?.scripts?.build ?? '').includes('patchstack-connect scan'),\n postbuildWired:\n (pkg?.scripts?.postbuild ?? '').includes('patchstack-connect mark-build') ||\n (pkg?.scripts?.build ?? '').includes('patchstack-connect mark-build'),\n widgetInstalled: widget.found,\n widgetTokenMatches: widget.uuidMatches,\n widgetOptOut,\n framework: stack.framework,\n widgetFileHint: widgetFileHint,\n productionMarkerWired: findProductionMarker(cwd, widgetFileHint),\n protectionWired: protection.wired,\n protectionStack: protection.stack,\n protectionChecks: protection.checks,\n };\n}\n\nconst ANSI = {\n reset: '\\u001B[0m',\n bold: '\\u001B[1m',\n dim: '\\u001B[2m',\n green: '\\u001B[32m',\n yellow: '\\u001B[33m',\n cyan: '\\u001B[36m',\n};\n\n/** Setup steps still missing — 0 means the checklist is fully green. */\n/**\n * True when the site's root shell is code rather than an HTML file. Those roots\n * are server-rendered, so no built HTML file carries the marker to production and\n * `mark-build`'s HTML pass has nothing to stamp.\n */\nexport function needsSourceProductionMarker(state: GuideState): boolean {\n if (state.siteUuid === null || state.widgetOptOut || state.widgetFileHint === null) {\n return false;\n }\n return !state.widgetFileHint.toLowerCase().endsWith('.html');\n}\n\nexport function countRemainingSteps(state: GuideState): number {\n return [\n state.installed?.section === 'dependencies',\n state.siteUuid !== null,\n state.installScanWired,\n !state.hasBuildScript || (state.prebuildWired && state.postbuildWired),\n state.widgetOptOut || (state.widgetInstalled && state.widgetTokenMatches !== false),\n !needsSourceProductionMarker(state) || state.productionMarkerWired,\n state.protectionWired,\n ].filter((step) => !step).length;\n}\n\nexport function renderGuideChecklist(state: GuideState, useColor: boolean): string {\n const paint = (code: string, text: string): string =>\n useColor ? `${code}${text}${ANSI.reset}` : text;\n const done = (text: string): string => ` ${paint(ANSI.green, '✔')} ${text}`;\n const todo = (text: string): string => ` ${paint(ANSI.yellow, '✖')} ${paint(ANSI.bold, text)}`;\n const detail = (text: string): string => ` ${paint(ANSI.dim, text)}`;\n const lines: string[] = [];\n\n const headerParts = [state.framework, state.packageManager].filter(\n (part): part is string => part !== null,\n );\n const name = state.projectName ?? path.basename(process.cwd());\n lines.push(paint(ANSI.bold, `Patchstack setup status — ${name} (${headerParts.join(' · ')})`));\n if (state.endpointOverride !== null) {\n lines.push(\n detail(\n `endpoint override in effect: ${state.endpointOverride} (set via .patchstackrc.json, PATCHSTACK_ENDPOINT, or --endpoint)`,\n ),\n );\n }\n lines.push('');\n\n if (!state.hasPackageJson) {\n lines.push(todo('No package.json found in this directory.'));\n lines.push(detail('Run the guide from the project root.'));\n return lines.join('\\n');\n }\n\n // 1. Install\n if (state.installed?.section === 'dependencies') {\n lines.push(done(`@patchstack/connect installed (${state.installed.version}, ${state.installed.section})`));\n } else if (state.installed !== null) {\n lines.push(todo(`Move @patchstack/connect to runtime dependencies (currently ${state.installed.section})`));\n lines.push(detail(`Run → ${installCommand(state.packageManager)}`));\n lines.push(detail('The generated guard imports @patchstack/connect/protect at runtime.'));\n } else {\n lines.push(todo('Install @patchstack/connect as a runtime dependency'));\n lines.push(detail(`Run → ${installCommand(state.packageManager)}`));\n if (state.packageManager === 'bun') {\n lines.push(detail(`(if bun isn't available here, ${INSTALL_COMMANDS.npm} works too)`));\n }\n }\n\n // 2. Provision (first scan)\n if (state.siteUuid !== null) {\n lines.push(done(`Site provisioned (${state.siteUuid})`));\n } else {\n lines.push(todo('Provision the site — run the first scan'));\n lines.push(detail('Run → npx @patchstack/connect scan'));\n lines.push(detail('Reads the lockfile, registers the project, writes .patchstackrc.json,'));\n lines.push(detail('and prints a dashboard link. The CLI prints the link but never opens it.'));\n }\n\n // 3. Dependency-change scan\n if (state.installScanWired) {\n lines.push(done('Dependency-install scan wired (postinstall)'));\n } else {\n lines.push(todo('Scan again whenever dependencies are installed'));\n lines.push(detail('Edit package.json → \"postinstall\": \"patchstack-connect scan\"'));\n }\n\n // 4. Build hooks\n if (!state.hasBuildScript) {\n lines.push(done('No build script to integrate (postinstall covers dependency changes)'));\n } else if (state.prebuildWired && state.postbuildWired) {\n lines.push(done('Build hooks wired (scan before builds, mark-build after)'));\n } else if (state.packageManager === 'bun') {\n // bun run skips npm-style pre/post scripts, so chain inside the build script.\n lines.push(todo('Wire the build hooks yourself — edit package.json (bun skips pre/post hooks, so chain inside \"build\")'));\n lines.push(detail('Edit package.json → \"build\": \"patchstack-connect scan && <existing build command> && patchstack-connect mark-build\"'));\n } else {\n lines.push(todo('Wire the build hooks yourself — edit package.json \"scripts\" (chain with && if a hook already exists)'));\n if (!state.prebuildWired) {\n lines.push(detail('Edit package.json → \"prebuild\": \"patchstack-connect scan\"'));\n }\n if (!state.postbuildWired) {\n lines.push(detail('Edit package.json → \"postbuild\": \"patchstack-connect mark-build\"'));\n }\n }\n\n // 5. Disclosure widget\n const widgetOk = state.widgetInstalled && state.widgetTokenMatches !== false;\n if (state.widgetOptOut && !widgetOk) {\n lines.push(done('Disclosure widget disabled by config (\"widget\": false in .patchstackrc.json)'));\n } else if (widgetOk) {\n lines.push(done('Disclosure widget installed'));\n } else if (state.widgetInstalled) {\n lines.push(todo(\"Fix the disclosure widget yourself — its site UUID doesn't match this project's\"));\n lines.push(detail(`Edit the widget tag → set data-site-uuid (or userToken) to '${state.siteUuid}' (a wrong UUID makes the widget silently no-op)`));\n } else if (state.siteUuid === null) {\n lines.push(todo('Add the \"Report a vulnerability\" widget — the first scan does this for you'));\n lines.push(detail('Run → npx @patchstack/connect scan (provisions the site and adds the widget tag'));\n lines.push(detail(' to the root HTML shell: index.html / public/index.html / src/app.html)'));\n } else {\n lines.push(todo('Add the \"Report a vulnerability\" widget yourself — this root is code, not a plain HTML shell'));\n lines.push(detail('Note → a normal `scan` adds this tag to a plain HTML shell automatically; add it by hand here:'));\n const placement =\n state.widgetFileHint !== null\n ? `Edit ${state.widgetFileHint} → put it just before </body>:`\n : \"Edit your root layout → put it just before </body> (the framework's HTML/layout mechanism, never a JS entry point):\";\n lines.push(detail(placement));\n lines.push(detail(` ${buildWidgetTag(state.siteUuid)}`));\n lines.push(detail('The site UUID is public by design — it ships in client-side HTML.'));\n }\n\n // 5b. Production marker on server-rendered roots. A code root never emits a\n // static HTML file, so `mark-build` has nothing to stamp and the marker only\n // reaches production if it ships in the shell alongside the widget tag.\n if (needsSourceProductionMarker(state)) {\n if (state.productionMarkerWired) {\n lines.push(done('Production marker wired (widget switches to report mode on the published site)'));\n } else {\n lines.push(todo('Add the production marker — this root is server-rendered, so mark-build cannot stamp it'));\n lines.push(\n detail(\n 'Without it the widget treats the published site as build mode and shows the claim flow to visitors.',\n ),\n );\n const gate = productionGate(state.framework);\n if (hasJsxShell(state.framework)) {\n lines.push(detail(`Run → npx @patchstack/connect scan (adds it to ${state.widgetFileHint} automatically)`));\n lines.push(detail('Or add it by hand, in <head> above the widget tag:'));\n for (const snippetLine of buildSourceMarkerSnippet(state.framework).split('\\n')) {\n lines.push(detail(` ${snippetLine}`));\n }\n } else {\n lines.push(\n detail(\n `Edit ${state.widgetFileHint} → using the framework's head mechanism, emit an inline`,\n ),\n );\n lines.push(detail(` <script>window.__PATCHSTACK_PROD__=true;</script> only when ${gate}.`));\n }\n lines.push(detail(`The ${gate} guard is required — an ungated marker also hides the claim flow in preview.`))\n }\n }\n\n // 6. Runtime protection\n if (state.protectionWired) {\n lines.push(done(`Runtime protection wired (${state.protectionStack})`));\n } else {\n lines.push(todo(`Finish runtime protection (${state.protectionStack})`));\n for (const check of state.protectionChecks.filter((item) => !item.ok)) {\n lines.push(detail(`${check.label}${check.hint ? ` — ${check.hint}` : ''}`));\n }\n lines.push(detail('Verify → npx @patchstack/connect protect --check'));\n }\n\n // 7. Dashboard access — always keep the URL prominent.\n lines.push('');\n if (state.claimUrl !== null) {\n lines.push(` ${paint(ANSI.cyan, '➜')} ${paint(ANSI.bold, 'Dashboard link (open to view reports):')}`);\n lines.push(` ${paint(ANSI.cyan, state.claimUrl)}`);\n lines.push(detail('Open this link in a browser. The CLI never opens it.'));\n if (state.endpointOverride !== null) {\n lines.push(detail('(this URL inherits the endpoint override above)'));\n }\n } else {\n lines.push(detail('The dashboard link appears after the first scan (re-print any time with `status`).'));\n }\n\n const remaining = countRemainingSteps(state);\n lines.push('');\n if (remaining === 0) {\n lines.push(\n done(\n paint(\n ANSI.bold,\n 'All setup steps complete. Commit .patchstackrc.json, package.json, the runtime guard changes, and the file carrying the widget snippet.',\n ),\n ),\n );\n if (state.claimUrl !== null) {\n lines.push(detail('The only manual action left is opening the dashboard link above (if not already connected).'));\n }\n } else {\n lines.push(\n ` ${paint(ANSI.yellow, String(remaining))} step(s) remaining — details in the reference guide below.`,\n );\n }\n\n return lines.join('\\n');\n}\n","// Shared helpers for the `patchstack-connect protect` scaffolder (adapters + orchestrator).\n\nimport { readFileSync, existsSync, writeFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport const read = (p: string): string => readFileSync(p, 'utf8');\nexport const log = (msg: string): void => console.log(`patchstack protect: ${msg}`);\n\n/** True when `name` is in the project's dependencies or devDependencies. */\nexport function hasDependency(cwd: string, name: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }[name]);\n } catch {\n return false;\n }\n}\n\nconst SITE_UUID_PLACEHOLDER = '__PATCHSTACK_SITE_UUID__';\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * Bake the site UUID written by `scan` into a managed runtime-guard template.\n *\n * The UUID is public project configuration (the disclosure widget exposes the\n * same value). Keeping the environment-variable fallback in the template lets\n * unscanned projects remain inert and lets deployments override it explicitly.\n */\nexport function bakeSiteUuid(cwd: string, guardRelPath: string): boolean {\n const rc = join(cwd, '.patchstackrc.json');\n if (!existsSync(rc)) {\n log('no .patchstackrc.json — guard uses PATCHSTACK_SITE_UUID env or the bundled fallback');\n return false;\n }\n\n let uuid: unknown;\n try {\n uuid = JSON.parse(read(rc)).siteUuid;\n } catch {\n log('.patchstackrc.json unreadable — skipping site-UUID bake');\n return false;\n }\n\n if (typeof uuid !== 'string' || !UUID_RE.test(uuid)) {\n log('.patchstackrc.json siteUuid missing or malformed — guard uses PATCHSTACK_SITE_UUID env or the bundled fallback');\n return false;\n }\n\n const guardPath = join(cwd, guardRelPath);\n if (!existsSync(guardPath)) return false;\n const source = read(guardPath);\n if (!source.includes(SITE_UUID_PLACEHOLDER)) {\n log(`${guardRelPath} site UUID already baked`);\n return false;\n }\n\n writeFileSync(guardPath, source.replace(SITE_UUID_PLACEHOLDER, uuid));\n log(`baked site UUID into ${guardRelPath} — live rules from the Patchstack API`);\n return true;\n}\n\n// Guard templates ship next to the built CLI (dist/protect/templates). Resolve for the built\n// layout (this code is bundled into dist/cli.js at the dist root → protect/templates) and the\n// source layout (this file lives in src/protect/install/ → ../templates).\nconst HERE = dirname(fileURLToPath(import.meta.url));\nexport function templatesDir(): string {\n const builtLayout = join(HERE, 'protect', 'templates'); // built: dist/cli.js → dist/protect/templates\n const candidates = [\n builtLayout,\n join(HERE, '..', 'templates'), // source: src/protect/install/ → src/protect/templates\n join(HERE, 'templates'),\n ];\n return candidates.find((p) => existsSync(p)) ?? builtLayout;\n}\n","// Adapter: TanStack Start + Supabase (the shape Lovable emits).\n//\n// Wires the always-on guard with zero changes to the user's own code — patches the generated\n// Supabase client (browser→Supabase tunnel) and src/start.ts (request + function middleware),\n// scaffolds src/integrations/patchstack/{guard.ts,rules.json}, and bakes the site UUID.\n// Idempotent + upgrades in place via the managed `#region` blocks.\n\nimport { writeFileSync, existsSync, mkdirSync, copyFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { bakeSiteUuid, read, log, templatesDir } from '../util.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nconst CLIENT_TUNNEL = [\n '',\n \" // PATCHSTACK: in the browser, tunnel Supabase traffic through the app's own server guard\",\n ' // (same-origin) so payloads are inspected before they reach Supabase.',\n \" if (typeof window !== 'undefined') {\",\n \" const target = typeof input === 'string' ? input : input instanceof Request ? input.url : String(input);\",\n \" const method = init?.method ?? (input instanceof Request ? input.method : 'GET');\",\n \" headers.set('x-ps-target', target);\",\n \" const guardUrl = new URL('/_patchstack/guard', window.location.origin).toString();\",\n ' return fetch(guardUrl, { ...init, method, headers });',\n ' }',\n '',\n].join('\\n');\n\nconst GUARD_IMPORT =\n 'import { GUARD_PATH, handleGuardRequest, inspectServerFn, screenResponse, guardRequest } from \"@/integrations/patchstack/guard\";';\nconst GUARD_IMPORT_RE = /import \\{[^}]*\\} from \"@\\/integrations\\/patchstack\\/guard\";/;\n\nconst START_IMPORTS = ['import { getRequest } from \"@tanstack/react-start/server\";', GUARD_IMPORT].join('\\n');\n\n// Managed middleware blocks, delimited by #region markers so a re-run can UPGRADE them in place\n// (e.g. adding the route-WAF hook to an already-wired app) instead of skipping. Keep the markers —\n// reconcileBlock() keys off them.\nconst REQUEST_MIDDLEWARE_BLOCK = [\n '// #region patchstack-guard (managed by patchstack-connect protect — do not edit)',\n '// Browser→Supabase tunnel + response screening; optional route WAF via PATCHSTACK_ROUTE_WAF=1.',\n 'const patchstackGuard = createMiddleware().server(async ({ next }) => {',\n ' const request = getRequest();',\n ' if (request) {',\n ' const { pathname } = new URL(request.url);',\n ' if (pathname === GUARD_PATH) return handleGuardRequest(request);',\n ' if (process.env.PATCHSTACK_ROUTE_WAF === \"1\") {',\n ' const blocked = await guardRequest(request);',\n ' if (blocked) return blocked;',\n ' }',\n ' }',\n ' return screenResponse(await next());',\n '});',\n '// #endregion patchstack-guard',\n].join('\\n');\n\nconst FUNCTION_MIDDLEWARE_BLOCK = [\n '// #region patchstack-function-guard (managed by patchstack-connect protect — do not edit)',\n '// Inspect server-function args before they reach the database.',\n 'const patchstackFunctionGuard = createMiddleware({ type: \"function\" }).server(async ({ next, data }) => {',\n ' const blocked = await inspectServerFn(data);',\n ' if (blocked) throw new Error(blocked.message);',\n ' return next();',\n '});',\n '// #endregion patchstack-function-guard',\n].join('\\n');\n\n// Reconcile a managed block: replace a marked region in place (UPGRADE), migrate a legacy\n// (un-marked) block, or insert before `insertBefore` (fresh). Legacy blocks are our own single\n// arrow-fn statements whose only line-leading `});` is the terminator, so we bound them from the\n// `const` line (plus the comment header immediately above) to that `});`.\nfunction reconcileBlock(s: string, region: string, block: string, legacyConst: string, insertBefore: string): string {\n const lines = s.split('\\n');\n const startMarker = `// #region ${region} `;\n const endMarker = `// #endregion ${region}`;\n const si = lines.findIndex((l) => l.includes(startMarker));\n if (si !== -1) {\n const ei = lines.findIndex((l, i) => i > si && l.trim() === endMarker);\n if (ei !== -1) {\n lines.splice(si, ei - si + 1, ...block.split('\\n'));\n return lines.join('\\n');\n }\n }\n const ci = lines.findIndex((l) => l.includes(legacyConst));\n if (ci !== -1) {\n const close = lines.findIndex((l, i) => i >= ci && l.trim() === '});');\n if (close !== -1) {\n let start = ci;\n while (start > 0 && (lines[start - 1] ?? '').trim().startsWith('//')) start--; // eat old comment header\n lines.splice(start, close - start + 1, ...block.split('\\n'));\n return lines.join('\\n');\n }\n }\n return s.replace(insertBefore, block + '\\n\\n' + insertBefore);\n}\n\nfunction detect(cwd: string): boolean {\n const pkgPath = join(cwd, 'package.json');\n if (!existsSync(pkgPath)) return false;\n let pkg: { dependencies?: Record<string, string>; devDependencies?: Record<string, string> };\n try {\n pkg = JSON.parse(read(pkgPath));\n } catch {\n return false;\n }\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return (\n Boolean(deps['@tanstack/react-start']) &&\n existsSync(join(cwd, 'src/start.ts')) &&\n existsSync(join(cwd, 'src/integrations/supabase/client.ts'))\n );\n}\n\nconst GUARD_FILE = 'src/integrations/patchstack/guard.ts';\n\nfunction scaffold(cwd: string, opts: WireOptions): string[] {\n const templates = templatesDir();\n const dst = join(cwd, 'src/integrations/patchstack');\n mkdirSync(dst, { recursive: true });\n copyFileSync(join(templates, 'guard.ts'), join(dst, 'guard.ts')); // guard.ts is managed — always refreshed\n const changed = [GUARD_FILE];\n const rulesDst = join(dst, 'rules.json');\n // Default: the high-precision starter, written only if absent (don't clobber the user's rules on\n // re-run). --demo: (re)seed the broad multi-class sample bundle for a self-contained demonstration.\n if (opts.demo) {\n copyFileSync(join(templates, 'demo-rules.json'), rulesDst);\n changed.push('src/integrations/patchstack/rules.json');\n log('scaffolded guard.ts + rules.json (demo sample rule set)');\n } else if (!existsSync(rulesDst)) {\n copyFileSync(join(templates, 'rules.json'), rulesDst);\n changed.push('src/integrations/patchstack/rules.json');\n log('scaffolded guard.ts + rules.json (starter rules)');\n } else {\n log('scaffolded guard.ts (kept existing rules.json)');\n }\n return changed;\n}\n\nfunction patchClient(cwd: string): boolean {\n const p = join(cwd, 'src/integrations/supabase/client.ts');\n const s = read(p);\n if (s.includes('x-ps-target')) {\n log('client.ts already wired');\n return false;\n }\n const anchor = \"headers.set('apikey', supabaseKey);\";\n if (!s.includes(anchor)) {\n log('client.ts anchor not found — skipping (template changed?)');\n return false;\n }\n writeFileSync(p, s.replace(anchor, anchor + '\\n' + CLIENT_TUNNEL));\n log('patched client.ts (tunnel Supabase through the guard)');\n return true;\n}\n\nfunction patchStart(cwd: string): boolean {\n const p = join(cwd, 'src/start.ts');\n let s = read(p);\n const importAnchor = 'import { createStart, createMiddleware } from \"@tanstack/react-start\";';\n const exportAnchor = 'export const startInstance';\n const rmAnchor = 'requestMiddleware: [';\n if (!s.includes(importAnchor) || !s.includes(exportAnchor)) {\n log('start.ts anchors not found — skipping (template changed?)');\n return false;\n }\n\n // Each step reconciles idempotently: a re-run (including after a connect upgrade) refreshes the\n // managed blocks in place — never duplicates, never leaves a stale version behind.\n const original = s;\n\n // Imports — refresh the managed guard import line wholesale (upgrade), else insert both imports.\n if (GUARD_IMPORT_RE.test(s)) {\n s = s.replace(GUARD_IMPORT_RE, GUARD_IMPORT);\n } else {\n s = s.replace(importAnchor, importAnchor + '\\n' + START_IMPORTS);\n }\n\n // Middleware blocks — upgrade a marked region / migrate a legacy block / insert fresh.\n s = reconcileBlock(s, 'patchstack-guard', REQUEST_MIDDLEWARE_BLOCK, 'const patchstackGuard =', exportAnchor);\n s = reconcileBlock(s, 'patchstack-function-guard', FUNCTION_MIDDLEWARE_BLOCK, 'const patchstackFunctionGuard =', exportAnchor);\n\n // Register the browser-tunnel guard in requestMiddleware.\n if (s.includes(rmAnchor) && !s.includes('requestMiddleware: [patchstackGuard')) {\n s = s.replace(rmAnchor, rmAnchor + 'patchstackGuard, ');\n }\n\n // Register the server-function guard in functionMiddleware (create the key if the app has none).\n if (!s.includes('functionMiddleware: [patchstackFunctionGuard')) {\n const fmAnchor = 'functionMiddleware: [';\n if (s.includes(fmAnchor)) {\n s = s.replace(fmAnchor, fmAnchor + 'patchstackFunctionGuard, ');\n } else if (s.includes(rmAnchor)) {\n s = s.replace(rmAnchor, 'functionMiddleware: [patchstackFunctionGuard],\\n ' + rmAnchor);\n }\n }\n\n if (s === original) {\n log('start.ts already wired');\n return false;\n }\n writeFileSync(p, s);\n log('patched start.ts (guard registered as request + function middleware)');\n return true;\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n const changed = scaffold(cwd, opts);\n // In demo mode, keep the local sample rules active — don't bake a site UUID (which would make\n // the guard fetch live Pulse rules instead of the bundled demo set).\n if (!opts.demo && bakeSiteUuid(cwd, GUARD_FILE)) changed.push(GUARD_FILE);\n if (patchClient(cwd)) changed.push('src/integrations/supabase/client.ts');\n if (patchStart(cwd)) changed.push('src/start.ts');\n log(\n opts.demo\n ? 'done — guard wired with the demo sample rules (blocks by default). Set PATCHSTACK_MODE=dry-run for log-only.'\n : 'done — guard wired and always-on (blocks by default). Set PATCHSTACK_MODE=dry-run for log-only.',\n );\n return { ok: true, changed: [...new Set(changed)] };\n}\n\nfunction verify(cwd: string): VerifyResult {\n const guardPath = join(cwd, GUARD_FILE);\n const clientPath = join(cwd, 'src/integrations/supabase/client.ts');\n const startPath = join(cwd, 'src/start.ts');\n const guard = existsSync(guardPath) ? read(guardPath) : '';\n const client = existsSync(clientPath) ? read(clientPath) : '';\n const start = existsSync(startPath) ? read(startPath) : '';\n\n const checks = [\n { label: 'guard.ts scaffolded', ok: guard.length > 0, hint: 'run `patchstack-connect protect`' },\n { label: 'Supabase client tunnels through the guard', ok: client.includes('x-ps-target'), hint: 'run `patchstack-connect protect` to re-patch src/integrations/supabase/client.ts' },\n { label: 'request middleware defined + registered', ok: start.includes('const patchstackGuard =') && start.includes('requestMiddleware: [patchstackGuard'), hint: 'run `patchstack-connect protect` to re-patch src/start.ts' },\n { label: 'server-function middleware defined + registered', ok: start.includes('const patchstackFunctionGuard =') && start.includes('functionMiddleware: [patchstackFunctionGuard'), hint: 'run `patchstack-connect protect` to re-patch src/start.ts' },\n ];\n return { wired: checks.every((c) => c.ok), checks };\n}\n\nexport const tanstackSupabaseAdapter: Adapter = {\n name: 'tanstack-supabase',\n label: 'TanStack Start + Supabase',\n detect,\n wire,\n verify,\n};\n","// Adapter: Next.js. Wires the guard as edge middleware (request-phase WAF + egress SSRF).\n// If the app has no middleware yet, scaffolds `middleware.ts` (+ patchstack.rules.json). If a\n// middleware file already exists, we do NOT clobber it — we scaffold the rules and print a plan\n// (add the guard to your middleware), so an existing middleware is never silently overwritten.\n\nimport { writeFileSync, existsSync, mkdirSync, copyFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { bakeSiteUuid, read, log, templatesDir } from '../util.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nfunction hasNextDep(cwd: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }.next);\n } catch {\n return false;\n }\n}\n\n// Next reads middleware from `middleware.ts` at the project root, or `src/middleware.ts` when the\n// app uses a `src/` dir. Return the existing one if present, else the conventional target.\nfunction middlewareInfo(cwd: string): { relDir: string; relFile: string; exists: boolean } {\n const candidates = ['middleware.ts', 'middleware.js', 'src/middleware.ts', 'src/middleware.js'];\n for (const rel of candidates) {\n if (existsSync(join(cwd, rel))) return { relDir: rel.includes('/') ? 'src' : '.', relFile: rel, exists: true };\n }\n const useSrc = existsSync(join(cwd, 'src'));\n return { relDir: useSrc ? 'src' : '.', relFile: useSrc ? 'src/middleware.ts' : 'middleware.ts', exists: false };\n}\n\nfunction detect(cwd: string): boolean {\n return hasNextDep(cwd);\n}\n\nfunction rulesFile(relDir: string): string {\n return relDir === '.' ? 'patchstack.rules.json' : `${relDir}/patchstack.rules.json`;\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n const templates = templatesDir();\n const mw = middlewareInfo(cwd);\n const dir = join(cwd, mw.relDir === '.' ? '' : mw.relDir);\n mkdirSync(dir, { recursive: true });\n\n // Co-locate the rules next to the middleware (the template imports ./patchstack.rules.json).\n const rulesDst = join(dir, 'patchstack.rules.json');\n const changed: string[] = [];\n if (opts.demo || !existsSync(rulesDst)) {\n copyFileSync(join(templates, opts.demo ? 'demo-rules.json' : 'rules.json'), rulesDst);\n changed.push(rulesFile(mw.relDir));\n }\n\n const mwPath = join(cwd, mw.relFile);\n const existing = mw.exists ? read(mwPath) : '';\n if (mw.exists && existing.includes('patchstack-next')) {\n // Already ours — do NOT re-copy the template over it: middleware.ts is user-editable, so\n // overwriting would discard any edits made after scaffolding.\n log(`${mw.relFile} already has the Patchstack middleware — left as-is`);\n return { ok: true, changed };\n }\n if (mw.exists) {\n // The app's own middleware — leave it, and tell the user how to add the guard.\n log(\n `existing ${mw.relFile} left untouched — scaffolded ${rulesFile(mw.relDir)}; add the guard to your ` +\n `middleware: import { createProtection } from \"@patchstack/connect/protect\", run fetchGuard() on the ` +\n `request, and return the block Response. Then: npx patchstack-connect protect --check`,\n );\n return { ok: true, changed };\n }\n\n // Fresh → write the managed middleware.\n copyFileSync(join(templates, 'next-middleware.ts'), mwPath);\n if (!opts.demo) bakeSiteUuid(cwd, mw.relFile);\n changed.push(mw.relFile);\n log(`scaffolded ${mw.relFile} (Patchstack middleware)`);\n return { ok: true, changed: [...new Set(changed)] };\n}\n\nfunction verify(cwd: string): VerifyResult {\n const mw = middlewareInfo(cwd);\n const present = mw.exists && read(join(cwd, mw.relFile)).includes('patchstack-next');\n const rulesPresent = existsSync(join(cwd, rulesFile(mw.relDir)));\n return {\n wired: present && rulesPresent,\n checks: [\n { label: 'Patchstack middleware present', ok: present, hint: `run \\`patchstack-connect protect\\` (writes ${mw.relFile})` },\n { label: 'rules co-located with the middleware', ok: rulesPresent, hint: 'run `patchstack-connect protect`' },\n ],\n };\n}\n\nexport const nextAdapter: Adapter = {\n name: 'nextjs',\n label: 'Next.js',\n detect,\n wire,\n verify,\n};\n","// Adapter: SvelteKit. Wires the guard as a server hook (`src/hooks.server.ts` → `handle`).\nimport { join } from 'node:path';\nimport { read } from '../util.js';\nimport { wireSeam, verifySeam, type SeamSpec } from '../seam.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nconst SPEC: SeamSpec = {\n templateName: 'sveltekit-hooks.ts',\n candidates: ['src/hooks.server.ts', 'src/hooks.server.js'],\n target: 'src/hooks.server.ts',\n marker: 'patchstack-sveltekit',\n planHint: 'add the guard to your `handle` (compose with `sequence()` from \"@sveltejs/kit/hooks\"), then: npx patchstack-connect protect --check',\n seamLabel: 'SvelteKit server hook',\n};\n\nfunction detect(cwd: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }['@sveltejs/kit']);\n } catch {\n return false;\n }\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n return wireSeam(cwd, opts, SPEC);\n}\n\nfunction verify(cwd: string): VerifyResult {\n return verifySeam(cwd, SPEC);\n}\n\nexport const sveltekitAdapter: Adapter = {\n name: 'sveltekit',\n label: 'SvelteKit',\n detect,\n wire,\n verify,\n};\n","// Shared \"seam-file is the guard\" wiring, used by adapters whose framework has a single server hook\n// that IS the guard (SvelteKit `hooks.server.ts`, Astro `src/middleware.ts`). Scaffold the seam from\n// a template + co-locate patchstack.rules.json. An EXISTING seam file is never clobbered — we scaffold\n// the rules and print a plan instead (so a hand-written hook is preserved).\n\nimport { existsSync, mkdirSync, copyFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { bakeSiteUuid, read, log, templatesDir } from './util.js';\nimport type { WireOptions, WireResult, VerifyResult } from './types.js';\n\nexport interface SeamSpec {\n templateName: string; // template copied to the seam target when none exists\n candidates: string[]; // existing seam files to look for, in order (repo-relative)\n target: string; // where to create the seam if none exists (repo-relative)\n marker: string; // #region marker id proving it's ours (e.g. 'patchstack-sveltekit')\n planHint: string; // guidance when an existing seam file can't be safely edited\n seamLabel: string; // human label for the check (e.g. 'SvelteKit hook')\n}\n\nfunction rulesRel(seamRel: string): string {\n const d = dirname(seamRel);\n return (d === '.' ? 'patchstack.rules.json' : `${d}/patchstack.rules.json`).replace(/\\\\/g, '/');\n}\n\nexport function wireSeam(cwd: string, opts: WireOptions, spec: SeamSpec): WireResult {\n const templates = templatesDir();\n const existing = spec.candidates.find((c) => existsSync(join(cwd, c)));\n const seamRel = existing ?? spec.target;\n mkdirSync(dirname(join(cwd, seamRel)), { recursive: true });\n\n // Rules co-locate next to the seam (the templates import ./patchstack.rules.json).\n const rulesDst = join(cwd, rulesRel(seamRel));\n const changed: string[] = [];\n if (opts.demo || !existsSync(rulesDst)) {\n copyFileSync(join(templates, opts.demo ? 'demo-rules.json' : 'rules.json'), rulesDst);\n changed.push(rulesRel(seamRel));\n }\n\n const current = existing ? read(join(cwd, existing)) : '';\n if (existing && current.includes(spec.marker)) {\n // Already ours — do NOT re-copy the template over it: the whole seam file is user-editable\n // (unlike the tanstack region-marked blocks), so overwriting would discard any edits.\n log(`${existing} already has the Patchstack guard — left as-is`);\n return { ok: true, changed };\n }\n if (existing) {\n log(`existing ${existing} left untouched — scaffolded ${rulesRel(seamRel)}; ${spec.planHint}`);\n return { ok: true, changed };\n }\n\n copyFileSync(join(templates, spec.templateName), join(cwd, seamRel));\n if (!opts.demo) bakeSiteUuid(cwd, seamRel);\n changed.push(seamRel);\n log(`scaffolded ${seamRel}`);\n return { ok: true, changed: [...new Set(changed)] };\n}\n\nexport function verifySeam(cwd: string, spec: SeamSpec): VerifyResult {\n const existing = spec.candidates.find((c) => existsSync(join(cwd, c)));\n const seamRel = existing ?? spec.target;\n const present = existing ? read(join(cwd, existing)).includes(spec.marker) : false;\n const rulesPresent = existsSync(join(cwd, rulesRel(seamRel)));\n return {\n wired: present && rulesPresent,\n checks: [\n { label: `${spec.seamLabel} present`, ok: present, hint: `run \\`patchstack-connect protect\\` (writes ${spec.target})` },\n { label: 'rules co-located with the guard', ok: rulesPresent, hint: 'run `patchstack-connect protect`' },\n ],\n };\n}\n","// Adapter: Astro. Wires the guard as middleware (`src/middleware.ts` → `onRequest`).\nimport { join } from 'node:path';\nimport { read } from '../util.js';\nimport { wireSeam, verifySeam, type SeamSpec } from '../seam.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nconst SPEC: SeamSpec = {\n templateName: 'astro-middleware.ts',\n candidates: ['src/middleware.ts', 'src/middleware.js', 'src/middleware/index.ts', 'src/middleware/index.js'],\n target: 'src/middleware.ts',\n marker: 'patchstack-astro',\n planHint: 'add the guard to your `onRequest` (compose with `sequence()` from \"astro:middleware\"), then: npx patchstack-connect protect --check',\n seamLabel: 'Astro middleware',\n};\n\nfunction detect(cwd: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }.astro);\n } catch {\n return false;\n }\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n return wireSeam(cwd, opts, SPEC);\n}\n\nfunction verify(cwd: string): VerifyResult {\n return verifySeam(cwd, SPEC);\n}\n\nexport const astroAdapter: Adapter = {\n name: 'astro',\n label: 'Astro',\n detect,\n wire,\n verify,\n};\n","// Adapter: Nuxt (Nitro). Wires the guard as a server middleware file (`server/middleware/`).\n// Nuxt runs each file there as independent middleware, so our file coexists with the app's own —\n// there's no single hook to compose. Scaffolds a new managed file (never overwrites a divergent one).\nimport { hasDependency } from '../util.js';\nimport { wireSeam, verifySeam, type SeamSpec } from '../seam.js';\nimport type { Adapter, WireOptions, WireResult, VerifyResult } from '../types.js';\n\nconst SPEC: SeamSpec = {\n templateName: 'nuxt-middleware.ts',\n candidates: ['server/middleware/patchstack.ts', 'server/middleware/patchstack.js'],\n target: 'server/middleware/patchstack.ts',\n marker: 'patchstack-nuxt',\n planHint: 'add a `server/middleware/` handler that runs the guard, then: npx patchstack-connect protect --check',\n seamLabel: 'Nuxt server middleware',\n};\n\nfunction detect(cwd: string): boolean {\n return hasDependency(cwd, 'nuxt');\n}\n\nfunction wire(cwd: string, opts: WireOptions): WireResult {\n return wireSeam(cwd, opts, SPEC);\n}\n\nfunction verify(cwd: string): VerifyResult {\n return verifySeam(cwd, SPEC);\n}\n\nexport const nuxtAdapter: Adapter = {\n name: 'nuxt',\n label: 'Nuxt',\n detect,\n wire,\n verify,\n};\n","// Locate the source file + variable where an app instance is created, for the register-into-app\n// adapters (Express/Fastify/NestJS). Dependency-free: walk src/ (or the repo root) for a source\n// file matching `re`, which MUST capture the app variable name in group 1.\n\nimport { readFileSync, existsSync, readdirSync, lstatSync } from 'node:fs';\nimport { join, relative, dirname } from 'node:path';\n\n// Build/output/test dirs are skipped so we never patch a COMPILED artifact (e.g. dist/main.js) —\n// which would leave the real src/ entry unprotected and vary by machine.\nconst SKIP_DIRS = new Set([\n 'node_modules', 'patchstack', 'dist', 'build', 'out', 'coverage', '.next', '.output', '.svelte-kit',\n 'test', 'tests', '__tests__', 'e2e', 'examples', 'fixtures', '__fixtures__',\n]);\nconst MAX_DEPTH = 8;\n\nexport function findAppInstance(cwd: string, re: RegExp): { relPath: string; appVar: string } | null {\n const root = existsSync(join(cwd, 'src')) ? join(cwd, 'src') : cwd;\n let hit: { relPath: string; appVar: string } | null = null;\n const walk = (dir: string, depth: number): void => {\n if (hit || depth > MAX_DEPTH) return;\n let entries: string[];\n try {\n entries = readdirSync(dir).sort(); // deterministic order across machines\n } catch {\n return;\n }\n for (const name of entries) {\n if (hit) return;\n if (SKIP_DIRS.has(name) || name.startsWith('.')) continue;\n const p = join(dir, name);\n let st;\n try {\n st = lstatSync(p); // lstat, not stat — do NOT follow symlinks (avoids symlink-cycle recursion)\n } catch {\n continue;\n }\n if (st.isSymbolicLink()) continue;\n if (st.isDirectory()) walk(p, depth + 1);\n else if (/\\.(?:ts|js|mjs|cjs)$/.test(name)) {\n let src: string;\n try {\n src = readFileSync(p, 'utf8');\n } catch {\n continue;\n }\n const m = re.exec(src);\n if (m) hit = { relPath: relative(cwd, p).replace(/\\\\/g, '/'), appVar: m[1]! };\n }\n }\n };\n walk(root, 0);\n return hit;\n}\n\n/** Relative ESM specifier from `fromRel` to `toRel` (both repo-relative, extension stripped). */\nexport function importSpecifier(fromRel: string, toRel: string, preserveExtension = false): string {\n let spec = relative(dirname(fromRel), toRel).replace(/\\\\/g, '/');\n if (!preserveExtension) spec = spec.replace(/\\.(?:ts|js)$/, '');\n if (!spec.startsWith('.')) spec = `./${spec}`;\n return spec;\n}\n","// Shared \"register-into-app\" wiring for adapters whose framework exposes a mutable app instance you\n// hook a guard onto (Express `app.use`, Fastify `app.register`, NestJS `app.use` on main.ts). Scaffold\n// the guard, then insert the registration call right after the app instance is created — dependency-free\n// anchor + #region-marker patching, idempotent.\n\nimport { writeFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { read, log } from './util.js';\nimport { scaffoldGeneric } from './generic.js';\nimport { findAppInstance, importSpecifier } from './find-app.js';\nimport type { WireOptions, WireResult, VerifyResult } from './types.js';\n\nexport interface RegisterSpec {\n appRe: RegExp; // matches the app-instance line; MUST capture the app var in group 1\n guardTemplate: string; // guard template scaffolded as src/patchstack/guard.ts\n /** Optional JavaScript templates for apps that execute their source files directly. */\n guardTemplateEsm?: string;\n guardTemplateCjs?: string;\n importName: string; // named export the entry imports from the guard\n call: (appVar: string) => string; // the registration statement, e.g. `${v}.use(patchstackMiddleware);`\n /** Prefer a registration anchor after app creation, such as Express's JSON body parser. */\n callAfter?: (appVar: string) => RegExp;\n /** Scaffold but leave the app untouched when the preferred anchor is absent. */\n requireCallAfter?: boolean;\n label: string; // human label for logs / verify checks, e.g. 'Express app'\n manualHint: string; // guidance when no app-instance site is found\n}\n\nconst REGION = '// #region patchstack (managed by patchstack-connect protect — do not edit)';\n\ninterface GuardTarget {\n template: string;\n file: string;\n importLine: (name: string, specifier: string) => string;\n preserveExtension: boolean;\n}\n\nfunction guardTarget(cwd: string, entryRel: string, spec: RegisterSpec): GuardTarget {\n if (/\\.cjs$/.test(entryRel) || (/\\.js$/.test(entryRel) && packageType(cwd) !== 'module')) {\n if (spec.guardTemplateCjs) {\n return {\n template: spec.guardTemplateCjs,\n file: 'guard.cjs',\n importLine: (name, target) => `const { ${name} } = require(\"${target}\");`,\n preserveExtension: true,\n };\n }\n } else if (/\\.(?:js|mjs)$/.test(entryRel) && spec.guardTemplateEsm) {\n return {\n template: spec.guardTemplateEsm,\n file: entryRel.endsWith('.mjs') ? 'guard.mjs' : 'guard.js',\n importLine: (name, target) => `import { ${name} } from \"${target}\";`,\n preserveExtension: true,\n };\n }\n\n return {\n template: spec.guardTemplate,\n file: 'guard.ts',\n importLine: (name, target) => `import { ${name} } from \"${target}\";`,\n preserveExtension: false,\n };\n}\n\nfunction packageType(cwd: string): string | undefined {\n try {\n return JSON.parse(read(join(cwd, 'package.json'))).type;\n } catch {\n return undefined;\n }\n}\n\nexport function wireRegister(cwd: string, opts: WireOptions, spec: RegisterSpec): WireResult {\n const entry = findAppInstance(cwd, spec.appRe);\n if (!entry) {\n const { changed } = scaffoldGeneric(cwd, opts, spec.guardTemplate);\n log(`${spec.label} not located — scaffolded guard; ${spec.manualHint}`);\n return { ok: true, changed };\n }\n\n const target = guardTarget(cwd, entry.relPath, spec);\n const { changed, dir } = scaffoldGeneric(cwd, opts, target.template, target.file);\n\n const p = join(cwd, entry.relPath);\n const s = read(p);\n if (s.includes(spec.importName)) {\n log(`${entry.relPath} already wired`);\n return { ok: true, changed };\n }\n\n const sourceLines = s.split('\\n');\n const sourceAppIdx = sourceLines.findIndex((line) => spec.appRe.test(line));\n const requiredAnchor = spec.callAfter?.(entry.appVar);\n if (\n spec.requireCallAfter &&\n requiredAnchor &&\n !sourceLines.some((line, index) => index > sourceAppIdx && requiredAnchor.test(line))\n ) {\n log(`${entry.relPath} body-parser anchor not found — scaffolded guard; ${spec.manualHint}`);\n return { ok: true, changed };\n }\n\n const importLine = target.importLine(\n spec.importName,\n importSpecifier(entry.relPath, `${dir}/${target.file}`, target.preserveExtension),\n );\n const lines = s.split('\\n');\n let lastImport = -1;\n for (let i = 0; i < lines.length; i++) {\n if (/^\\s*(?:import\\b|(?:const|let|var)\\s+.+?=\\s*require\\()/.test(lines[i] ?? '')) lastImport = i;\n }\n lines.splice(lastImport + 1, 0, importLine);\n const appIdx = lines.findIndex((l) => spec.appRe.test(l));\n if (appIdx !== -1) {\n const preferred = spec.callAfter?.(entry.appVar);\n const preferredIdx = preferred\n ? lines.findIndex((line, index) => index > appIdx && preferred.test(line))\n : -1;\n const callIdx = preferredIdx === -1 ? appIdx : preferredIdx;\n lines.splice(callIdx + 1, 0, REGION, spec.call(entry.appVar), '// #endregion patchstack');\n }\n writeFileSync(p, lines.join('\\n'));\n changed.push(entry.relPath);\n log(`patched ${entry.relPath} (${spec.call(entry.appVar).trim()})`);\n return { ok: true, changed: [...new Set(changed)] };\n}\n\nexport function verifyRegister(cwd: string, spec: RegisterSpec): VerifyResult {\n const dir = existsSync(join(cwd, 'src')) ? 'src/patchstack' : 'patchstack';\n const entry = findAppInstance(cwd, spec.appRe);\n const target = entry ? guardTarget(cwd, entry.relPath, spec) : null;\n const scaffolded = target ? existsSync(join(cwd, dir, target.file)) : false;\n const entrySource = entry ? read(join(cwd, entry.relPath)) : '';\n const entryLines = entrySource.split('\\n');\n const anchor = entry && spec.callAfter ? spec.callAfter(entry.appVar) : null;\n const anchorIndex = anchor ? entryLines.findIndex((line) => anchor.test(line)) : -1;\n const callIndex = entry ? entryLines.findIndex((line) => line.includes(spec.call(entry.appVar))) : -1;\n const ordered = anchor ? anchorIndex !== -1 && callIndex > anchorIndex : callIndex !== -1;\n const wired = entrySource.includes(spec.importName) && ordered;\n return {\n wired: scaffolded && wired,\n checks: [\n { label: `${spec.label} guard scaffolded`, ok: scaffolded, hint: 'run `patchstack-connect protect`' },\n { label: `guard registered on the ${spec.label}`, ok: wired, hint: spec.manualHint },\n ],\n };\n}\n","// Generic fallback for stacks no built-in adapter matches. Rather than silently skip, we scaffold\n// a framework-agnostic guard, print a wiring plan (with best-effort entry-point detection), and\n// provide a `--check` verifier — so the builder's own agent can finish the wiring and confirm it,\n// entirely through the CLI (no server, no hosted infra).\n\nimport { readFileSync, existsSync, mkdirSync, copyFileSync, readdirSync, lstatSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { bakeSiteUuid, read, templatesDir } from './util.js';\nimport type { WireOptions, VerifyResult } from './types.js';\n\nconst GUARD_MARKER = 'patchstack/guard';\n\nfunction genericDir(cwd: string): string {\n return existsSync(join(cwd, 'src')) ? 'src/patchstack' : 'patchstack';\n}\n\nexport function scaffoldGeneric(\n cwd: string,\n opts: WireOptions,\n guardTemplate = 'generic-guard.ts',\n guardFile = 'guard.ts',\n): { changed: string[]; dir: string } {\n const templates = templatesDir();\n const dir = genericDir(cwd);\n const dst = join(cwd, dir);\n mkdirSync(dst, { recursive: true });\n copyFileSync(join(templates, guardTemplate), join(dst, guardFile));\n const guardRel = `${dir}/${guardFile}`;\n const changed = [guardRel];\n if (!opts.demo) bakeSiteUuid(cwd, guardRel);\n const rulesDst = join(dst, 'rules.json');\n if (opts.demo || !existsSync(rulesDst)) {\n copyFileSync(join(templates, opts.demo ? 'demo-rules.json' : 'rules.json'), rulesDst);\n changed.push(`${dir}/rules.json`);\n }\n return { changed, dir };\n}\n\n// Best-effort: likely server entry files + whether Express is a dependency.\nfunction candidateEntries(cwd: string): string[] {\n const names = [\n 'src/server.ts', 'src/server.js', 'src/index.ts', 'src/index.js', 'src/app.ts', 'src/app.js',\n 'src/main.ts', 'server.ts', 'server.js', 'index.ts', 'index.js', 'app.ts', 'app.js',\n ];\n const hits = names.filter((n) => existsSync(join(cwd, n)));\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n if (typeof pkg.main === 'string' && existsSync(join(cwd, pkg.main))) hits.push(pkg.main);\n } catch {\n /* ignore */\n }\n return [...new Set(hits)];\n}\n\nfunction usesExpress(cwd: string): boolean {\n try {\n const pkg = JSON.parse(read(join(cwd, 'package.json')));\n return Boolean({ ...pkg.dependencies, ...pkg.devDependencies }.express);\n } catch {\n return false;\n }\n}\n\nexport function wiringPlan(cwd: string, dir: string): string {\n const entries = candidateEntries(cwd);\n const express = usesExpress(cwd);\n const lines = [\n `no built-in adapter matched this stack — scaffolded a generic guard at ${dir}/guard.ts + ${dir}/rules.json.`,\n 'Finish by wiring it into your server (pick the one that fits):',\n ` • Web-Fetch entry: export default { fetch: protectFetch(yourHandler) } // import from \"${dir}/guard\"`,\n ` • Node / Express: app.use(patchstackMiddleware) // add before your routes`,\n entries.length\n ? `Likely server ${entries.length === 1 ? 'entry' : 'entries'}: ${entries.join(', ')}${express ? ' (Express detected)' : ''}.`\n : 'Could not locate a server entry — wire it wherever requests enter your app.',\n 'Then confirm it is hooked up: npx patchstack-connect protect --check',\n ];\n return lines.join('\\n');\n}\n\nexport function genericVerify(cwd: string): VerifyResult {\n const dir = genericDir(cwd);\n const scaffolded = existsSync(join(cwd, dir, 'guard.ts'));\n const imported = scaffolded && guardIsImported(cwd, join(cwd, dir, 'guard.ts'));\n return {\n wired: scaffolded && imported,\n checks: [\n { label: 'generic guard scaffolded', ok: scaffolded, hint: 'run `patchstack-connect protect`' },\n {\n label: 'guard imported into a server entry',\n ok: imported,\n hint: `import { protectFetch } (or patchstackMiddleware) from \"${dir}/guard\" and wire it into your request path`,\n },\n ],\n };\n}\n\nfunction guardIsImported(cwd: string, guardPath: string): boolean {\n const root = existsSync(join(cwd, 'src')) ? join(cwd, 'src') : cwd;\n let found = false;\n const walk = (d: string, depth: number): void => {\n if (found || depth > 8) return;\n let entries: string[];\n try {\n entries = readdirSync(d);\n } catch {\n return;\n }\n for (const name of entries) {\n if (found) return;\n if (name === 'node_modules' || name === 'patchstack' || name.startsWith('.')) continue;\n const p = join(d, name);\n let st;\n try {\n st = lstatSync(p); // don't follow symlinks (avoids symlink-cycle recursion)\n } catch {\n continue;\n }\n if (st.isSymbolicLink()) continue;\n if (st.isDirectory()) walk(p, depth + 1);\n else if (/\\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(name) && p !== guardPath) {\n try {\n if (readFileSync(p, 'utf8').includes(GUARD_MARKER)) found = true;\n } catch {\n /* ignore */\n }\n }\n }\n };\n walk(root, 0);\n return found;\n}\n","// Adapter: NestJS. Wires the guard in the bootstrap file — `app.use(patchstackMiddleware)` right\n// after `NestFactory.create(...)`. Nest's INestApplication.use() accepts Express-style middleware\n// (the default platform), so this reuses the framework-agnostic guard rather than a Nest module +\n// decorators. On the Fastify platform the guard is still fail-open; response screening isn't wired.\nimport { hasDependency } from '../util.js';\nimport { findAppInstance } from '../find-app.js';\nimport { wireRegister, verifyRegister, type RegisterSpec } from '../register.js';\nimport type { Adapter } from '../types.js';\n\nconst SPEC: RegisterSpec = {\n appRe: /(?:const|let|var)\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*await\\s+NestFactory\\.create/,\n guardTemplate: 'generic-guard.ts',\n guardTemplateEsm: 'generic-guard.js',\n guardTemplateCjs: 'generic-guard.cjs',\n importName: 'patchstackMiddleware',\n call: (v) => `${v}.use(patchstackMiddleware);`,\n label: 'NestJS app',\n manualHint: 'add `app.use(patchstackMiddleware)` right after your NestFactory.create(...) call',\n};\n\nexport const nestjsAdapter: Adapter = {\n name: 'nestjs',\n label: 'NestJS',\n detect: (cwd) => hasDependency(cwd, '@nestjs/core') && findAppInstance(cwd, SPEC.appRe) !== null,\n wire: (cwd, opts) => wireRegister(cwd, opts, SPEC),\n verify: (cwd) => verifyRegister(cwd, SPEC),\n};\n","// Adapter: Fastify (Node). Scaffolds the Fastify guard plugin and registers it on the app —\n// `app.register(patchstackFastify)` right after the `fastify()` instance is created.\nimport { hasDependency } from '../util.js';\nimport { findAppInstance } from '../find-app.js';\nimport { wireRegister, verifyRegister, type RegisterSpec } from '../register.js';\nimport type { Adapter } from '../types.js';\n\nconst SPEC: RegisterSpec = {\n appRe: /(?:const|let|var)\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*(?:fastify|Fastify)\\(/,\n guardTemplate: 'fastify-plugin.ts',\n guardTemplateEsm: 'fastify-plugin.js',\n guardTemplateCjs: 'fastify-plugin.cjs',\n importName: 'patchstackFastify',\n call: (v) => `${v}.register(patchstackFastify);`,\n label: 'Fastify app',\n manualHint: 'add `app.register(patchstackFastify)` right after you create your fastify() app',\n};\n\nexport const fastifyAdapter: Adapter = {\n name: 'fastify',\n label: 'Fastify (Node)',\n detect: (cwd) => hasDependency(cwd, 'fastify') && findAppInstance(cwd, SPEC.appRe) !== null,\n wire: (cwd, opts) => wireRegister(cwd, opts, SPEC),\n verify: (cwd) => verifyRegister(cwd, SPEC),\n};\n","// Adapter: Express (Node). Scaffolds a guard that matches the entry file's module format, then\n// registers the WAF middleware after the app's body parser and before its routes — the guard reads\n// the express-parsed req.body, so it must run once the body is populated.\nimport { hasDependency } from '../util.js';\nimport { findAppInstance } from '../find-app.js';\nimport { wireRegister, verifyRegister, type RegisterSpec } from '../register.js';\nimport type { Adapter } from '../types.js';\n\n// A body parser that populates req.body, in any of the shapes AI builders emit: express.json() /\n// express.urlencoded(), body-parser's bodyParser.json() / .urlencoded(), an aliased parser\n// (any `x.json(` / `x.urlencoded(`), or a destructured `json(` / `urlencoded(`.\nconst bodyParserRe = (appVar: string) =>\n new RegExp(`^\\\\s*${appVar}\\\\.use\\\\(\\\\s*(?:[A-Za-z_$][\\\\w$]*\\\\.)?(?:json|urlencoded)\\\\(`, 'm');\n\nconst SPEC: RegisterSpec = {\n appRe: /(?:const|let|var)\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*express\\(\\)/,\n guardTemplate: 'express-guard.ts',\n guardTemplateEsm: 'express-guard.js',\n guardTemplateCjs: 'express-guard.cjs',\n importName: 'patchstackMiddleware',\n call: (v) => `${v}.use(patchstackMiddleware);`,\n callAfter: bodyParserRe,\n requireCallAfter: true,\n label: 'Express app',\n manualHint: 'add `app.use(patchstackMiddleware)` after your body parser (express.json/urlencoded or body-parser) and before the routes',\n};\n\nexport const expressAdapter: Adapter = {\n name: 'express',\n label: 'Express (Node)',\n detect: (cwd) => hasDependency(cwd, 'express') && findAppInstance(cwd, SPEC.appRe) !== null,\n wire: (cwd, opts) => wireRegister(cwd, opts, SPEC),\n verify: (cwd) => verifyRegister(cwd, SPEC),\n};\n","// `patchstack-connect protect` — scaffold the always-on runtime guard into an app.\n//\n// Stack-specific wiring lives in one adapter per builder/framework shape (see ./adapters/). This\n// orchestrator picks the first adapter that matches the app and delegates. If none matches it\n// ESCALATES (never silently skips) — the guard engine itself is stack-agnostic, so an unmatched\n// app is a gap in auto-wiring coverage to be closed by a new adapter or an agent-assisted install,\n// not a reason to leave the app unprotected quietly.\n\nimport { log } from './util.js';\nimport { tanstackSupabaseAdapter } from './adapters/tanstack-supabase.js';\nimport { nextAdapter } from './adapters/next.js';\nimport { sveltekitAdapter } from './adapters/sveltekit.js';\nimport { astroAdapter } from './adapters/astro.js';\nimport { nuxtAdapter } from './adapters/nuxt.js';\nimport { nestjsAdapter } from './adapters/nestjs.js';\nimport { fastifyAdapter } from './adapters/fastify.js';\nimport { expressAdapter } from './adapters/express.js';\nimport { scaffoldGeneric, wiringPlan, genericVerify } from './generic.js';\nimport type { Adapter, WireOptions, ProtectResult, VerifyReport } from './types.js';\n\n// Registry — order = match priority (most specific first): framework meta-frameworks before the\n// bare server libraries (a SvelteKit/Astro app may also carry express/fastify as a transitive dep).\nconst ADAPTERS: Adapter[] = [\n tanstackSupabaseAdapter,\n nextAdapter,\n sveltekitAdapter,\n astroAdapter,\n nuxtAdapter,\n nestjsAdapter,\n fastifyAdapter,\n expressAdapter,\n];\n\n/** Scaffold + wire the runtime guard into the app at `cwd`. Best-effort — never throws. */\nexport function runProtect(cwd: string, opts: WireOptions = {}): ProtectResult {\n let adapter;\n try {\n adapter = ADAPTERS.find((a) => a.detect(cwd));\n if (adapter) {\n const result = adapter.wire(cwd, opts);\n return { status: 'wired', adapter: adapter.name, changed: result.changed };\n }\n } catch (err) {\n // A wire/detect failure (read-only FS, EACCES, a bad source file) must not crash the CLI —\n // fall through to the generic scaffold + plan so the user still gets something actionable.\n log(`adapter ${adapter?.name ?? ''} failed (${(err as Error)?.message ?? err}); falling back to a generic guard`);\n }\n\n // No adapter matched (or it failed) — DON'T silently skip. Scaffold the framework-agnostic guard\n // and print a wiring plan the builder's agent (or user) can finish, then verify with `--check`.\n try {\n const { changed, dir } = scaffoldGeneric(cwd, opts);\n const plan = wiringPlan(cwd, dir);\n log(plan);\n return { status: 'scaffolded', adapter: 'generic', changed, plan };\n } catch (err) {\n log(`could not scaffold the guard (${(err as Error)?.message ?? err})`);\n return { status: 'scaffolded', adapter: 'generic', changed: [], plan: '' };\n }\n}\n\n/** Verify the guard is correctly wired (backs `protect --check`). Fail-open — never throws. */\nexport function runVerify(cwd: string): VerifyReport {\n try {\n const adapter = ADAPTERS.find((a) => a.detect(cwd));\n if (adapter) return { stack: adapter.label, ...adapter.verify(cwd) };\n return { stack: 'generic', ...genericVerify(cwd) };\n } catch (err) {\n return { stack: 'unknown', wired: false, checks: [{ label: 'verification failed', ok: false, hint: String((err as Error)?.message ?? err) }] };\n }\n}\n\nexport type { Adapter, WireOptions, WireResult, VerifyResult, VerifyReport, ProtectResult } from './types.js';\n","// Managed disclosure-widget tag — the connector installs the widget for you.\n//\n// After a successful scan the connector ensures the site's root HTML shell\n// carries the widget's one-liner CDN tag (the canonical install form from the\n// widget docs: a single <script> with `data-site-uuid`, auto-initialising on\n// DOMContentLoaded). The tag carries an ownership attribute so re-runs update\n// it in place instead of stacking copies, and so `uninstall` flows can find it.\n// A manual/legacy install (any other reference to the widget script) is always\n// left untouched — we never convert or duplicate someone's hand-rolled tag.\n\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nexport const WIDGET_SCRIPT_URL = 'https://cdn.patchstack.com/patchstack-widget.js';\n\n/** Attribute that tags the connector-managed widget tag so re-runs update it. */\nexport const WIDGET_MARKER_ATTR = 'data-patchstack-connect-widget';\n\n/** Substring that marks any widget install (managed or manual) in HTML. */\nconst WIDGET_NEEDLE = 'patchstack-widget';\n\n/**\n * Root HTML shells the connector is willing to edit, in priority order:\n * Vite/plain SPA, CRA-style, SvelteKit. Framework layouts that are code rather\n * than HTML (Next/Nuxt/Astro layouts) are never edited automatically — `guide`\n * prints the snippet and the right file for those.\n */\nexport const SOURCE_SHELL_CANDIDATES = ['index.html', 'public/index.html', 'src/app.html'];\n\nexport function buildWidgetTag(siteUuid: string): string {\n return `<script src=\"${WIDGET_SCRIPT_URL}\" data-site-uuid=\"${siteUuid}\" defer ${WIDGET_MARKER_ATTR}=\"true\"></script>`;\n}\n\nexport type WidgetEnsureAction =\n /** No widget present — the managed tag was inserted before </body>. */\n | 'added'\n /** A managed tag existed with a different UUID — replaced in place. */\n | 'updated'\n /** The managed tag is already present and current. */\n | 'unchanged'\n /** A manual (non-managed) widget install exists — left untouched. */\n | 'manual'\n /** The document has no </body> to anchor on — nothing was changed. */\n | 'no-body';\n\nexport interface WidgetEnsureResult {\n html: string;\n action: WidgetEnsureAction;\n}\n\nconst MANAGED_TAG_RE = new RegExp(\n `<script[^>]*${WIDGET_MARKER_ATTR}[^>]*>\\\\s*</script>`,\n 'i',\n);\n\n/**\n * Ensure a single HTML document carries the managed widget tag. Idempotent:\n * updates the managed tag in place, adopts (leaves alone) manual installs, and\n * only ever inserts immediately before </body>.\n */\nexport function ensureWidgetInHtml(html: string, siteUuid: string): WidgetEnsureResult {\n const tag = buildWidgetTag(siteUuid);\n\n const managed = html.match(MANAGED_TAG_RE);\n if (managed !== null) {\n if (managed[0].includes(`data-site-uuid=\"${siteUuid}\"`)) {\n return { html, action: 'unchanged' };\n }\n return { html: html.replace(MANAGED_TAG_RE, tag), action: 'updated' };\n }\n\n if (html.includes(WIDGET_NEEDLE)) {\n return { html, action: 'manual' };\n }\n\n const bodyClose = html.match(/([ \\t]*)<\\/body>/i);\n if (bodyClose === null || bodyClose.index === undefined) {\n return { html, action: 'no-body' };\n }\n const indent = bodyClose[1] ?? '';\n const insertion = `${indent} ${tag}\\n${indent}</body>`;\n return {\n html: html.slice(0, bodyClose.index) + insertion + html.slice(bodyClose.index + bodyClose[0].length),\n action: 'added',\n };\n}\n\n/** First editable root HTML shell in the project, or null when there is none. */\nexport function findSourceShell(cwd: string): string | null {\n for (const candidate of SOURCE_SHELL_CANDIDATES) {\n if (existsSync(path.join(cwd, candidate))) {\n return candidate;\n }\n }\n return null;\n}\n\nexport interface SourceWidgetResult {\n /** Project-relative path of the shell that was inspected, or null. */\n shell: string | null;\n action: WidgetEnsureAction | 'no-shell';\n}\n\n/**\n * Ensure the managed widget tag in the project's root HTML shell. Edits at most\n * that one file; returns what happened so the caller can report it.\n */\nexport function ensureSourceWidget(cwd: string, siteUuid: string): SourceWidgetResult {\n const shell = findSourceShell(cwd);\n if (shell === null) {\n return { shell: null, action: 'no-shell' };\n }\n const file = path.join(cwd, shell);\n const before = readFileSync(file, 'utf8');\n const { html, action } = ensureWidgetInHtml(before, siteUuid);\n if (html !== before) {\n writeFileSync(file, html);\n }\n return { shell, action };\n}\n","import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport { persistApiKey } from './config.js';\nimport type { Config } from './types.js';\n\n/**\n * Device authorization flow (RFC 8628) for recovering a lost credential.\n *\n * Split into `startLogin` and `waitForApproval` because the two callers need\n * opposite things. A person at a terminal wants one command that prints a code\n * and blocks. An assistant runs a command, waits for it to exit, and only then\n * reads the output — so a command that blocks for ten minutes shows it nothing\n * until the code has already expired, and looks like a hang.\n *\n * `startLogin` returns immediately with the link. `waitForApproval` polls. The\n * CLI runs both for a terminal and only the first for everything else.\n */\n\nexport interface LoginDeps {\n fetchImpl?: typeof fetch;\n /** Injected so tests do not wait. */\n sleep?: (ms: number) => Promise<void>;\n now?: () => number;\n}\n\nexport interface PendingLogin {\n /** Redeems the credential once approved. Never printed — it is a secret. */\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n expiresAt: number;\n intervalMs: number;\n}\n\nexport interface StartResult {\n status: 'started' | 'unclaimed' | 'not-found' | 'failed';\n pending?: PendingLogin;\n message?: string;\n}\n\nexport interface LoginResult {\n status: 'approved' | 'expired' | 'unclaimed' | 'not-found' | 'failed';\n message?: string;\n userCode?: string;\n verificationUri?: string;\n}\n\nfunction baseFrom(manifestEndpoint: string): string {\n const url = new URL(manifestEndpoint);\n const p = url.pathname.replace(/\\/$/, '');\n url.pathname = p.endsWith('/manifest') ? p.slice(0, -'/manifest'.length) : '/monitor/pulse';\n url.search = '';\n url.hash = '';\n return url.toString().replace(/\\/$/, '');\n}\n\n/**\n * Where a pending request waits between the two commands.\n *\n * The temp directory rather than the project: the device code is a secret with\n * a ten-minute life, and nothing that short-lived belongs in a repo where it\n * could be committed. Keyed by site so two projects do not collide.\n */\nfunction pendingPath(siteUuid: string): string {\n const key = createHash('sha256').update(siteUuid).digest('hex').slice(0, 16);\n return path.join(tmpdir(), `patchstack-login-${key}.json`);\n}\n\nexport function savePendingLogin(siteUuid: string, pending: PendingLogin): void {\n writeFileSync(pendingPath(siteUuid), JSON.stringify(pending), { encoding: 'utf8', mode: 0o600 });\n}\n\nexport function readPendingLogin(siteUuid: string): PendingLogin | null {\n try {\n return JSON.parse(readFileSync(pendingPath(siteUuid), 'utf8')) as PendingLogin;\n } catch {\n return null; // absent, unreadable, or corrupt — all mean \"nothing pending\"\n }\n}\n\nexport function clearPendingLogin(siteUuid: string): void {\n try {\n rmSync(pendingPath(siteUuid));\n } catch {\n /* already gone */\n }\n}\n\n/** Ask for a code. Returns as soon as the link is available. */\nexport async function startLogin(config: Config, deps: LoginDeps = {}): Promise<StartResult> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const now = deps.now ?? (() => Date.now());\n\n if (config.siteUuid === null) {\n return { status: 'failed', message: 'No site UUID configured — run `patchstack-connect scan` first.' };\n }\n\n const base = baseFrom(config.endpoint);\n\n const started = await fetchImpl(`${base}/device/code`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n body: JSON.stringify({ site_uuid: config.siteUuid }),\n });\n\n if (started.status === 409) {\n return {\n status: 'unclaimed',\n message:\n 'This site has not been claimed yet, so there is no owner to approve the request. Claim it in the dashboard, or delete .patchstackrc.json to provision a new site.',\n };\n }\n if (started.status === 404) {\n return { status: 'not-found', message: 'Patchstack does not recognise this site UUID.' };\n }\n if (!started.ok) {\n return { status: 'failed', message: `Could not start the login (HTTP ${started.status}).` };\n }\n\n const body = (await started.json()) as {\n device_code: string;\n user_code: string;\n expires_in: number;\n interval: number;\n };\n\n const pending: PendingLogin = {\n deviceCode: body.device_code,\n userCode: body.user_code,\n // Points at the API, which redirects to the dashboard SPA — the CLI only\n // knows the API origin, and the approval page lives on the app.\n verificationUri: `${base}/device?code=${encodeURIComponent(body.user_code)}`,\n expiresAt: now() + body.expires_in * 1000,\n intervalMs: Math.max(1, body.interval) * 1000,\n };\n\n savePendingLogin(config.siteUuid, pending);\n\n return { status: 'started', pending };\n}\n\n/**\n * Redeem a pending request if the owner has already approved it, without\n * waiting. Lets a second `login` finish a flow the first one started, so an\n * assistant that comes back after the user approves does the right thing\n * whether or not it remembers the `--wait` flag.\n */\nexport async function redeemIfApproved(\n config: Config,\n pending: PendingLogin,\n deps: LoginDeps = {},\n): Promise<'approved' | 'pending' | 'expired'> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n\n const polled = await fetchImpl(`${baseFrom(config.endpoint)}/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n body: JSON.stringify({ device_code: pending.deviceCode }),\n });\n\n if (polled.status === 428) return 'pending';\n\n if (!polled.ok) {\n if (config.siteUuid !== null) clearPendingLogin(config.siteUuid);\n return 'expired';\n }\n\n const { api_key: apiKey } = (await polled.json()) as { api_key?: string };\n if (typeof apiKey !== 'string' || apiKey.length === 0) return 'expired';\n\n await persistApiKey(process.cwd(), apiKey);\n if (config.siteUuid !== null) clearPendingLogin(config.siteUuid);\n\n return 'approved';\n}\n\n/** Poll until the owner approves, the code expires, or `until` passes. */\nexport async function waitForApproval(\n config: Config,\n pending: PendingLogin,\n deps: LoginDeps & { until?: number } = {},\n): Promise<LoginResult> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const sleep = deps.sleep ?? ((ms: number) => new Promise((r) => setTimeout(r, ms)));\n const now = deps.now ?? (() => Date.now());\n\n const deadline = Math.min(pending.expiresAt, deps.until ?? pending.expiresAt);\n const expired = { status: 'expired' as const, message: 'The login request expired. Run the command again.' };\n\n while (now() < deadline) {\n await sleep(pending.intervalMs);\n\n const polled = await fetchImpl(`${baseFrom(config.endpoint)}/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n body: JSON.stringify({ device_code: pending.deviceCode }),\n });\n\n if (polled.status === 428) continue; // still waiting on the human\n if (!polled.ok) {\n if (config.siteUuid !== null) clearPendingLogin(config.siteUuid);\n return expired;\n }\n\n const { api_key: apiKey } = (await polled.json()) as { api_key?: string };\n if (typeof apiKey !== 'string' || apiKey.length === 0) {\n return { status: 'failed', message: 'Patchstack approved the request but returned no credential.' };\n }\n\n // Approving rotates the site's OAuth secret, which Pulse ingest and\n // block-log reporting both authenticate with.\n await persistApiKey(process.cwd(), apiKey);\n if (config.siteUuid !== null) clearPendingLogin(config.siteUuid);\n\n return { status: 'approved', userCode: pending.userCode, verificationUri: pending.verificationUri };\n }\n\n return expired;\n}\n\n/**\n * Start a flow and block until it resolves. For a terminal, where someone is\n * watching the output as it streams.\n */\nexport async function login(\n config: Config,\n onPrompt: (userCode: string, verificationUri: string) => void,\n deps: LoginDeps = {},\n): Promise<LoginResult> {\n const started = await startLogin(config, deps);\n\n if (started.status !== 'started' || started.pending === undefined) {\n return { status: started.status === 'started' ? 'failed' : started.status, message: started.message };\n }\n\n onPrompt(started.pending.userCode, started.pending.verificationUri);\n\n return waitForApproval(config, started.pending, deps);\n}\n\n/** Exported for tests that need a scratch temp dir. */\nexport function makeTempDir(prefix = 'patchstack-'): string {\n return mkdtempSync(path.join(tmpdir(), prefix));\n}\n","import { createRequire } from 'node:module';\nimport { pathToFileURL } from 'node:url';\nimport { join } from 'node:path';\nimport type { TsModule } from './types.js';\n\n// Load a TypeScript compiler for parsing the target app's source. We do NOT bundle `typescript` into\n// connect (it's a heavy dep and the runtime guard never needs it) — instead we resolve the TARGET\n// app's own installed `typescript` (every TS app has it, at the exact version its code expects), then\n// fall back to a `typescript` resolvable from connect's own context (dev/global). Returns null if\n// neither is available, so the caller can degrade with a clear message rather than crash.\nexport async function loadTypeScript(cwd: string): Promise<TsModule | null> {\n // 1. The target app's node_modules (the normal case).\n try {\n const req = createRequire(pathToFileURL(join(cwd, 'package.json')));\n const resolved = req.resolve('typescript');\n const mod = await import(pathToFileURL(resolved).href);\n return (mod.default ?? mod) as TsModule;\n } catch {\n /* fall through */\n }\n // 2. A `typescript` resolvable from here (connect dev / a global install).\n try {\n const mod = await import('typescript');\n return (mod.default ?? mod) as TsModule;\n } catch {\n return null;\n }\n}\n","import { readFileSync, realpathSync } from 'node:fs';\nimport { createHash } from 'node:crypto';\nimport { relative } from 'node:path';\nimport type { SiteInputMap, Endpoint, TsModule } from './types.js';\nimport { guessScriptKind } from './ast.js';\nimport { buildModuleBindings } from './bindings.js';\nimport { collectSources, detectDeploymentShapes, detectFramework, hasEntrySignal, type WalkStats } from './sources.js';\nimport { classifyServerSurface, surfaceNote } from './surface.js';\nimport { functionNameFromPath, routeFromFilePath } from './routes.js';\nimport { collectLocalSinks } from './sinks.js';\nimport { createModuleGraph } from './module-graph.js';\nimport { isProvenFlow } from './coordinates.js';\nimport { extractFromFile } from './entries.js';\nimport { collectFileImports, countUnresolvableImports, createImportInventory, readPathAliases, scanFileImports } from './imports.js';\nimport { collectInvocations, createInvocationInventory } from './invocations.js';\n\n// Framework-AGNOSTIC input-flow extractor. It doesn't gate on a specific stack — it walks any JS/TS\n// source and applies recognizer tables for (1) entry points, (2) inputs, (3) sinks, so it generalizes\n// across builders (TanStack Start, Next, SvelteKit, Express/Fastify/Hono, …) and providers, and\n// degrades gracefully (recording what it couldn't see in `coverage.notes`). Add a stack by adding a\n// recognizer, not a new adapter.\n//\n// False-positive control: sink and validator recognizers are gated on the file's module bindings —\n// a call whose receiver is a plain local object/class/function is NOT a dependency sink, and\n// `.object({…})` is only read as an input schema when its receiver traces to a known validator\n// package. Receivers that can't be traced (handler params, cross-file imports) stay heuristic,\n// favoring recall over precision.\n\nexport interface ExtractOptions {\n /** Follow symlinks that leave the project directory (off by default — keeps analysis in-project). */\n followSymlinks?: boolean;\n}\n\nexport async function extractInputMap(cwd: string, ts: TsModule, options: ExtractOptions = {}): Promise<SiteInputMap> {\n const notes: string[] = [];\n const endpoints: Endpoint[] = [];\n const failed: string[] = [];\n let boundary = cwd;\n try { boundary = realpathSync(cwd); } catch { /* use cwd as-is */ }\n\n const graph = createModuleGraph(ts, { cwd, boundary, followOutside: options.followSymlinks }); // shared cache\n const stats: WalkStats = { discovered: 0, unwalked: 0 };\n const files = collectSources(cwd, boundary, { followOutside: options.followSymlinks }, [], new Set(), stats);\n const imports = createImportInventory(readPathAliases(cwd));\n const invocations = createInvocationInventory();\n let parsed = 0;\n let preFiltered = 0;\n let importScanFailures = 0;\n let unresolvableImports = 0;\n let sourceBytes = 0;\n const calls = { total: 0, dependency: 0, local: 0, ambiguous: 0 };\n const startedAt = Date.now();\n // Local modules an entry file imports directly — parsed after the walk for their invocations (below).\n const entryFiles = new Set<string>();\n const hopTargets = new Set<string>();\n\n for (const file of files) {\n try {\n const text = readFileSync(file, 'utf8');\n const relFile = relative(cwd, file);\n sourceBytes += text.length;\n // Imports are collected from EVERY file, entry point or not: the data layer of an AI-built app\n // usually lives in a file with no handler in it, so a pre-filtered file is exactly where the\n // interesting dependency is imported.\n if (!hasEntrySignal(text)) {\n preFiltered++;\n const scanned = scanFileImports(text, ts);\n if (scanned === null) importScanFailures++; // this file's imports are unknown, not empty\n else imports.add(relFile, scanned, false);\n unresolvableImports += countUnresolvableImports(text, ts);\n continue;\n }\n parsed++;\n entryFiles.add(file);\n // Coordinates are only valid for the exact file content they were derived from.\n const fingerprint = createHash('sha256').update(text).digest('hex').slice(0, 16);\n const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true, guessScriptKind(ts, file));\n const bindings = buildModuleBindings(sf, ts);\n for (const specifier of bindings.imports) {\n if (!specifier.startsWith('.')) continue; // node_modules is not this app's surface\n const target = graph.resolveLocal(file, specifier);\n if (target !== undefined) hopTargets.add(target);\n }\n imports.add(relFile, collectFileImports(sf, ts), true);\n // Counted on this path too. A parsed file is not a covered file: `collectFileImports` requires a\n // string-literal specifier, so a computed require in an entry file is just as unattributable as\n // one in a pre-filtered file — and this is the path where it is easiest to assume otherwise.\n unresolvableImports += countUnresolvableImports(text, ts);\n const ctx = { file, owner: relFile, graph };\n // The ctx reaches helper summaries too, so a same-file helper using an imported client resolves.\n // The invocation inventory rides the parse we already did for sinks — no second pass, which is what\n // makes it cheap enough to ship before deciding whether to parse more files.\n const called = collectInvocations(sf, ts, bindings, ctx);\n invocations.add(called.invocations);\n calls.total += called.counts.total;\n calls.dependency += called.counts.dependency;\n calls.local += called.counts.local;\n calls.ambiguous += called.counts.ambiguous;\n const localSinks = collectLocalSinks(sf, ts, bindings, ctx);\n for (const ep of extractFromFile(sf, ts, localSinks, bindings, ctx)) {\n // A FILE-BASED route handler carries its URL path in its location, not in the code, so derive\n // it here — without this a rule can only be param-pinned, never route-scoped (`when.path`).\n if (ep.route === undefined && ep.entryKind === 'edge-function') {\n const fn = functionNameFromPath(relFile);\n if (fn) ep.route = '/' + fn; // how the platform invokes it (…/functions/v1/<name>)\n }\n if (ep.route === undefined && (ep.entryKind === 'route-handler' || ep.entryKind === 'server-action')) {\n const derived = routeFromFilePath(relFile);\n if (derived.route) {\n ep.route = derived.route;\n if (derived.dynamic) ep.routeDynamic = true;\n }\n }\n endpoints.push({ ...ep, file: relFile, fingerprint });\n }\n } catch (e) {\n // The fail-open below is right for production but hides bugs during development: a crash in the\n // extractor looks identical to an unparseable file. PS_MAP_DEBUG surfaces it.\n if (typeof process !== 'undefined' && process.env?.PS_MAP_DEBUG) console.error('[patchstack] map error', file, e);\n // Fail-open: one unreadable/unparseable file must never kill the whole map.\n failed.push(relative(cwd, file));\n }\n }\n\n // --- one hop: the local modules an entry file imports ----------------------\n // An entry file's dependency calls are usually not written IN the entry file. `src/server.js` imports\n // `loadConfig` from `./config`, and the `JSON5.parse(...)` call lives in config.js — a file with no entry\n // signal, so the walk above only scanned its imports. Reading the call from the file it is written in is\n // the difference between reporting the API an advisory names and reporting nothing about it.\n //\n // ONE hop, from entry files only, invocations only: no sinks, no endpoints, no recursion into what the\n // hop file itself imports. The bound is structural — reachable from an entry by a relative import —\n // rather than a file budget, so coverage is predictable from the app's shape instead of from its size.\n let hopParsed = 0;\n let hopFailures = 0;\n for (const target of hopTargets) {\n if (entryFiles.has(target)) continue; // already collected above, along with its endpoints\n try {\n const text = readFileSync(target, 'utf8');\n const sf = ts.createSourceFile(target, text, ts.ScriptTarget.Latest, true, guessScriptKind(ts, target));\n const bindings = buildModuleBindings(sf, ts);\n // `owner` is the hop file, so a site points at the line that makes the call rather than at the\n // entry file that reaches it. A coordinate naming the wrong file cannot be checked by hand.\n const called = collectInvocations(sf, ts, bindings, { file: target, owner: relative(cwd, target), graph });\n invocations.add(called.invocations);\n calls.total += called.counts.total;\n calls.dependency += called.counts.dependency;\n calls.local += called.counts.local;\n calls.ambiguous += called.counts.ambiguous;\n hopParsed++;\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.PS_MAP_DEBUG) console.error('[patchstack] map hop error', target, e);\n // Fail-open, and counted: these files were already read once for their imports, so they must NOT\n // join `failed` (that would double-count the skip and flip the import-completeness flag over a\n // gap that belongs to a different question).\n hopFailures++;\n }\n }\n\n notes.push('Static analysis is best-effort — this is the DETECTED surface, not a proof of completeness.');\n notes.push('`inputs` and `sinks` are INVENTORIES (both present in the handler). Only `flows` asserts that an input reaches a sink: require confidence \"exact-local\" or \"transformed-local\" before pinning a rule, and identify the input by `inputId` — a field NAME can occur in more than one request namespace.');\n notes.push('Sinks are followed into same-file helpers and ONE hop into an imported relative module (a dependency\\u2019s internals are not followed); deeper or dynamic indirection is not traced. Sinks inside declared-but-uncalled local functions are excluded.');\n notes.push('A sink `package` is resolved from the file’s imports (`attribution: \"import\"`) or inferred from another import in the same file (`\"inferred\"`); an inferred package is a hint for a reviewer, not evidence about the receiver, and never licenses a rule.');\n if (!options.followSymlinks) notes.push('Symlinks leaving the project directory were not followed (use --follow-symlinks to include them).');\n if (failed.length > 0) {\n const sample = failed.slice(0, 5).join(', ');\n notes.push(`${failed.length} file(s) could not be analyzed and were skipped (fail-open): ${sample}${failed.length > 5 ? ', …' : ''}.`);\n }\n const unresolved = endpoints.filter((e) => e.inputsResolved === false).length;\n if (unresolved > 0) {\n notes.push(`${unresolved} endpoint(s) declare an input validator that could not be statically parsed — their inputs are UNKNOWN, not empty (marked inputsResolved: false).`);\n }\n const heuristicOnly = endpoints.filter((e) => e.sinks.length > 0 && e.inputs.length > 0 && !e.flows.some((f) => isProvenFlow(f.confidence))).length;\n if (heuristicOnly > 0) {\n notes.push(`${heuristicOnly} endpoint(s) have inputs and sinks but no proven data link — their flows say \"may reach\", not \"does reach\" (see each flow's confidence).`);\n }\n if (endpoints.length === 0) notes.push('No recognized server-side entry points found under the analyzed roots.');\n\n const importList = imports.list();\n const unmodelled = importList.filter((d) => d.recognizedSinkKinds.length === 0).length;\n // A file we could not read is a file whose imports we do not know — the same unknown as a failed scan.\n // An unwalked subtree is the quietest gap of the three: it produces no file, so no counter moves and\n // the tree just looks smaller. It has to be part of this or the flag certifies an inventory with a\n // hole in it.\n // Two kinds of gap, one flag. ENVIRONMENTAL gaps (unread, unscanned, unwalked) might close on a\n // re-run with different permissions; an INHERENT gap — a specifier computed at runtime — never will,\n // because no static pass can resolve it. Both make the inventory incomplete, so both clear the flag;\n // they are reported apart so a reviewer can tell \"try again\" from \"this app cannot be answered\n // statically\" instead of re-running against a permanent property of the source.\n const importCoverageGaps = {\n unreadableFiles: failed.length,\n unscannableFiles: importScanFailures,\n unwalkedPaths: stats.unwalked,\n unresolvableImports,\n };\n const environmentalGaps = failed.length + importScanFailures + stats.unwalked;\n const importsComplete = environmentalGaps === 0 && unresolvableImports === 0;\n notes.push('`imports` lists every package the app imports, from ALL source files — not only files holding an entry point. Absence of a SINK for a package is never evidence; absence of the PACKAGE is evidence only when coverage.importsComplete is true.');\n notes.push(`${unmodelled} of ${importList.length} imported package(s) have no recognized sink family (recognizedSinkKinds: []). The extractor models a small set of API families, so for those packages it cannot tell whether input reaches them: a vulnerability in one must stay \"needs review\" and can never be closed as unreachable using this map.`);\n if (environmentalGaps > 0) {\n notes.push(`The import inventory is INCOMPLETE: ${failed.length} file(s) could not be read, ${importScanFailures} could not be scanned, and ${stats.unwalked} path(s) could not be walked at all (unreadable directory, broken link, or a symlink leaving the project). A package may therefore be imported without appearing in \\`imports\\`. Do not read a package's absence as \"not imported\" while coverage.importsComplete is false.`);\n }\n if (unresolvableImports > 0) {\n notes.push(`The import inventory is INCOMPLETE for a reason no re-run can fix: ${unresolvableImports} import(s) do not name a resolvable module — either the specifier is computed at runtime (\\`require(REGISTRY[kind])\\`) or the loader itself was aliased (\\`const r = require\\`), so which package is loaded is not knowable from the source. Those imports appear NOWHERE in \\`imports\\` — not as an unresolved entry, simply absent — so a package's absence is not evidence of it being unused. This is a property of the application's code, not a scan failure. Reported conservatively: an aliased loader counts even if every call through it uses a literal.`);\n }\n\n const invocationList = invocations.list();\n if (invocationList.length > 0 || parsed > 0) {\n notes.push(`\\`apiInvocations\\` records ${invocationList.length} dependency API call(s) resolved from ${parsed} entry file(s) plus ${hopParsed} local module(s) they import directly. POSITIVE EVIDENCE ONLY: a package missing from it may still have its API called — see coverage.apiInventoryLimitations.`);\n }\n if (hopFailures > 0) {\n notes.push(`${hopFailures} local module(s) imported by an entry file could not be parsed, so any dependency call written in them is missing from \\`apiInvocations\\`.`);\n }\n\n // Node-only and best-effort: the map runs in a build, but the runtime this file belongs to must stay\n // edge-safe, so nothing here may assume `process`.\n //\n // Two numbers, because the obvious one is not the one a performance decision needs. `memoryUsage().rss`\n // is the resident size AT THIS MOMENT — after extraction, with the walk's garbage possibly already\n // collected — so calling it a peak would overstate what it measures. `resourceUsage().maxRSS` is a real\n // high-water mark, but for the whole process (it includes loading TypeScript), so it is an upper bound on\n // the cost of running `map` rather than extraction's own peak. Both are reported and both are labelled\n // for what they are.\n let rssBytes;\n let peakRssBytes;\n try {\n if (typeof process !== 'undefined') {\n if (typeof process.memoryUsage === 'function') rssBytes = process.memoryUsage().rss;\n if (typeof process.resourceUsage === 'function') {\n const maxRssKb = process.resourceUsage().maxRSS; // kilobytes, per Node's docs\n if (typeof maxRssKb === 'number' && maxRssKb > 0) peakRssBytes = maxRssKb * 1024;\n }\n }\n } catch { /* not available */ }\n\n const deploymentShapes = detectDeploymentShapes(cwd, { boundary, followOutside: options.followSymlinks });\n // Emitted UNCONDITIONALLY, and the empty case is the one that needs it most: an empty list is the only\n // state a consumer could read as \"this app has no server\", and a JSON reader sees none of the type\n // documentation that says otherwise. Attaching the caveat only when something was found put the warning\n // everywhere except the case it warns about.\n notes.push(deploymentShapes.length === 0\n ? '`deploymentShapes` is EMPTY: no deployment artifact was recognized. That is not evidence the app has no server-side runtime — a serverless handler this analysis cannot parse produces no endpoint and looks identical to an app that has none, and entry-point recognition has no completeness flag (coverage.importsComplete covers the import inventory only). A definitive answer needs deployment or build attestation, which source analysis cannot supply.'\n : `\\`deploymentShapes\\` records ${deploymentShapes.length} deployment artifact(s) the project declares (${deploymentShapes.map((s) => s.shape).join(', ')}). POSITIVE EVIDENCE ONLY, and findings differ in strength: only \\`runtime-entry\\` (a worker entry, or a provider function directory with source) shows something that serves. \\`deployment-config\\` means the project deploys to a platform — a static site on Netlify has a \\`netlify.toml\\` — and \\`layout\\` (a root \\`api/\\` or \\`functions/\\` folder) is an ordinary application folder. Neither may on its own be read as a server runtime.`);\n\n // Classified from what was positively found: the endpoints above, the deployment artifacts, and the\n // manifest. Emitted with its evidence and its own caveat, in every state — the `unknown` and static\n // states are the ones a consumer could over-read, so neither travels without the sentence that bounds it.\n const serverSurface = classifyServerSurface(cwd, endpoints.length, deploymentShapes, ts);\n notes.push(surfaceNote(serverSurface));\n\n return {\n version: 3,\n framework: detectFramework(cwd),\n deploymentShapes,\n serverSurface,\n endpoints,\n imports: importList,\n apiInvocations: invocationList,\n coverage: {\n adapter: 'agnostic-v1',\n filesDiscovered: stats.discovered,\n filesParsed: parsed,\n filesPreFiltered: preFiltered,\n filesHopParsed: hopParsed,\n filesSkipped: failed.length,\n pathsUnwalked: stats.unwalked,\n importsComplete,\n importCoverageGaps,\n apiInvocations: invocationList.length,\n callsTotal: calls.total,\n callsDependency: calls.dependency,\n callsLocal: calls.local,\n callsAmbiguous: calls.ambiguous,\n sourceBytes,\n analysisMs: Date.now() - startedAt,\n ...(rssBytes !== undefined ? { rssBytes } : {}),\n ...(peakRssBytes !== undefined ? { peakRssBytes } : {}),\n // The list IS the partiality statement. There is deliberately no `apiInventoryComplete`: parsing\n // every file would raise recall without removing any of these, so no parsing budget could make an\n // absent invocation mean \"not called\".\n apiInventoryLimitations: [\n 'only files carrying an entry-point signal, and the local modules they import directly, are parsed — a call two hops away is unseen',\n 'a computed callee or property (`client[name]()`) cannot be resolved to an API',\n 'a dynamic import()/require() with a non-literal specifier is not traced',\n 'reflection, generated code, and syntax that fails to parse are invisible',\n 'a receiver reached through more than one local hop, or through dependency injection, is not followed',\n ],\n roots: ['.'],\n notes,\n },\n };\n}\n\n\nfunction escapeRe(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// Re-exported so `./extract.js` stays the directory's entry point for consumers and tests.\nexport { runtimeCoordinate } from './coordinates.js';\nexport { functionNameFromPath, routeFromFilePath } from './routes.js';\nexport type { WalkStats } from './sources.js';\nexport type { ModuleGraph } from './sinks.js';\n","import type { TsModule } from './types.js';\n\n// Dependency-free AST helpers shared by every recognizer in this directory.\n\n// Leftmost identifier of a member/call chain (`supabase.from(x).insert` → \"supabase\", `fs.writeFile` → \"fs\").\n// `new` is part of a chain like any other link: `new Pool().query` roots at `Pool`, and so does\n// `function getDb() { return new Pool() }` — the shape a generated app uses for a database client. Omitting\n// it dropped the receiver entirely, which reads as \"not a dependency\" rather than \"not followed\".\nexport function rootIdentifier(node: any, ts: TsModule): string | undefined {\n let cur = node;\n while (cur) {\n if (ts.isIdentifier(cur)) return cur.text;\n if (ts.isPropertyAccessExpression(cur) || ts.isElementAccessExpression(cur) || ts.isCallExpression(cur) || ts.isNewExpression(cur) || ts.isNonNullExpression(cur) || ts.isParenthesizedExpression(cur) || ts.isAwaitExpression(cur)) {\n cur = cur.expression;\n } else return undefined;\n }\n return undefined;\n}\n\n// Source span of a node: the auditable coordinate, AND the sink's identity for flow analysis (a line is\n// not an identity — two sinks can share one, and an enclosing statement can hold unrelated expressions).\nexport function spanOf(node: any): { line?: number; start?: number; end?: number } {\n const out: { line?: number; start?: number; end?: number } = { line: lineOf(node) };\n try { out.start = node.getStart(); out.end = node.getEnd(); } catch { /* synthetic node */ }\n return out;\n}\n\n// 1-based line of a node in its source file — the auditable coordinate rules and humans point at.\nexport function lineOf(node: any): number | undefined {\n const sf = typeof node?.getSourceFile === 'function' ? node.getSourceFile() : undefined;\n if (!sf) return undefined;\n try { return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1; } catch { return undefined; }\n}\n\nexport function guessScriptKind(ts: TsModule, file: string) {\n if (file.endsWith('.tsx')) return ts.ScriptKind.TSX;\n if (file.endsWith('.jsx')) return ts.ScriptKind.JSX;\n if (file.endsWith('.js')) return ts.ScriptKind.JS;\n return ts.ScriptKind.TS;\n}\n\nexport function isFnLike(n: any, ts: TsModule): n is import('typescript').ArrowFunction | import('typescript').FunctionExpression {\n return ts.isArrowFunction(n) || ts.isFunctionExpression(n);\n}\nexport function hasExport(node: any, ts: TsModule): boolean {\n return Boolean(node.modifiers?.some((m: any) => m.kind === ts.SyntaxKind.ExportKeyword));\n}\n\n// --- call-chain + method ----------------------------------------------------\nexport function unwindChain(node: any, ts: TsModule): { baseName?: string; baseCall?: any; calls: Record<string, any> } {\n const calls: Record<string, any> = {};\n let cur = node;\n while (cur && ts.isCallExpression(cur)) {\n const callee = cur.expression;\n if (ts.isPropertyAccessExpression(callee)) { calls[callee.name.text] = cur; cur = callee.expression; }\n else if (ts.isIdentifier(callee)) return { baseName: callee.text, baseCall: cur, calls };\n else break;\n }\n return { calls };\n}\n\nexport function methodFromObjectArg(baseCall: any, ts: TsModule): string | undefined {\n const arg = baseCall?.arguments?.[0];\n if (!arg || !ts.isObjectLiteralExpression(arg)) return undefined;\n for (const p of arg.properties) {\n if (ts.isPropertyAssignment(p) && (p.name as any)?.text === 'method' && ts.isStringLiteralLike(p.initializer)) {\n return p.initializer.text.toUpperCase();\n }\n }\n return undefined;\n}\n\nexport function bindingKey(el: any, ts: TsModule): string | undefined {\n if (!ts.isBindingElement(el)) return undefined;\n const prop = el.propertyName ?? el.name;\n return prop && ts.isIdentifier(prop) ? prop.text : undefined;\n}\n\n// A named function *declaration*, or a function bound to a variable/property — i.e. code that only runs\n// if something calls it. An inline callback (an arrow passed as an argument), an IIFE, or a function\n// used directly in an expression is NOT this: those execute where they appear.\nexport function isUninvokedFunctionDeclaration(n: any, ts: TsModule): boolean {\n if (ts.isFunctionDeclaration(n)) return true;\n if (isFnLike(n, ts)) {\n const p = n.parent;\n if (p && (ts.isVariableDeclaration(p) || ts.isPropertyAssignment(p) || ts.isPropertyDeclaration(p))) return true;\n }\n return false;\n}\n\n/**\n * Is `name` bound by an enclosing function parameter (or catch clause) at this call site? If so the call\n * is NOT the global of that name — a callback parameter called `fetch` is the single most likely way to\n * fake an SSRF candidate. Scoped to parameters/catch bindings: cheap, and it covers the shadowing shapes\n * that occur in practice. Erring here loses a candidate rather than inventing one.\n */\nexport function isShadowedByEnclosingBinding(node: any, name: string, ts: TsModule): boolean {\n for (let cur = node?.parent; cur; cur = cur.parent) {\n if (ts.isCatchClause(cur) && cur.variableDeclaration && ts.isIdentifier(cur.variableDeclaration.name)\n && cur.variableDeclaration.name.text === name) return true;\n const params = (cur as any).parameters;\n if (!params) continue;\n for (const p of params) {\n if (!p?.name) continue;\n if (ts.isIdentifier(p.name) && p.name.text === name) return true;\n if (ts.isObjectBindingPattern(p.name) || ts.isArrayBindingPattern(p.name)) {\n for (const el of p.name.elements) {\n if (ts.isBindingElement(el) && ts.isIdentifier(el.name) && el.name.text === name) return true;\n }\n }\n }\n }\n return false;\n}\n\n/** Method name a call invokes (`db.from(t).insert(x)` → \"insert\", `exec(x)` → \"exec\"). */\nexport function calleeName(call: any, ts: TsModule): string | undefined {\n const c = call?.expression;\n if (!c) return undefined;\n if (ts.isPropertyAccessExpression(c)) return c.name.text;\n if (ts.isIdentifier(c)) return c.text; // also covers `new Function(...)`\n return undefined;\n}\n\n/** Is this identifier occurrence a VALUE read (rather than a property key, a member name, a binding)? */\nexport function isValueRead(id: any, ts: TsModule): boolean {\n const p = id.parent;\n if (!p) return true;\n if (ts.isPropertyAssignment(p) && p.name === id) return false; // { title: … } — a key\n if (ts.isPropertyAccessExpression(p) && p.name === id) return false; // x.title — the member name\n if (ts.isBindingElement(p) && p.propertyName === id) return false; // { title: t } — the source key\n if ((ts.isVariableDeclaration(p) || ts.isParameter(p) || ts.isBindingElement(p)) && p.name === id) return false;\n if (ts.isPropertySignature(p) || ts.isMethodSignature(p)) return false;\n return true; // includes ShorthandPropertyAssignment `{ title }`, which IS a read\n}\n\n// From a `.insert` property access, the CallExpression that invokes it — the sink's operation call.\nexport function opCallOf(propAccess: any, ts: TsModule): any {\n const p = propAccess?.parent;\n return p && ts.isCallExpression(p) && p.expression === propAccess ? p : propAccess;\n}\n\nexport function localCalls(node: any, ts: TsModule): string[] {\n const names: string[] = [];\n const visit = (n: any) => {\n if (ts.isCallExpression(n) && ts.isIdentifier(n.expression)) names.push(n.expression.text);\n ts.forEachChild(n, visit);\n };\n visit(node);\n return names;\n}\n","import { builtinModules } from 'node:module';\nimport type { TsModule } from './types.js';\nimport { isFnLike, isUninvokedFunctionDeclaration, rootIdentifier } from './ast.js';\n\nconst BUILTINS = new Set(builtinModules);\n\n// Per-file module bindings: resolve a local identifier to the npm package (or node: builtin) it came\n// from — directly (an import), or via `const x = <importedFn|new ImportedClass>(...)` /\n// `const x = require('mod')`; derived names resolve transitively (`const conn = pool.promise()`).\n// `imports` is every module specifier the file imports (for the fallback). `locals` is every name\n// declared in-file that does NOT trace to a module — calls on those receivers are not dependency\n// sinks. (Names assigned outside their declaration, e.g. `let fs; fs = require('fs')`, are treated\n// as local — an accepted miss.)\nexport interface Bindings {\n resolve(name: string): string | undefined;\n /** For `import { saveOrder as write }`, maps the local name back to the EXPORTED name. */\n exportNameOf(name: string): string | undefined;\n /**\n * HOW a name reached its package: `direct` from an import/require declaration, `factory` through a\n * traced call chain (`const db = createClient(...)`, `const conn = pool.promise()`).\n *\n * Recorded rather than inferred because the API inventory reports it as evidence: \"this call is on a\n * value we followed through a factory\" is a weaker claim than \"this call is on an imported binding\",\n * and a consumer deciding what to act on needs to tell them apart.\n */\n originOf(name: string): 'direct' | 'factory' | undefined;\n /**\n * Whether the name is a NAMED MEMBER of its package (`import { Pool } from 'pg'`,\n * `const { parse } = require('json5')`) rather than the module object itself (`import * as fs`,\n * `import JSON5 from 'json5'`, `const JSON5 = require('json5')`).\n *\n * Both are `direct`, but only the member's name belongs to the package. A module object's local name is\n * the app's invention — the same require is written `JSON5`, `J5`, or `json5` in three codebases — so it\n * is not a name any advisory can be matched against.\n */\n isPackageMember(name: string): boolean;\n imports: Set<string>;\n locals: Set<string>;\n}\nexport function buildModuleBindings(sf: any, ts: TsModule): Bindings {\n const nameToModule = new Map<string, string>(); // local name → module specifier\n const declared = new Set<string>(); // every name declared in this file\n const exportNames = new Map<string, string>(); // local alias → exported name\n const members = new Set<string>(); // names bound to a NAMED export, not to the module object\n const imports = new Set<string>();\n const origins = new Map<string, 'direct' | 'factory'>();\n\n const record = (local: string, mod: string, origin: 'direct' | 'factory' = 'direct') => {\n nameToModule.set(local, mod);\n imports.add(mod);\n if (!origins.has(local)) origins.set(local, origin);\n };\n const declareBound = (nameNode: any) => {\n if (ts.isIdentifier(nameNode)) declared.add(nameNode.text);\n else if (ts.isObjectBindingPattern(nameNode) || ts.isArrayBindingPattern(nameNode)) {\n for (const el of nameNode.elements) if (ts.isBindingElement(el) && ts.isIdentifier(el.name)) declared.add(el.name.text);\n }\n };\n\n const visit = (node: any) => {\n // import … from 'mod'\n if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteralLike(node.moduleSpecifier)) {\n const mod = node.moduleSpecifier.text;\n imports.add(mod);\n const clause = node.importClause;\n if (clause?.name) record(clause.name.text, mod); // default\n const nb = clause?.namedBindings;\n if (nb) {\n if (ts.isNamespaceImport(nb)) record(nb.name.text, mod);\n else if (ts.isNamedImports(nb)) for (const el of nb.elements) {\n record(el.name.text, mod);\n members.add(el.name.text);\n // `import { saveOrder as write }` — looking up `write` in the target module would miss.\n if (el.propertyName && ts.isIdentifier(el.propertyName)) exportNames.set(el.name.text, el.propertyName.text);\n }\n }\n }\n if (ts.isFunctionDeclaration(node) && node.name) declared.add(node.name.text);\n if (ts.isClassDeclaration(node) && node.name) declared.add(node.name.text);\n // const x = require('mod') / const { a } = require('mod')\n if (ts.isVariableStatement(node)) {\n for (const decl of node.declarationList.declarations) {\n declareBound(decl.name);\n const init = decl.initializer;\n const reqMod = requireSpecifier(init, ts);\n if (reqMod) {\n if (ts.isIdentifier(decl.name)) record(decl.name.text, reqMod);\n else if (ts.isObjectBindingPattern(decl.name)) for (const el of decl.name.elements) if (ts.isIdentifier(el.name)) {\n record(el.name.text, reqMod);\n members.add(el.name.text);\n // `const { merge: deepMerge } = require(\"lodash\")` — the CommonJS twin of an import alias.\n // Without this the local alias looks like the package's own export name, and reporting it as\n // one invents an API the package does not have.\n if (el.propertyName && ts.isIdentifier(el.propertyName)) exportNames.set(el.name.text, el.propertyName.text);\n }\n }\n // const x = tracedFactory(...) / const x = new TracedClass(...) → x carries that package.\n // Looking up nameToModule (not just direct imports) makes this transitive: pool → conn → ….\n // Recorded as pending too, so a factory resolved LATER (a local wrapper, below) still binds x.\n if (init && ts.isIdentifier(decl.name)) {\n const callee = ts.isCallExpression(init) ? init.expression : ts.isNewExpression(init) ? init.expression : undefined;\n const root = callee ? rootIdentifier(callee, ts) : undefined;\n if (root) {\n pending.push([decl.name.text, root]);\n if (nameToModule.has(root)) record(decl.name.text, nameToModule.get(root)!, 'factory');\n }\n }\n }\n }\n // A LOCAL factory that hands back a dependency object: `function getClient() { return createClient(…) }`.\n // Without this, `const supabase = getClient()` looks like a plain local and every sink on it is\n // dropped as \"not a dependency\" — silently losing the real client (the common AI-generated shape).\n if ((ts.isFunctionDeclaration(node) || isFnLike(node, ts)) && node.body) {\n const fnName = ts.isFunctionDeclaration(node) && node.name\n ? node.name.text\n : ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)\n ? node.parent.name.text\n : undefined;\n if (fnName) {\n const root = returnedRootIdentifier(node.body, ts);\n if (root) pending.push([fnName, root]);\n }\n }\n ts.forEachChild(node, visit);\n };\n const pending: Array<[string, string]> = []; // [localName, rootIdentifierItCameFrom]\n visit(sf);\n // Fixpoint: resolve chains like createClient → getClient → supabase (bounded; order-independent).\n for (let i = 0; i < 4; i++) {\n let changed = false;\n for (const [name, root] of pending) {\n if (!nameToModule.has(name) && nameToModule.has(root)) { record(name, nameToModule.get(root)!, 'factory'); changed = true; }\n }\n if (!changed) break;\n }\n const locals = new Set([...declared].filter((n) => !nameToModule.has(n)));\n return {\n resolve: (name: string) => nameToModule.get(name),\n exportNameOf: (name: string) => exportNames.get(name),\n originOf: (name: string) => origins.get(name),\n isPackageMember: (name: string) => members.has(name),\n imports,\n locals,\n };\n}\n\n// Root identifier of what a function body returns (`return createClient(…)` → \"createClient\"), for\n// following a local factory to the dependency it wraps. Concise arrow bodies are the expression itself.\nfunction returnedRootIdentifier(body: any, ts: TsModule): string | undefined {\n if (!ts.isBlock(body)) return rootIdentifier(body, ts); // concise arrow body\n let found: string | undefined;\n const visit = (n: any) => {\n if (found) return;\n if (isUninvokedFunctionDeclaration(n, ts) && n !== body) return; // don't read a nested fn's return\n if (ts.isReturnStatement(n) && n.expression) { found = rootIdentifier(n.expression, ts); return; }\n ts.forEachChild(n, visit);\n };\n visit(body);\n return found;\n}\n\nfunction requireSpecifier(init: any, ts: TsModule): string | undefined {\n if (init && ts.isCallExpression(init) && ts.isIdentifier(init.expression) && init.expression.text === 'require') {\n const a = init.arguments[0];\n if (a && ts.isStringLiteralLike(a)) return a.text;\n }\n return undefined;\n}\n\n// Normalize a module specifier to its npm package root (keep scope, drop subpath). Node builtins are\n// normalized to the `node:` form even when imported bare (`import fs from 'fs'`) — there IS an npm\n// package named `fs`, and CVE correlation must never confuse the two. Relative paths → undefined.\nexport function npmPackageOf(spec: string | undefined): string | undefined {\n if (!spec) return undefined;\n if (spec.startsWith('.') || spec.startsWith('/')) return undefined;\n if (spec.startsWith('node:')) return spec;\n if (BUILTINS.has(spec)) return `node:${spec}`;\n const parts = spec.split('/');\n return spec.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0];\n}\n","import { readFileSync, readdirSync, realpathSync, statSync } from 'node:fs';\nimport { join, relative, isAbsolute } from 'node:path';\nimport { ROUTE_CALL_RE } from './routes.js';\nimport type { DeploymentEvidence, DeploymentShape } from './types.js';\n\n// Cheap textual pre-filter so we only parse files that could contain an entry point. Derived from the\n// same list as the AST recognizer (see ROUTE_REGISTER_NAMES).\nexport function hasEntrySignal(text: string): boolean {\n return (\n text.includes('createServerFn') ||\n /\\bexport\\s+(async\\s+)?(function|const)\\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b/.test(text) ||\n ROUTE_CALL_RE.test(text) ||\n text.includes(\"'use server'\") || text.includes('\"use server\"') ||\n text.includes('Deno.serve') || /\\bserve\\s*\\(/.test(text)\n );\n}\n\nexport function detectFramework(cwd: string): string {\n try {\n const pkg = JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8'));\n const d = { ...pkg.dependencies, ...pkg.devDependencies };\n if (d['@tanstack/react-start'] || d['@tanstack/start'] || d['@tanstack/solid-start']) return 'tanstack-start';\n if (d['next']) return 'next';\n if (d['@sveltejs/kit']) return 'sveltekit';\n if (d['@nestjs/core']) return 'nestjs';\n if (d['fastify']) return 'fastify';\n if (d['express']) return 'express';\n if (d['hono']) return 'hono';\n } catch { /* ignore */ }\n // A Deno/edge functions project may have no package.json at all.\n try {\n if (statSync(join(cwd, 'supabase', 'functions')).isDirectory()) return 'supabase-functions';\n } catch { /* not a supabase project */ }\n try {\n if (statSync(join(cwd, 'functions')).isDirectory()) return 'deno-functions';\n } catch { /* ignore */ }\n return 'unknown';\n}\n\nconst isSourceFile = (name: string) => /\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/.test(name) && !name.endsWith('.d.ts');\n\n// Directories that never hold app source, so walking the whole project stays cheap. (We walk the whole\n// project rather than `src` only: server entrypoints, route dirs and platform function dirs commonly\n// live at the root — `server.ts`, `app/`, `api/`, `routes/`, `functions/`, `netlify/`, `supabase/`.)\nconst SKIP_DIRS = new Set([\n 'node_modules', 'dist', 'build', 'out', 'coverage', 'public', 'static', 'assets',\n '.git', '.next', '.nuxt', '.svelte-kit', '.output', '.vercel', '.wrangler', '.turbo', '.cache',\n 'vendor', 'tmp', 'temp', '__pycache__',\n]);\n\nexport interface WalkStats {\n discovered: number;\n /**\n * Directories or links the walk could not traverse (permissions, a broken link, a vanished path) plus\n * subtrees deliberately left unvisited because a symlink escapes the project.\n *\n * These never become \"files\", so nothing downstream can notice them by counting: an unreadable\n * directory simply makes the tree look smaller. That is fine for the surface view and NOT fine for the\n * import inventory, whose whole value is that a package's absence means something — an unwalked subtree\n * can import anything. Any non-zero value here forfeits that claim.\n */\n unwalked: number;\n}\n\n/**\n * Walk the project for source files. Symlinks are followed ONLY while they stay inside the project\n * boundary (`boundary`, a realpath) — a link to an external repo would otherwise pull unrelated code\n * (and its paths) into the map. `followOutside` opts out of the boundary check. A realpath visited-set\n * makes link cycles safe.\n */\nexport function collectSources(\n dir: string,\n boundary: string,\n opts: { followOutside?: boolean },\n out: string[] = [],\n seen = new Set<string>(),\n stats: WalkStats = { discovered: 0, unwalked: 0 },\n): string[] {\n let key: string;\n try { key = realpathSync(dir); } catch { stats.unwalked++; return out; }\n if (seen.has(key)) return out; // already walked via another path — not a gap\n if (!opts.followOutside && !isInside(key, boundary)) { stats.unwalked++; return out; }\n seen.add(key);\n let entries;\n try { entries = readdirSync(dir, { withFileTypes: true }); } catch { stats.unwalked++; return out; }\n // Directory order is filesystem-dependent (APFS and ext4 disagree), and it decides the order of\n // endpoints and import sites in the document. Sorting makes the same tree produce the same bytes on\n // any machine — otherwise a rebuild in CI looks like a changed app and cuts a pointless new revision.\n entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n for (const e of entries) {\n if (SKIP_DIRS.has(e.name) || (e.name.startsWith('.') && e.name !== '.')) continue;\n const full = join(dir, e.name);\n if (e.isDirectory()) collectSources(full, boundary, opts, out, seen, stats);\n else if (e.isSymbolicLink()) {\n let st, real;\n try { st = statSync(full); real = realpathSync(full); } catch { stats.unwalked++; continue; }\n // The link escapes the project: deliberate, but still a part of the tree we did not read, so it\n // counts against the inventory's completeness exactly like a failure would — but only when it\n // could have held source. A symlinked README outside the project must not forfeit the claim.\n if (!opts.followOutside && !isInside(real, boundary)) {\n if (st.isDirectory() || isSourceFile(e.name)) stats.unwalked++;\n continue;\n }\n if (st.isDirectory()) collectSources(full, boundary, opts, out, seen, stats);\n else if (st.isFile() && isSourceFile(e.name)) { out.push(full); stats.discovered++; }\n } else if (isSourceFile(e.name)) { out.push(full); stats.discovered++; }\n }\n return out;\n}\n\nexport function isInside(candidate: string, boundary: string): boolean {\n if (candidate === boundary) return true;\n const rel = relative(boundary, candidate);\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel);\n}\n\n// --- deployment shapes ------------------------------------------------------\n// What the PROJECT says about where it runs, as opposed to what its source says it does.\n//\n// The two answers come apart in the direction that matters. A project can hold a serverless function\n// this extractor cannot parse — an unfamiliar handler signature, a runtime it does not model — and the\n// endpoint walk then reports nothing, which is indistinguishable from an app that has no server at all.\n// A consumer reading only `endpoints: []` would call that app static and tell its owner there is nothing\n// to protect.\n//\n// So these are POSITIVE artifacts: a config file or a platform directory that exists. Each finding names\n// the thing that proved it, because a classification a consumer cannot explain is one it should not act\n// on — and the absence of every shape below is still not evidence of absence, only of \"we found none\".\n//\n// Findings are not equally strong, and the difference is carried in the data rather than left for a\n// consumer to rediscover:\n//\n// runtime-entry code that SERVES — a worker entry, or a provider function directory with source\n// deployment-config the project deploys to a platform, which says nothing about anything serving\n// layout an ordinary application folder that MIGHT be functions (`api/`, `functions/`)\n//\n// The `deployment-config` line is the one worth being careful about: a static site on Netlify has a\n// `netlify.toml`, a static Vercel project has a `vercel.json`, and a Pages project deploying only assets\n// has a `wrangler.toml`. Reading any of those as a server runtime would classify a large share of purely\n// static apps as having one — so they establish \"deploys somewhere\", nothing more.\n//\n// `layout` exists because `api/client.ts` is a perfectly normal front-end folder and `api/handler.ts` is a\n// Vercel function, and from the outside they are the same directory name.\n//\n// A classifier may use `deployment-config` and `layout` to stay UNDECIDED; neither may conclude a runtime.\n//\n// `DeploymentEvidence` and `DeploymentShape` are imported from `types.ts` rather than restated: they are the\n// document's contract, and two structural copies of a vocabulary is how the two drift apart later.\ninterface ShapeCandidate {\n shape: string;\n evidence: DeploymentEvidence;\n files?: string[];\n dirs?: string[];\n /**\n * Require the per-function directory layout (`<name>/index.ts`) rather than any source underneath.\n *\n * Supabase needs this: the convention puts shared code in `supabase/functions/_shared/*.ts`, which the\n * platform does not deploy and which exists in projects with no deployed function at all. Counting it\n * would report a runtime for a project that serves nothing — and this signal is the one the product\n * messaging leans on, so a false positive here is a wrong statement to a customer.\n */\n requiresFunctionEntry?: boolean;\n}\n\nconst DEPLOYMENT_SHAPES: ShapeCandidate[] = [\n // Config first: these are declarations by the project itself, and they survive a build output being\n // absent (a fresh clone has no `.vercel`/`.wrangler` directory).\n { shape: 'vercel', evidence: 'deployment-config', files: ['vercel.json'] },\n { shape: 'netlify', evidence: 'deployment-config', files: ['netlify.toml'] },\n // Wrangler names a Workers/Pages deployment. `.jsonc` and `.json` are both current spellings.\n { shape: 'cloudflare-workers', evidence: 'deployment-config', files: ['wrangler.toml', 'wrangler.jsonc', 'wrangler.json'] },\n // Pages advanced mode: a single worker entry at the project root takes over routing entirely. Unlike a\n // wrangler config, this file IS the server — it is a runtime entry, not a deployment declaration.\n { shape: 'cloudflare-pages-advanced', evidence: 'runtime-entry', files: ['_worker.js', '_worker.ts'] },\n { shape: 'netlify-functions', evidence: 'runtime-entry', dirs: ['netlify/functions', 'netlify/edge-functions'] },\n { shape: 'supabase-functions', evidence: 'runtime-entry', dirs: ['supabase/functions'], requiresFunctionEntry: true },\n // Ambiguous by nature and reported as one shape: a root `functions/` directory is Cloudflare Pages\n // Functions, Firebase functions, or a Deno layout depending on the platform, and nothing inside the\n // repository always distinguishes them. Naming it honestly is better than guessing a provider.\n { shape: 'root-functions-directory', evidence: 'layout', dirs: ['functions'] },\n // The bare-root Vercel convention: `api/handler.ts` with no framework router. Next owns `pages/api`\n // and `app/api` instead, which the endpoint walk already recognizes, so this is reported as its own\n // shape rather than folded into `vercel`.\n { shape: 'root-api-directory', evidence: 'layout', dirs: ['api'] },\n];\n\nexport interface DeploymentScanOptions {\n /** Project boundary (a real path). Candidates resolving outside it are refused. */\n boundary?: string;\n /** Follow artifacts that resolve outside the project (off by default, like the source walk). */\n followOutside?: boolean;\n}\n\n/**\n * Deployment artifacts present in the project, each with the file or directory that evidenced it.\n *\n * Cheap by construction: a handful of `statSync` calls at known paths, no walking. Never throws — an\n * unreadable project yields an empty list, which is a \"found none\" and must not be read as \"has none\".\n *\n * Symlinks are resolved and refused when they leave the project, the same rule the source walk applies. A\n * symlinked `api/` pointing at a sibling workspace would otherwise become THIS project's deployment\n * evidence — the analysis would describe a runtime that belongs to different code.\n */\nexport function detectDeploymentShapes(cwd: string, opts: DeploymentScanOptions = {}): DeploymentShape[] {\n let boundary = opts.boundary ?? cwd;\n try { boundary = realpathSync(boundary); } catch { /* use as given */ }\n\n const inProject = (path: string): boolean => {\n if (opts.followOutside) return true;\n try {\n return isInside(realpathSync(path), boundary);\n } catch {\n return false; // unresolvable is not in-project, and not evidence\n }\n };\n\n const found: DeploymentShape[] = [];\n\n for (const candidate of DEPLOYMENT_SHAPES) {\n for (const file of candidate.files ?? []) {\n const full = join(cwd, file);\n try {\n if (statSync(full).isFile() && inProject(full)) {\n found.push({ shape: candidate.shape, source: file, evidence: candidate.evidence });\n break; // one spelling is enough; the shape is the claim, not the filename\n }\n } catch { /* not this one */ }\n }\n\n for (const dir of candidate.dirs ?? []) {\n const full = join(cwd, dir);\n\n // Containment is settled BEFORE anything reads the directory. `statSync` follows symlinks, so a\n // linked `api/` reports as a directory here — and inspecting its contents first would mean this\n // analysis had already read a tree outside the project, whatever it then did with the result. The\n // guarantee is \"we do not look\", not \"we look and discard\".\n try {\n if (!statSync(full).isDirectory() || !inProject(full)) continue;\n } catch {\n continue; // missing, or unresolvable — either way not evidence\n }\n\n // A directory with no source file in it is scaffolding, not a deployment: an empty `api/` would\n // otherwise make every project that once considered serverless look like it ships it.\n if (candidate.requiresFunctionEntry ? holdsFunctionEntry(full) : holdsSourceFile(full)) {\n found.push({ shape: candidate.shape, source: dir, evidence: candidate.evidence });\n break;\n }\n }\n }\n\n return found;\n}\n\n/**\n * Whether a directory holds at least one deployable FUNCTION, in the per-function layout: a child directory\n * whose name does not start with `_`, containing an `index.*` source file.\n *\n * Only ever called for a directory the caller has already confirmed is inside the project.\n *\n * The underscore rule is the platform's own: Supabase treats `supabase/functions/_shared/` as shared code\n * and does not deploy it, so a project can have that directory full of TypeScript and serve nothing.\n */\nfunction holdsFunctionEntry(dir: string): boolean {\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isDirectory() || entry.name.startsWith('_')) continue;\n try {\n for (const nested of readdirSync(join(dir, entry.name), { withFileTypes: true })) {\n if (nested.isFile() && /^index\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/.test(nested.name)) return true;\n }\n } catch { /* unreadable candidate */ }\n }\n } catch { /* unreadable */ }\n\n return false;\n}\n\n/**\n * Whether a directory holds at least one source file, one level down included.\n *\n * No boundary check here, and deliberately not: `readdirSync(withFileTypes)` classifies a symlink as\n * neither a file nor a directory, so a linked entry can never satisfy either branch and cannot smuggle\n * outside code into this test. Every entry that reaches a `return true` is a real file at a real path\n * under `dir`, which the caller has already confirmed is in-project.\n *\n * (A first version did check the boundary at each hop. It was unreachable — verified by removing the\n * top-level refusal, which failed the escaping-directory tests while the nested one stayed green.)\n *\n * The accepted cost is a legitimate in-project symlink inside a provider directory not counting as\n * source. That errs toward reporting no shape, which the map already states is not evidence of absence.\n */\nfunction holdsSourceFile(dir: string): boolean {\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.isFile() && isSourceFile(entry.name)) return true;\n // One level deeper covers the per-function layout (`netlify/functions/hello/index.ts`) without\n // turning this into a walk.\n if (entry.isDirectory()) {\n try {\n for (const nested of readdirSync(join(dir, entry.name), { withFileTypes: true })) {\n if (nested.isFile() && isSourceFile(nested.name)) return true;\n }\n } catch { /* unreadable subdirectory */ }\n }\n }\n } catch { /* unreadable */ }\n\n return false;\n}\n","import type { TsModule } from './types.js';\nimport { isFnLike } from './ast.js';\n\n// One list drives BOTH the AST route-registration recognizer and the textual pre-filter — they must\n// never diverge: a file the pre-filter skips is invisible to every recognizer.\nconst ROUTE_REGISTER_NAMES = ['get', 'post', 'put', 'patch', 'delete', 'options', 'all', 'head', 'use'];\nexport const ROUTE_REGISTER = new Set(ROUTE_REGISTER_NAMES);\nexport const ROUTE_CALL_RE = new RegExp(`\\\\.(${[...ROUTE_REGISTER_NAMES, 'route'].join('|')})\\\\s*\\\\(`);\n\n// Derive the URL path of a FILE-BASED route handler from its location, across the conventions AI\n// builders actually emit. Dynamic segments become `:name` and set `dynamic` so a consumer knows the\n// route is a PATTERN (the engine's `when.path` takes a glob or /regex/, not an Express param), rather\n// than mistaking `/api/:id` for a literal path.\n// Next App Router app/api/items/route.ts -> /api/items\n// app/api/items/[id]/route.ts -> /api/items/:id (dynamic)\n// app/(marketing)/api/x/route.ts -> /api/x (route group stripped)\n// Next Pages Router pages/api/items/index.ts -> /api/items\n// pages/api/[id].ts -> /api/:id (dynamic)\n// SvelteKit src/routes/api/items/+server.ts -> /api/items\n// Nuxt server/api/items.post.ts -> /api/items\n// The deployed name of a platform function, from its conventional location:\n// supabase/functions/<name>/index.ts (Supabase Edge Functions)\n// functions/<name>/index.ts | functions/<name>.ts (Base44 / generic Deno function dirs)\nexport function functionNameFromPath(relFile: string): string | undefined {\n const parts = relFile.split(/[\\\\/]/).filter(Boolean);\n const i = parts.lastIndexOf('functions');\n if (i === -1 || i === parts.length - 1) return undefined;\n const next = parts[i + 1];\n if (!next) return undefined;\n const base = next.replace(/\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/, '');\n return base === 'index' ? undefined : base;\n}\n\nexport function routeFromFilePath(relFile: string): { route?: string; dynamic?: boolean } {\n const parts = relFile.split(/[\\\\/]/).filter(Boolean);\n if (parts.length === 0) return {};\n const base = (parts[parts.length - 1] ?? '').replace(/\\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/, '');\n const dirs = parts.slice(0, -1);\n const at = (name: string) => dirs.lastIndexOf(name);\n\n let segs: string[] | null = null;\n if (base === 'route' && at('app') !== -1) {\n segs = dirs.slice(at('app') + 1); // Next App Router\n } else if (base === '+server' && at('routes') !== -1) {\n segs = dirs.slice(at('routes') + 1); // SvelteKit\n } else if (at('pages') !== -1) {\n segs = [...dirs.slice(at('pages') + 1), ...(base === 'index' ? [] : [base])]; // Next Pages Router\n } else if (at('server') !== -1) {\n // Nuxt server routes; a `.post`/`.get` suffix encodes the method, not a path segment.\n segs = [...dirs.slice(at('server') + 1), ...(base === 'index' ? [] : [base.replace(/\\.(get|post|put|patch|delete|head|options)$/i, '')])];\n }\n if (!segs) return {};\n\n // Next route groups `(marketing)` and parallel/private segments don't appear in the URL.\n segs = segs.filter((s) => !(s.startsWith('(') && s.endsWith(')')) && !s.startsWith('@') && !s.startsWith('_'));\n\n let dynamic = false;\n const mapped = segs.map((s) => {\n const m = /^\\[+(\\.{0,3})(.+?)\\]+$/.exec(s); // [id], [...slug], [[...slug]]\n if (m) {\n dynamic = true;\n return ':' + m[2];\n }\n return s;\n });\n const route = '/' + mapped.join('/');\n return { route: route.length > 1 ? route.replace(/\\/+$/, '') : '/', dynamic };\n}\n\n// Unwind `router.route('/x').get(h).post(h2)` down to the `.route('/x')` call to recover the path.\nexport function routeFromChain(expr: any, ts: TsModule): string | undefined {\n let cur = expr;\n while (cur && ts.isCallExpression(cur) && ts.isPropertyAccessExpression(cur.expression)) {\n const nm = cur.expression.name.text;\n if (nm === 'route') {\n const a = cur.arguments[0];\n return a && ts.isStringLiteralLike(a) ? a.text : undefined;\n }\n if (!ROUTE_REGISTER.has(nm)) return undefined;\n cur = cur.expression.expression;\n }\n return undefined;\n}\n\n// Read `{ method, url|path, handler }` from a Fastify-style route object (handler as arrow/function\n// property or as an object-method shorthand).\nexport function routeObject(obj: any, ts: TsModule): { url?: string; methods: string[]; handler?: any } {\n let url: string | undefined;\n let handler: any;\n const methods: string[] = [];\n for (const p of obj.properties) {\n const key = (p.name as any)?.text;\n if (ts.isPropertyAssignment(p)) {\n if ((key === 'url' || key === 'path') && ts.isStringLiteralLike(p.initializer)) url = p.initializer.text;\n if (key === 'method') {\n if (ts.isStringLiteralLike(p.initializer)) methods.push(p.initializer.text.toUpperCase());\n else if (ts.isArrayLiteralExpression(p.initializer)) {\n for (const el of p.initializer.elements) if (ts.isStringLiteralLike(el)) methods.push(el.text.toUpperCase());\n }\n }\n if (key === 'handler' && isFnLike(p.initializer, ts)) handler = p.initializer;\n } else if (ts.isMethodDeclaration(p) && key === 'handler') handler = p;\n }\n return { url, methods, handler };\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { DeploymentShape, ServerSurface, SurfaceSignal, TsModule } from './types.js';\n\n// Does this app have a server side at all?\n//\n// The question is worth answering because the answer changes what protection MEANS: an app with no server\n// runtime cannot run a request guard, so its advisories are dependency and bundle hygiene rather than\n// request-path risk. Told plainly, that is useful. Told wrongly, it is the worst output this analysis can\n// produce — \"nothing to protect here\" on an app we simply failed to read.\n//\n// So the classification is built from POSITIVE signals on both sides, and the honest answer is usually\n// neither:\n//\n// server-runtime-detected a recognized endpoint, or an artifact that SERVES (a worker entry, a provider\n// function directory with source)\n// static-build-detected a static generator identified AND nothing suggesting a server surface\n// unknown everything else — including \"we found nothing and cannot say why\"\n//\n// A deployment CONFIG is not in that first list, and that is the correction that matters most here: a static\n// site on Netlify has a `netlify.toml`, a static Vercel project has a `vercel.json`, and a Pages project\n// serving only assets has a `wrangler.toml`. Reading those as a runtime would have classified a large share\n// of purely static apps as having a server. They stay visible in the evidence and they still rule out a\n// confident static claim — a project that deploys somewhere is not one this analysis can call server-free —\n// but the answer with nothing else behind it is `unknown`.\n//\n// Three rules keep `static-build-detected` from becoming the default for an unrecognised stack:\n//\n// 1. It needs a static generator NAMED. Absence of server signals is not evidence; `endpoints: []` is\n// what an unparsed framework looks like, and entry-point recognition has no completeness flag.\n// 2. A server-framework dependency blocks it. An app with `express` installed and no endpoint we could\n// read is a parsing gap, not a static site.\n// 3. Any deployment shape blocks it — config and `layout` included. A root `api/` folder holding source\n// may be a front-end helper or a pile of platform functions, and from here they are the same folder.\n// That ambiguity belongs in `unknown`, not in a claim either way.\n//\n// Even `static-build-detected` is not deployment attestation: it says the source describes a static build,\n// not that nothing server-side is deployed. Only build or platform metadata can carry that, and this\n// analysis never sees it.\n\n/** Dependencies that build a static bundle and, on their own, no server. */\nconst STATIC_GENERATORS: Array<{ dep: string; label: string }> = [\n { dep: 'vite', label: 'vite' },\n { dep: 'react-scripts', label: 'create-react-app' },\n { dep: 'gatsby', label: 'gatsby' },\n { dep: 'parcel', label: 'parcel' },\n { dep: '@sveltejs/adapter-static', label: 'sveltekit-static-adapter' },\n];\n\n/**\n * Build tools that turn a static bundler into an SSR stack.\n *\n * Vite is the awkward one: it is the default bundler for client-only apps AND the foundation of several\n * server frameworks, so `vite` in a manifest is not by itself a static build. Anything here vetoes the\n * static reading and leaves the app `unknown`, which is the conservative direction for a state whose product\n * meaning is \"no request-path protection needed\".\n */\nconst SSR_COMPANIONS = ['vike', 'vite-plugin-ssr', '@react-router/node', '@react-router/serve', 'vite-plugin-node'];\n\n/**\n * Dependencies that mean a server, so a static claim is off the table.\n *\n * Deliberately wider than the framework detector: this list only has to answer \"might this app serve\n * requests\", and over-answering yes costs a claim we would rather not make anyway.\n */\nconst SERVER_DEPENDENCIES = [\n 'express', 'fastify', 'hono', 'koa', '@nestjs/core', '@hapi/hapi', 'h3', 'polka', 'restify',\n '@tanstack/react-start', '@tanstack/start', '@tanstack/solid-start', 'nuxt', 'remix',\n '@remix-run/node', '@remix-run/server-runtime',\n];\n\n/**\n * Frameworks that ship BOTH modes, where another dependency decides which one this project is.\n *\n * `@sveltejs/kit` is the case that made this necessary: every static SvelteKit app has it alongside\n * `@sveltejs/adapter-static`, so treating kit as an unconditional server dependency made a real static\n * SvelteKit project permanently `unknown` — and the test that \"proved\" the adapter worked installed the\n * adapter with no kit, which is not a package set anyone ships.\n */\nconst CONDITIONAL_SERVER_DEPENDENCIES: Array<{ dep: string; staticWhen: string }> = [\n { dep: '@sveltejs/kit', staticWhen: '@sveltejs/adapter-static' },\n];\n\n/** Astro and Next ship both modes, so the adapter or the output setting decides. */\nconst SSR_ADAPTERS = ['@astrojs/node', '@astrojs/vercel', '@astrojs/cloudflare', '@astrojs/netlify', '@astrojs/deno'];\n\n/** How each deployment-evidence level appears in the surface evidence list. */\nconst SHAPE_SIGNAL: Record<DeploymentShape['evidence'], SurfaceSignal['signal']> = {\n 'runtime-entry': 'runtime-entry',\n 'deployment-config': 'deployment-config',\n layout: 'ambiguous-layout',\n};\n\ninterface Manifest {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n}\n\nfunction readManifest(cwd: string): Manifest | null {\n try {\n const parsed = JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8'));\n\n return typeof parsed === 'object' && parsed !== null ? parsed as Manifest : null;\n } catch {\n return null; // no manifest, or unreadable — either way nothing is identified from it\n }\n}\n\n/**\n * Whether a Next project is configured to emit a static export rather than run a server.\n *\n * The config is PARSED, not pattern-matched. A regex over the file text accepts\n * `// output: 'export'`, the same words inside a string, and an example block nobody exports — and each of\n * those would have reclassified an ordinary server-mode Next app as static, which is the direction that\n * loses protection. Parsing is also not the same as executing: the AST is read, the config never runs.\n *\n * Only a value reachable from the module's export counts, so dead code declaring `output: 'export'` is\n * ignored too. The wrapper form (`withPlugins(config)`, `withMDX({...})`) is followed one level, since it\n * is how most real Next configs are written.\n */\nfunction nextExportsStatically(cwd: string, manifest: Manifest, ts: TsModule | undefined): string | null {\n const scripts = Object.values(manifest.scripts ?? {}).join(' ');\n // Scripts are JSON strings — no comments to be fooled by.\n if (/\\bnext\\s+export\\b/.test(scripts)) return 'next export (build script)';\n\n if (ts === undefined) return null; // no compiler available: nothing is claimed from the config\n\n for (const file of ['next.config.js', 'next.config.mjs', 'next.config.ts', 'next.config.cjs']) {\n let text: string;\n try {\n text = readFileSync(join(cwd, file), 'utf8');\n } catch {\n continue;\n }\n\n try {\n const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true);\n if (exportedConfigIsStatic(sf, ts)) return `output: 'export' (${file})`;\n } catch { /* unparseable config claims nothing */ }\n }\n\n return null;\n}\n\n/**\n * `output: 'export'` on the object this module actually exports.\n *\n * Alias following is cycle-safe by construction. `const a = b; const b = a; export default a` would\n * otherwise recurse until the stack gave out, and while the surrounding catch turns that into a\n * conservative `unknown`, a malformed config should be an ordinary answer rather than an exception used as\n * control flow — a thrown RangeError also discards any signal found before it.\n */\nfunction exportedConfigIsStatic(sf: any, ts: TsModule): boolean {\n const objects: any[] = [];\n const followed = new Set<string>();\n\n const collectFrom = (expr: any): void => {\n if (!expr) return;\n if (ts.isObjectLiteralExpression(expr)) { objects.push(expr); return; }\n // `export default withPlugins({...})` / `module.exports = withMDX(config)`\n if (ts.isCallExpression(expr)) { for (const arg of expr.arguments) collectFrom(arg); return; }\n // `const nextConfig = {...}; export default nextConfig`\n if (ts.isIdentifier(expr)) {\n const name = expr.text;\n if (followed.has(name)) return; // already resolved, or part of a cycle\n followed.add(name);\n const visit = (node: any): void => {\n if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === name) {\n collectFrom(node.initializer);\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n }\n };\n\n const findExports = (node: any): void => {\n // `export default X`\n if (ts.isExportAssignment(node)) collectFrom(node.expression);\n // `module.exports = X`\n if (ts.isBinaryExpression(node)\n && node.operatorToken.kind === ts.SyntaxKind.EqualsToken\n && ts.isPropertyAccessExpression(node.left)\n && node.left.name.text === 'exports') {\n collectFrom(node.right);\n }\n ts.forEachChild(node, findExports);\n };\n findExports(sf);\n\n for (const object of objects) {\n for (const property of object.properties) {\n if (!ts.isPropertyAssignment(property)) continue;\n const key = property.name;\n const keyName = ts.isIdentifier(key) || ts.isStringLiteralLike(key) ? key.text : undefined;\n if (keyName !== 'output') continue;\n if (ts.isStringLiteralLike(property.initializer) && property.initializer.text === 'export') return true;\n }\n }\n\n return false;\n}\n\n/**\n * Static generators this project positively identifies, each with the dependency or setting that named it.\n *\n * Astro and Next are conditional: both ship a server mode, so `astro` alone says nothing and an SSR adapter\n * rules the static reading out entirely.\n */\nfunction staticSignals(cwd: string, ts: TsModule | undefined): SurfaceSignal[] {\n const manifest = readManifest(cwd);\n if (manifest === null) return [];\n\n const deps = { ...manifest.dependencies, ...manifest.devDependencies };\n const signals: SurfaceSignal[] = [];\n\n for (const generator of STATIC_GENERATORS) {\n if (deps[generator.dep] !== undefined) {\n signals.push({ signal: 'static-generator', source: generator.label });\n }\n }\n\n if (deps['astro'] !== undefined && !SSR_ADAPTERS.some((adapter) => deps[adapter] !== undefined)) {\n signals.push({ signal: 'static-generator', source: 'astro (no SSR adapter)' });\n }\n\n if (deps['next'] !== undefined) {\n const exported = nextExportsStatically(cwd, manifest, ts);\n if (exported !== null) signals.push({ signal: 'static-generator', source: `next: ${exported}` });\n }\n\n return signals;\n}\n\n/** Server-framework dependencies present, each named — they block a static conclusion. */\nfunction serverDependencySignals(cwd: string, ts: TsModule | undefined): SurfaceSignal[] {\n const manifest = readManifest(cwd);\n if (manifest === null) return [];\n\n const deps = { ...manifest.dependencies, ...manifest.devDependencies };\n const found = SERVER_DEPENDENCIES.filter((dep) => deps[dep] !== undefined);\n\n // Both-mode frameworks: present, but not a server dependency when the project also installs the\n // dependency that makes it static.\n for (const conditional of CONDITIONAL_SERVER_DEPENDENCIES) {\n if (deps[conditional.dep] !== undefined && deps[conditional.staticWhen] === undefined) {\n found.push(conditional.dep);\n }\n }\n\n // An SSR companion turns a static bundler into a server stack, so it vetoes the static reading the same\n // way a server framework does. `vite` alone is not a static build.\n for (const companion of SSR_COMPANIONS) if (deps[companion] !== undefined) found.push(companion);\n\n // `next` counts as a server dependency UNLESS the project exports statically, which `staticSignals`\n // establishes from the same manifest.\n if (deps['next'] !== undefined && nextExportsStatically(cwd, manifest, ts) === null) found.push('next');\n if (deps['astro'] !== undefined) {\n for (const adapter of SSR_ADAPTERS) if (deps[adapter] !== undefined) found.push(adapter);\n }\n\n return found.map((dep) => ({ signal: 'server-dependency', source: dep }));\n}\n\n/**\n * Classify the app's server surface from what was positively found.\n *\n * `endpointCount` and `deploymentShapes` come from the analysis that already ran; the manifest signals are\n * read here. Nothing in this function infers from absence except the final fall-through to `unknown`,\n * which is the one honest thing absence supports.\n */\nexport function classifyServerSurface(\n cwd: string,\n endpointCount: number,\n deploymentShapes: DeploymentShape[],\n ts?: TsModule,\n): ServerSurface {\n const evidence: SurfaceSignal[] = [];\n\n if (endpointCount > 0) {\n evidence.push({ signal: 'endpoint', source: `${endpointCount} recognized entry point(s)` });\n }\n for (const shape of deploymentShapes) {\n evidence.push({\n signal: SHAPE_SIGNAL[shape.evidence],\n source: `${shape.shape} (${shape.source})`,\n });\n }\n\n const servers = serverDependencySignals(cwd, ts);\n const statics = staticSignals(cwd, ts);\n\n // Only code that SERVES settles this: a recognized endpoint, a worker entry, or a provider function\n // directory with source in it. A deployment config does not — a static site on Netlify has a\n // `netlify.toml` and no server — and a `layout` folder does not either, since `api/client.ts` is an\n // ordinary front-end helper. Both remain in the evidence, and both still block a static claim below.\n const servesRequests = deploymentShapes.some((shape) => shape.evidence === 'runtime-entry');\n if (endpointCount > 0 || servesRequests) {\n return { state: 'server-runtime-detected', evidence };\n }\n\n evidence.push(...servers, ...statics);\n\n const blocked = servers.length > 0 || deploymentShapes.length > 0;\n if (statics.length > 0 && !blocked) {\n return { state: 'static-build-detected', evidence };\n }\n\n return { state: 'unknown', evidence };\n}\n\n/** The sentence that goes with each state, so a consumer states the same limits the analysis does. */\nexport function surfaceNote(surface: ServerSurface): string {\n if (surface.state === 'server-runtime-detected') {\n // \"Applicable\", not \"applies\". Recognizing code that serves requests establishes which KIND of\n // protection is relevant to these paths; it establishes nothing about whether a guard is installed,\n // fetching rules or enforcing them — none of which a build-time map can see. The previous wording\n // (\"Request-path protection applies to this app\") read as a protection status, and since this note is\n // rendered verbatim by consumers, it put that claim on a dashboard.\n return 'serverSurface: a server runtime was recognized in the analysed source (see its evidence). Request-path shielding is APPLICABLE to these paths — this is not a statement that a guard is installed, fetching rules, or enforcing them.';\n }\n\n if (surface.state === 'static-build-detected') {\n return 'serverSurface: a static build was identified and no server runtime was recognized in the analysed source. This is NOT deployment attestation — it describes the source, not what is deployed, and a serverless function added at the platform level would not appear here. Advisories against this app are dependency and bundle concerns rather than request-path risk.';\n }\n\n return 'serverSurface is UNKNOWN: neither a server runtime nor a static build could be positively identified. This is the honest answer for an unrecognised stack, and it must not be read as \"no server side\" — an unparsed framework produces no endpoints, and entry-point recognition has no completeness flag.';\n}\n","import { createHash } from 'node:crypto';\nimport type { ArgumentRole, CandidateFamily, Sink, SinkKind, TsModule } from './types.js';\nimport {\n isFnLike,\n isShadowedByEnclosingBinding,\n isUninvokedFunctionDeclaration,\n localCalls,\n opCallOf,\n rootIdentifier,\n spanOf,\n} from './ast.js';\nimport { npmPackageOf, type Bindings } from './bindings.js';\n\nconst DB_OPS = new Set(['insert', 'update', 'delete', 'select', 'upsert', 'rpc']);\nconst PRISMA_OPS = new Set(['create', 'createMany', 'update', 'updateMany', 'delete', 'deleteMany', 'upsert', 'findFirst', 'findUnique', 'findMany', 'count', 'aggregate']);\nconst FS_CALLS = /^(readFile|writeFile|readFileSync|writeFileSync|appendFile|createReadStream|createWriteStream|unlink|rm|rmSync|mkdir|readdir|stat|open)$/;\nconst EXEC_CALLS = /^(exec|execSync|spawn|spawnSync|execFile|execFileSync|fork)$/;\nconst HTTP_CALLS = /^(fetch|got|request)$/;\nconst HTTP_MEMBER_METHODS = new Set(['get', 'post', 'put', 'patch', 'delete', 'head', 'request']);\n// When a sink's base can't be traced precisely, infer its package from the file's imports of a known\n// provider for that sink kind (a file almost always uses one db/http client).\nconst DB_PACKAGES = ['@supabase/supabase-js', '@prisma/client', 'drizzle-orm', 'knex', 'kysely', 'pg', 'mysql2', 'mysql', 'sequelize', 'typeorm', 'mongoose', 'better-sqlite3'];\n// Drivers that are not in the inference list above but do establish a database API when a receiver\n// resolves to them. Extend deliberately: this list is what separates \"a package we can trace\" from\n// \"a package that proves a DB API\", and admitting the wrong one produces a false SQL-injection rule.\nconst MORE_DB_PACKAGES = ['postgres', 'mssql', 'tedious', 'oracledb', 'sqlite3', 'mongodb', 'ioredis',\n '@planetscale/database', '@neondatabase/serverless', '@libsql/client', '@vercel/postgres', 'slonik', 'sql.js'];\n/**\n * Does `pkg` establish a DATABASE api? Package provenance is not API provenance: `.query()` is a generic\n * method name, and an `@apollo/client` (or any HTTP-ish client) instance resolves to a real package while\n * having nothing to do with SQL. Without this gate, `client.query(req.body.sql)` compiled a precise\n * SQL-injection candidate for a GraphQL call — a rule that blocks legitimate traffic and mitigates nothing.\n * Subpath imports count (`drizzle-orm/node-postgres`).\n */\nconst isDbPackage = (pkg: string) =>\n DB_PACKAGES.includes(pkg) || MORE_DB_PACKAGES.includes(pkg) ||\n [...DB_PACKAGES, ...MORE_DB_PACKAGES].some((p) => pkg.startsWith(p + '/'));\nconst HTTP_PACKAGES = ['axios', 'got', 'node-fetch', 'undici', 'superagent', 'ky'];\nconst isHttpPackage = (pkg: string) => HTTP_PACKAGES.includes(pkg) || pkg === 'node:http' || pkg === 'node:https';\n// A filesystem/process API is not only a node: builtin — these wrappers expose the same sinks, and\n// requiring a match keeps recognition tied to a RESOLVED import rather than to a method name.\nconst FS_PACKAGES = ['fs-extra', 'graceful-fs', 'memfs'];\nconst isFsPackage = (pkg: string) => /^node:fs(\\/promises)?$/.test(pkg) || FS_PACKAGES.includes(pkg);\nconst EXEC_PACKAGES = ['execa', 'cross-spawn', 'shelljs', 'zx'];\nconst isExecPackage = (pkg: string) => pkg === 'node:child_process' || EXEC_PACKAGES.includes(pkg);\n\n/**\n * Which sink families this package can produce, per the recognizer tables above — i.e. what the map is\n * even *able* to see about it. Empty for the vast majority of npm: a package with no recognizer can still\n * be imported and called, we just have no model of its API, so no flow into it will ever be reported.\n * Exposed so the import inventory can say that out loud rather than let a consumer read \"no sink\" as\n * \"not reachable\". Takes a package ROOT (subpaths already normalized away by `npmPackageOf`), except for\n * `node:fs/promises`, whose subpath is part of the builtin's identity.\n */\nexport function recognizedSinkKinds(pkg: string): SinkKind[] {\n const kinds: SinkKind[] = [];\n if (isDbPackage(pkg)) kinds.push('db');\n if (isFsPackage(pkg)) kinds.push('fs');\n if (isExecPackage(pkg)) kinds.push('exec');\n if (isHttpPackage(pkg)) kinds.push('http');\n return kinds;\n}\n\nexport interface ModuleGraph {\n /** Sinks of `exportName` in the module `specifier` resolves to, relative to `fromFile`. */\n importedSinks(fromFile: string, specifier: string, exportName: string): Sink[];\n /**\n * What `exportName` traces to inside the module `specifier` resolves to — for a client instance\n * re-exported from a local module (`export const db = createClient(...)`). ONE hop: a re-export\n * chain (`export { db } from './client'`) is not followed.\n *\n * Three parts, because the package alone cannot answer whether the NAME belongs to that package:\n * package the npm package the value came from\n * origin `direct` — the target module imported this very binding from the package;\n * `factory` — the target module DERIVED it (a call result, or its own function)\n * name what the target module knows the binding as inside the package, i.e. its import\n * alias resolved back (`import { merge as deepMerge }` → `merge`). The consumer's\n * local name is the app's choice and is not part of the package's surface.\n */\n importedBinding(\n fromFile: string,\n specifier: string,\n exportName: string,\n ): { package: string; origin: 'direct' | 'factory'; name: string } | undefined;\n /**\n * The in-project file a RELATIVE specifier resolves to, or undefined — a bare package specifier, a path\n * that resolves to nothing, or a target outside the project boundary. Exposed because a caller that\n * wants to analyse the target itself (rather than ask this graph about it) still needs the same\n * resolution and the same boundary refusal; re-deriving either would let them drift apart.\n */\n resolveLocal(fromFile: string, specifier: string): string | undefined;\n}\n\nexport interface SinkContext {\n /** Absolute path of the file being analyzed (for resolving relative imports). */\n file: string;\n /** The same file, REPO-RELATIVE — part of a sink's identity, so it must not vary by machine. */\n owner: string;\n graph: ModuleGraph;\n}\n\n// --- sinks (agnostic) -------------------------------------------------------\nexport function collectLocalSinks(sf: any, ts: TsModule, bindings: Bindings, ctx?: SinkContext): Map<string, Sink[]> {\n const map = new Map<string, Sink[]>();\n const visit = (node: any) => {\n if (ts.isFunctionDeclaration(node) && node.name && node.body) map.set(node.name.text, directSinks(node.body, ts, bindings, ctx));\n else if (ts.isVariableStatement(node)) {\n for (const decl of node.declarationList.declarations) {\n if (ts.isIdentifier(decl.name) && decl.initializer && isFnLike(decl.initializer, ts)) {\n map.set(decl.name.text, directSinks(decl.initializer.body, ts, bindings, ctx));\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return map;\n}\n\nexport function sinksFrom(arrowOrNode: any, ts: TsModule, localSinks: Map<string, Sink[]>, bindings: Bindings, ctx?: SinkContext): Sink[] {\n if (!arrowOrNode) return [];\n const body = arrowOrNode.isSyntheticBody ? arrowOrNode.body\n : isFnLike(arrowOrNode, ts) ? arrowOrNode.body : arrowOrNode;\n if (!body) return [];\n const sinks = directSinks(body, ts, bindings, ctx);\n for (const called of localCalls(body, ts)) {\n // Same-file helper.\n for (const s of localSinks.get(called) ?? []) sinks.push(s);\n // Imported helper: the name resolves to a RELATIVE module → follow one hop into it.\n if (ctx) {\n const spec = bindings.resolve(called);\n if (spec && spec.startsWith('.')) {\n for (const s of ctx.graph.importedSinks(ctx.file, spec, bindings.exportNameOf(called) ?? called)) sinks.push(s);\n }\n }\n }\n // `import * as helper from './util'; helper.save(x)` — the namespace twin of the imported-helper hop\n // above. `directSinks` correctly refuses to call that receiver a dependency sink, so without this the\n // helper's REAL sinks would vanish with it and the endpoint would look clean. Sinks found this way\n // carry the helper's file, which already bars them from auto-generating a rule (no local call site).\n if (ctx) {\n for (const [root, member] of namespaceMemberCalls(body, ts)) {\n const spec = bindings.resolve(root);\n if (spec && spec.startsWith('.')) {\n for (const s of ctx.graph.importedSinks(ctx.file, spec, member)) sinks.push(s);\n }\n }\n }\n return dedupeSinks(sinks, ctx?.owner ?? '');\n}\n\n/** `ns.member(...)` calls in a subtree, as [namespace root, member] pairs. */\nfunction namespaceMemberCalls(node: any, ts: TsModule): Array<[string, string]> {\n const out: Array<[string, string]> = [];\n const visit = (n: any) => {\n if (ts.isCallExpression(n) && ts.isPropertyAccessExpression(n.expression) && ts.isIdentifier(n.expression.expression)) {\n out.push([n.expression.expression.text, n.expression.name.text]);\n }\n ts.forEachChild(n, visit);\n };\n visit(node);\n return out;\n}\n\n// Provider-agnostic sink recognizers over a subtree. Each sink is tagged with the npm package behind\n// it: resolved precisely from the call's base identifier via the file's imports, else inferred from\n// the file's imports of a known provider for that sink kind. A receiver that traces to a plain local\n// object/class/function is NOT a dependency sink and is dropped.\nfunction directSinks(node: any, ts: TsModule, bindings: Bindings, ctx?: SinkContext): Sink[] {\n const sinks: Sink[] = [];\n // `spec` is the raw module specifier the receiver came from, which `pkg` cannot express: a RELATIVE\n // specifier yields no package, and that is a positive fact (the receiver is app code) rather than the\n // absence of one (an untraceable receiver such as a handler param). The member-call recognizers below\n // need that distinction — `import * as helper from './util'; helper.exec(x)` is not child_process.\n const baseOf = (base: any): { pkg?: string; local?: boolean; root?: string; spec?: string; relative?: boolean } => {\n const root = base ? rootIdentifier(base, ts) : undefined;\n if (!root) return {};\n const spec = bindings.resolve(root);\n const relative = spec !== undefined && (spec.startsWith('.') || spec.startsWith('/'));\n const pkg = npmPackageOf(spec);\n if (pkg) return { pkg, root, spec };\n // A RELATIVE receiver is app code — unless one hop away it is a dependency. `import { db } from\n // './lib/db'` where that module does `export const db = createClient(...)` is the most common layout\n // in generated apps, and treating it as app code made the sink vanish entirely. Ask the target module\n // what the export traces to: a package means the receiver IS that dependency (an import-to-import\n // chain, so `attribution: 'import'`), and NO package means it stays app code — which is what keeps\n // `import * as helper from './util'; helper.exec(x)` correctly sink-free.\n if (relative && ctx && spec) {\n const viaModule = ctx.graph.importedBinding(ctx.file, spec, bindings.exportNameOf(root) ?? root);\n if (viaModule) return { pkg: viaModule.package, root, spec };\n }\n return { local: bindings.locals.has(root), root, spec, relative };\n };\n // Whether `package` is evidence or a guess. A resolved import binding is evidence ('import'); a\n // package inferred from the file's OTHER imports is a guess that is usually right ('inferred'); an\n // untraceable receiver is neither (undefined) and must not drive an auto-generated rule.\n const attributionOf = (b: { pkg?: string }, pkg: string | undefined): Sink['attribution'] =>\n b.pkg ? 'import' : pkg ? 'inferred' : undefined;\n /**\n * Claim `provider: 'sql'` only when the package actually establishes a database API. A traced package\n * that is not a DB provider stays in the INVENTORY (a `.query()` on it is worth a human's attention)\n * but is marked so no rule can be compiled from it — and it does not get to call itself SQL.\n */\n const dbApi = (pkg: string | undefined, attribution: Sink['attribution']): { provider?: string; apiUnconfirmed?: true } => {\n if (pkg && !isDbPackage(pkg)) return { apiUnconfirmed: true };\n // `provider` is a claim about the API at THIS call site, so it needs the receiver — not just the file.\n // An INFERRED package means \"this file talks to pg\", never \"this receiver is a pg client\", and\n // `res.locals.db.query(x)` in a file that imports pg is exactly that. The flow is already refused;\n // asserting `provider: 'sql'` anyway would overstate it in the inventory, where a human reads it.\n // `package` still carries the hint, and `attribution` already says how strong it is — deriving the\n // claim from it here keeps one source of truth rather than a second confidence field to drift.\n return attribution === 'import' || attribution === 'global' ? { provider: 'sql' } : {};\n };\n const infer = (kind: 'db' | 'http'): string | undefined => {\n const table = kind === 'db' ? DB_PACKAGES : HTTP_PACKAGES;\n for (const p of table) if (bindings.imports.has(p)) return p;\n return undefined;\n };\n const push = (s: Sink) => sinks.push(s);\n const visit = (n: any) => {\n // A function that is DECLARED here but not invoked here is not reached by this endpoint — walking\n // into it would report sinks the endpoint never touches (e.g. an unused local helper that shells\n // out). Skip those subtrees; when the handler DOES call such a helper, `localCalls` +\n // `collectLocalSinks` bring its sinks in by name. Inline callbacks / IIFEs are NOT skipped — those\n // do run (`items.map(x => db.insert(x))`, `.then(...)`).\n if (n !== node && isUninvokedFunctionDeclaration(n, ts)) return;\n if (ts.isCallExpression(n)) {\n const callee = n.expression;\n // db: `.from(\"t\").<op>()` (supabase/knex/kysely)\n if (ts.isPropertyAccessExpression(callee) && callee.name.text === 'from') {\n const b = baseOf(callee.expression);\n const t = n.arguments[0];\n const table = t && ts.isStringLiteralLike(t) ? t.text : undefined;\n const parent = n.parent;\n if (!b.local && !b.relative && parent && ts.isPropertyAccessExpression(parent) && DB_OPS.has(parent.name.text)) {\n const pkg = b.pkg ?? infer('db');\n const attribution = attributionOf(b, pkg);\n push({ kind: 'db', ...dbApi(pkg, attribution), package: pkg, table, op: parent.name.text, attribution, ...spanOf(opCallOf(parent, ts)) });\n }\n }\n if (ts.isPropertyAccessExpression(callee)) {\n const method = callee.name.text;\n const b = baseOf(callee.expression);\n // `!b.relative` is the member-call twin of the bare-call justification below: a receiver that\n // resolves to a RELATIVE module is app code, whatever its methods are named. Without it,\n // `import * as helper from './util'; helper.exec(req.body.cmd)` was read as child_process and\n // produced a proven, auto-generatable command-injection candidate for harmless local code.\n // Such a receiver is not dropped outright — `sinksFrom` follows it into its module instead.\n if (!b.local && !b.relative) {\n // db: prisma-style `prisma.<model>.<op>()` — the op names are generic (`delete`, `update`, …),\n // so require a real prisma signal: a resolved binding, the import, or a prisma-named receiver.\n if (PRISMA_OPS.has(method) && ts.isPropertyAccessExpression(callee.expression)) {\n const prismaLikely = b.pkg === '@prisma/client' ||\n (!b.pkg && (bindings.imports.has('@prisma/client') || /prisma/i.test(b.root ?? '')));\n // Same rule for the provider claim: only a resolved receiver earns `provider: 'prisma'`; a\n // prisma-NAMED receiver is a hint, and `package` + `attribution` already say so.\n if (prismaLikely) push({ kind: 'db', ...(b.pkg ? { provider: 'prisma' } : {}), package: '@prisma/client', table: callee.expression.name.text, op: method, attribution: b.pkg ? 'import' : 'inferred', ...spanOf(n) });\n }\n // db: raw `.query(` / `.execute(`. Any object can have a `.query` method, so an untraceable\n // receiver stays in the inventory with NO attribution — visible to a human, never auto-ruled.\n if (method === 'query' || method === 'execute') {\n const pkg = b.pkg ?? infer('db');\n const attribution = attributionOf(b, pkg);\n push({ kind: 'db', ...dbApi(pkg, attribution), package: pkg, op: method, attribution, ...spanOf(n) });\n }\n // fs / exec via a namespace: `fs.writeFile(` / `child_process.exec(`. The receiver must\n // actually resolve to a filesystem/process package — the method name alone proves nothing.\n if (FS_CALLS.test(method) && b.pkg && isFsPackage(b.pkg)) {\n push({ kind: 'fs', package: b.pkg, op: method, attribution: 'import', ...spanOf(n) });\n }\n if (EXEC_CALLS.test(method) && b.pkg && isExecPackage(b.pkg)) {\n push({ kind: 'exec', package: b.pkg, op: method, attribution: 'import', ...spanOf(n) });\n }\n // http: any client whose binding resolves to a known http package (`axios.get`, `ky.post`,\n // `http.request`), else the classic identifiers by name as a heuristic.\n if (HTTP_MEMBER_METHODS.has(method)) {\n if (b.pkg && isHttpPackage(b.pkg)) {\n push({ kind: 'http', provider: b.root, package: b.pkg, op: method, attribution: 'import', ...spanOf(n) });\n } else if (!b.spec && ts.isIdentifier(callee.expression) && /^(axios|http|https|got|ky)$/.test(callee.expression.text)) {\n push({ kind: 'http', provider: callee.expression.text, package: infer('http'), op: method, attribution: 'inferred', ...spanOf(n) });\n }\n }\n }\n }\n // Bare calls: `fetch(…)` / `exec(…)` / `readFile(…)` / `eval(…)`. A dangerous NAME is not a\n // dangerous API: `import { fetch } from './util'` and a callback parameter named `fetch` both look\n // identical here, and treating either as an HTTP request produced a FALSE SSRF candidate. So the\n // call must be justified — either it resolves to a module that plausibly provides that API, or it\n // is a genuine unresolved global (only `fetch`/`eval`/`Function` ever are).\n if (ts.isIdentifier(callee) && !bindings.locals.has(callee.text)) {\n const name = callee.text;\n const spec = bindings.resolve(name);\n const pkg = npmPackageOf(spec);\n const shadowed = isShadowedByEnclosingBinding(n, name, ts);\n // A relative import resolves to no package: it's app code, not the API it shares a name with.\n const fromModule = spec !== undefined;\n const trueGlobal = !fromModule && !shadowed;\n\n if (HTTP_CALLS.test(name)) {\n if (pkg && isHttpPackage(pkg)) push({ kind: 'http', provider: name, package: pkg, op: 'request', attribution: 'import', ...spanOf(n) });\n else if (name === 'fetch' && trueGlobal) push({ kind: 'http', provider: 'fetch', op: 'request', attribution: 'global', ...spanOf(n) });\n }\n // `readFile`/`exec` are never globals: without a matching module binding this is app code.\n if (FS_CALLS.test(name) && pkg && isFsPackage(pkg)) {\n push({ kind: 'fs', package: pkg, op: name, attribution: 'import', ...spanOf(n) });\n }\n if (EXEC_CALLS.test(name) && pkg && isExecPackage(pkg)) {\n push({ kind: 'exec', package: pkg, op: name, attribution: 'import', ...spanOf(n) });\n }\n if (name === 'eval' && trueGlobal) push({ kind: 'eval', op: 'eval', attribution: 'global', ...spanOf(n) });\n }\n }\n if (ts.isNewExpression(n) && ts.isIdentifier(n.expression) && n.expression.text === 'Function'\n && !bindings.locals.has('Function') && !isShadowedByEnclosingBinding(n, 'Function', ts)) {\n push({ kind: 'eval', op: 'new Function', attribution: 'global', ...spanOf(n) });\n }\n ts.forEachChild(n, visit);\n };\n visit(node);\n return sinks;\n}\n\n// --- adapter summaries: which argument means what ---------------------------\n// Small, testable per-library summaries, keyed by sink kind so an overloaded name (`get`) can't be read\n// as the wrong thing. This is the cheap foundation the review recommended BEFORE a whole-program\n// dataflow engine: without argument roles, \"the input reaches this sink\" cannot be turned into a rule,\n// because the mitigation class depends on WHICH argument received the value.\nconst ARGUMENT_ROLES: Record<string, Record<string, ArgumentRole[]>> = {\n exec: {\n exec: ['command'], execSync: ['command'],\n execFile: ['file', 'args'], execFileSync: ['file', 'args'],\n spawn: ['command', 'args'], spawnSync: ['command', 'args'], fork: ['file', 'args'],\n },\n http: {\n fetch: ['url', 'init'], request: ['url', 'options'],\n get: ['url', 'options'], head: ['url', 'options'], delete: ['url', 'options'],\n post: ['url', 'body'], put: ['url', 'body'], patch: ['url', 'body'],\n },\n fs: {\n readFile: ['path'], readFileSync: ['path'], open: ['path'],\n writeFile: ['path', 'content'], writeFileSync: ['path', 'content'],\n appendFile: ['path', 'content'],\n unlink: ['path'], rm: ['path'], rmSync: ['path'], mkdir: ['path'], readdir: ['path'], stat: ['path'],\n createReadStream: ['path'], createWriteStream: ['path'],\n },\n db: {\n query: ['sql', 'values'], execute: ['sql', 'values'],\n insert: ['values'], update: ['values'], upsert: ['values'], select: ['columns'],\n // Filters: the value half is still request data reaching the query, but as a bound parameter.\n eq: ['column', 'value'], neq: ['column', 'value'], gt: ['column', 'value'], gte: ['column', 'value'],\n lt: ['column', 'value'], lte: ['column', 'value'], like: ['column', 'value'], ilike: ['column', 'value'],\n match: ['values'], filter: ['column', 'value'],\n },\n eval: { eval: ['code'], Function: ['code'] },\n};\n\n/**\n * The (sink kind, argument role) pairs where a request value arriving is inherently dangerous AND a rule\n * can express the mitigation. Deliberately narrow — notably `db`+`values` is absent: a request value in\n * a parameterized insert is genuine reachability signal but not a blockable pattern by itself.\n */\nexport const CANDIDATE_FAMILIES: Record<string, Partial<Record<ArgumentRole, CandidateFamily>>> = {\n http: { url: 'ssrf' },\n exec: { command: 'command-injection', file: 'command-injection', args: 'command-injection' },\n fs: { path: 'path-traversal' },\n db: { sql: 'sql-injection' },\n eval: { code: 'code-injection' },\n};\n\n/** Role of argument `index` for this call, given the sink kind it was recognized as. */\nexport function argumentRoleOf(sinkKind: string, method: string | undefined, index: number, total = 0): ArgumentRole {\n // `new Function(a, b, \"return a+b\")` — every argument but the LAST declares a parameter name; only the\n // last one is executable code. An index-based table cannot express that.\n if (sinkKind === 'eval' && method === 'Function') return index === total - 1 ? 'code' : 'args';\n const table = method ? ARGUMENT_ROLES[sinkKind]?.[method] : undefined;\n return table?.[index] ?? 'unknown';\n}\n\n// Deterministic identity for a sink, so `Flow.sink` (an embedded copy) can be correlated back to the\n// inventory entry without deep-equality. `owner` is the endpoint's own repo-relative file, which the\n// span alone does NOT imply: duplicated route boilerplate across two files puts the same call at the\n// same offsets, and hashing only the span made those sinks share an id while the schema promises\n// map-wide identity. A repo-relative path (never absolute) keeps the id stable across machines.\nfunction sinkId(s: Sink, owner: string): string {\n return createHash('sha256')\n .update([s.kind, s.provider, s.package, s.table, s.op, s.file ?? owner, s.start, s.end].join('|'))\n .digest('hex')\n .slice(0, 12);\n}\n\nfunction dedupeSinks(sinks: Sink[], owner: string): Sink[] {\n const seen = new Set<string>();\n const out: Sink[] = [];\n for (const s of sinks) {\n const key = `${s.kind}:${s.provider}:${s.package}:${s.table}:${s.op}:${s.line}:${s.start}`;\n if (!seen.has(key)) { seen.add(key); out.push({ ...s, id: sinkId(s, owner) }); }\n }\n return out;\n}\n","import { readFileSync, realpathSync, statSync } from 'node:fs';\nimport { dirname, join, relative, resolve as resolvePath } from 'node:path';\nimport type { Sink, TsModule } from './types.js';\nimport { guessScriptKind, isFnLike, localCalls } from './ast.js';\nimport { buildModuleBindings, npmPackageOf, type Bindings } from './bindings.js';\nimport { isInside } from './sources.js';\nimport { collectLocalSinks, type ModuleGraph } from './sinks.js';\n\n// --- cross-file (imported) helper tracing -----------------------------------\n// AI-generated apps routinely put the data access in a sibling module (`import { saveOrder } from\n// './db'`), so a handler's real sink lives one file away. Without following that, the endpoint looks\n// sink-free and no rule can be correlated to it. We follow ONE cross-file hop (plus same-file helpers\n// inside the target), which covers the common shape while keeping the walk bounded and cheap.\nconst RESOLVE_EXTS = ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs'];\n\nexport function createModuleGraph(ts: TsModule, opts: { cwd: string; boundary: string; followOutside?: boolean }): ModuleGraph {\n // file → { fnSinks, calleesOf, bindings } | null (unreadable/unparseable)\n type Entry = { fnSinks: Map<string, Sink[]>; calleesOf: Map<string, string[]>; bindings: Bindings };\n const cache = new Map<string, Entry | null>();\n\n const load = (file: string) => {\n if (cache.has(file)) return cache.get(file) ?? null;\n let entry: Entry | null = null;\n try {\n const text = readFileSync(file, 'utf8');\n const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true, guessScriptKind(ts, file));\n const bindings = buildModuleBindings(sf, ts);\n // `bindings` is kept for `importedBinding`: the module's own view of what its exports came from.\n entry = { fnSinks: collectLocalSinks(sf, ts, bindings), calleesOf: collectCallees(sf, ts), bindings };\n } catch {\n entry = null; // fail-open: an unreadable dependency must not break the map\n }\n cache.set(file, entry);\n return entry;\n };\n\n /** Shared guard: resolve a relative specifier, and refuse to leave the project. */\n const resolveInProject = (fromFile: string, specifier: string): string | undefined => {\n const target = resolveRelativeModule(fromFile, specifier);\n if (!target) return undefined;\n // Stay inside the project: `../../other-repo/db` (or a symlink) would otherwise pull an unrelated\n // codebase into this app's attack surface. The primary walker enforces this; so must the resolver.\n if (!opts.followOutside) {\n let real = target;\n try { real = realpathSync(target); } catch { /* use as-is */ }\n if (!isInside(real, opts.boundary)) return undefined;\n }\n return target;\n };\n\n return {\n resolveLocal: resolveInProject,\n\n importedSinks(fromFile, specifier, exportName) {\n const target = resolveInProject(fromFile, specifier);\n if (!target) return [];\n const mod = load(target);\n if (!mod) return [];\n const collected = [...(mod.fnSinks.get(exportName) ?? [])];\n // One same-file hop inside the target: `export function saveOrder(){ return doInsert() }`.\n for (const callee of mod.calleesOf.get(exportName) ?? []) {\n for (const s of mod.fnSinks.get(callee) ?? []) collected.push(s);\n }\n // `line` refers to the HELPER's file, not the endpoint's — carry the file so the coordinate is\n // interpretable (and so flow linking marks it `imported` rather than proven — it cannot see the call).\n const rel = relative(opts.cwd, target);\n return collected.map((s) => ({ ...s, file: rel }));\n },\n\n // A different question about the same module: not \"what sinks are in there\" but \"what does this\n // export TRACE TO\". The common AI-built layout puts the client in a lib file —\n // `export const db = createClient(...)` in `lib/db.ts`, imported everywhere — so the receiver of\n // `db.from('orders').insert(...)` resolves to a relative specifier and nothing else. Refusing it (as\n // an unattributable receiver) is right for app code but wrong here: one hop away it is a real\n // dependency, and that chain is import-to-import, fully static — evidence, not inference.\n importedBinding(fromFile, specifier, exportName) {\n const target = resolveInProject(fromFile, specifier);\n if (!target) return undefined;\n const mod = load(target);\n if (!mod) return undefined;\n // The target module's own bindings answer it: `db` there resolves through\n // `const db = createClient(...)` back to the package `createClient` was imported from.\n const pkg = npmPackageOf(mod.bindings.resolve(exportName));\n if (pkg === undefined) return undefined;\n // `origin` and `name` come from the SAME module as the package, which is the point: a consumer\n // one hop away can see neither how the value was produced there nor what the package calls it.\n return {\n package: pkg,\n origin: mod.bindings.originOf(exportName) ?? 'direct',\n name: mod.bindings.exportNameOf(exportName) ?? exportName,\n };\n },\n };\n}\n\n// Resolve a RELATIVE specifier to a real file (extension + /index, and the TS-ESM `./db.js` → db.ts\n// convention). Bare package specifiers are intentionally NOT followed — that's node_modules, and a\n// dependency's internals are not this app's attack surface.\nfunction resolveRelativeModule(fromFile: string, spec: string): string | undefined {\n if (!spec.startsWith('.')) return undefined;\n const dir = dirname(fromFile);\n const base = resolvePath(dir, spec);\n const candidates: string[] = [];\n const jsLike = /\\.(js|jsx|mjs|cjs)$/.exec(base);\n if (jsLike) {\n const stem = base.slice(0, -jsLike[0].length);\n for (const e of RESOLVE_EXTS) candidates.push(stem + e); // ./db.js may mean db.ts\n }\n candidates.push(base);\n for (const e of RESOLVE_EXTS) candidates.push(base + e);\n for (const e of RESOLVE_EXTS) candidates.push(join(base, 'index' + e));\n for (const c of candidates) {\n try {\n if (statSync(c).isFile()) return c;\n } catch {\n /* next */\n }\n }\n return undefined;\n}\n\n// name → the local function names it calls (for one same-file hop inside an imported module).\nfunction collectCallees(sf: any, ts: TsModule): Map<string, string[]> {\n const map = new Map<string, string[]>();\n const visit = (node: any) => {\n let name: string | undefined;\n let body: any;\n if (ts.isFunctionDeclaration(node) && node.name && node.body) { name = node.name.text; body = node.body; }\n else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer && isFnLike(node.initializer, ts)) {\n name = node.name.text; body = node.initializer.body;\n }\n if (name && body) map.set(name, localCalls(body, ts));\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return map;\n}\n","import type { AddressSpace, FieldShape, InputField, InputSource } from './types.js';\n\n/**\n * Map an input to the EXACT rule-engine parameter that addresses it, or null with a reason. Verified\n * against the resolver in engine/request.js — a coordinate that the resolver cannot resolve would compile\n * into a rule that silently never matches, which is worse than emitting nothing:\n * - body / json / form / multipart / server-fn args → `post.<dotted path>` (createServerFnGuard feeds\n * server-function arguments through as the JSON body, so `post.<field>` resolves them)\n * - query → `get.<name>`\n * - header → `server.HTTP_<UPPER_SNAKE>` (resolver lowercases and maps `_` → `-`)\n * - cookie → `cookie.<name>`\n * - file → `files.<field>` (`.content` / `.type` / `.filename` are separate)\n * - route-param → NONE. The resolver exposes get/post/request/cookie/server/files — NOT `req.params`.\n * - array path → NONE. `#getNestedValue` walks own properties, so `tags[].label` needs an\n * `array_key_value` rule, not a dotted parameter.\n */\nexport function runtimeCoordinate(source: InputSource | undefined, path: string): { runtimeParameter: string | null; runtimeParameterReason?: string } {\n if (/\\[\\d*\\]/.test(path)) {\n return { runtimeParameter: null, runtimeParameterReason: 'array traversal: needs an array_key_value rule, not a dotted parameter' };\n }\n switch (source) {\n case 'json-body':\n case 'form-body':\n case 'multipart':\n case 'body':\n case 'server-fn-data':\n return { runtimeParameter: `post.${path}` };\n case 'query':\n return { runtimeParameter: `get.${path}` };\n case 'cookie':\n return { runtimeParameter: `cookie.${path}` };\n case 'file':\n return { runtimeParameter: `files.${path}` };\n case 'header':\n return { runtimeParameter: `server.HTTP_${path.toUpperCase().replace(/-/g, '_')}` };\n case 'route-param':\n return { runtimeParameter: null, runtimeParameterReason: 'route parameters are not exposed by the runtime resolver' };\n default:\n return { runtimeParameter: null, runtimeParameterReason: 'input source could not be determined' };\n }\n}\n\n/**\n * The request region an input lives in — its identity, independent of whether we can currently ADDRESS\n * it. A route param has a space (`route-param`) but no coordinate; an array path has a space (`post`)\n * but needs an `array_key_value` rule. Keep those two questions apart: conflating them made an\n * unaddressable input indistinguishable from one in another region.\n */\nexport function addressSpaceOf(source: InputSource | undefined): AddressSpace {\n switch (source) {\n case 'json-body':\n case 'form-body':\n case 'multipart':\n case 'body':\n case 'server-fn-data':\n return 'post';\n case 'query': return 'get';\n case 'cookie': return 'cookie';\n case 'file': return 'files';\n case 'header': return 'server';\n case 'route-param': return 'route-param';\n default: return 'unknown';\n }\n}\n\n/**\n * Is this flow backed by a read seen at the sink's own call site? True for the two `*-local` tiers.\n * `imported` / `heuristic` / `unknown` all mean \"we did not see the argument\", for different reasons.\n */\nexport function isProvenFlow(confidence: string | undefined): boolean {\n return confidence === 'exact-local' || confidence === 'transformed-local';\n}\n\n/** `<space>:<path>` — an input's identity within an endpoint. */\nexport function inputIdOf(source: InputSource | undefined, path: string): string {\n return `${addressSpaceOf(source)}:${path}`;\n}\n\n/**\n * The rule-engine NAMESPACE an input lands in (`post`, `get`, `cookie`, `files`, `server`), or null when\n * it has no address. Derived from `runtimeCoordinate` on purpose: comparing raw source labels would call\n * `json-body` and an Express `req.body` read different places when both resolve to `post.*`, and would\n * miss that `post.id` and `get.id` are genuinely different places.\n */\nexport function namespaceOf(source: InputSource | undefined, path: string): string | null {\n const { runtimeParameter } = runtimeCoordinate(source, path);\n if (!runtimeParameter) return null;\n const dot = runtimeParameter.indexOf('.');\n return dot === -1 ? runtimeParameter : runtimeParameter.slice(0, dot);\n}\n\n/** Place extracted fields in a request region: attach `source`, the runtime coordinate, and the id. */\nexport function withCoordinates(fields: FieldShape[], source: InputSource): InputField[] {\n return fields.map((f) => {\n const src = f.source ?? source;\n return { ...f, source: src, id: inputIdOf(src, f.name), ...runtimeCoordinate(src, f.name) };\n });\n}\n","import type { FieldShape, InputField, InputSource, TsModule } from './types.js';\nimport { bindingKey, rootIdentifier } from './ast.js';\nimport { npmPackageOf, type Bindings } from './bindings.js';\nimport { addressSpaceOf, inputIdOf, runtimeCoordinate } from './coordinates.js';\n\nconst ZOD_BASE = new Set(['string', 'number', 'boolean', 'array', 'object', 'enum', 'bigint', 'date', 'record']);\n// String-format refinements a validator can declare — kept on the field so a rule can pin the shape.\nconst STRING_FORMATS = new Set(['email', 'uuid', 'url', 'ip', 'ipv4', 'ipv6', 'cuid', 'cuid2', 'ulid', 'emoji', 'datetime', 'base64', 'jwt', 'nanoid']);\n// Packages whose `.object({…})` calls describe an input schema.\nconst VALIDATOR_PACKAGES = new Set(['zod', 'valibot', 'yup', 'joi', '@hapi/joi', 'superstruct']);\n\n// --- inputs -----------------------------------------------------------------\nexport function inputsFromValidator(validatorCall: any, ts: TsModule, bindings: Bindings): FieldShape[] {\n if (!validatorCall) return [];\n return zodObjectFields(validatorCall, ts, bindings);\n}\n\n// From a raw handler: validator schema fields it parses, plus the request fields it actually reads\n// (member accesses, destructuring, `await request.json()` bodies).\nexport function inputsFromHandler(\n params: any,\n body: any,\n ts: TsModule,\n bindings: Bindings,\n opts: { payloadParam?: boolean; validatorSource?: InputSource } = {},\n): InputField[] {\n // A validated schema inside a handler describes the request body — except for a payload-style entry\n // (a server action), where the schema describes the action's own argument.\n const schemaSource = opts.validatorSource ?? 'json-body';\n const schemaFields = zodObjectFields(body, ts, bindings);\n const reads = requestMemberAccesses(params, body, ts, opts);\n\n // Keyed by IDENTITY — `<space>:<path>` — not by field name. A handler that reads `query.id` and\n // `params.id`, or validates a body field named `id` while the sink consumes `query.id`, has TWO inputs\n // that merely share a name. Name-keying made one of them disappear, and since the survivor decided the\n // coordinate, a rule could be pinned to a parameter the payload never travels in. Distinct identities\n // remove that class outright: each input carries its own address, and a flow names which one it means.\n // Same space + same path IS the same input, so a schema field and an `req.body` read of it merge\n // (the schema entry wins, since it also carries the declared type/constraints).\n const byId = new Map<string, InputField>();\n const put = (name: string, source: InputSource, extra: Omit<FieldShape, 'name' | 'source'> = {}) => {\n const id = inputIdOf(source, name);\n if (byId.has(id)) return;\n byId.set(id, { ...extra, id, name, source, ...runtimeCoordinate(source, name) });\n };\n for (const f of schemaFields) {\n const { name, source, ...shape } = f;\n put(name, source ?? schemaSource, shape);\n }\n for (const { name, sources } of reads) for (const source of sources) put(name, source);\n return [...byId.values()];\n}\n\n// Find the first validator `.object({...})` in a subtree — gated on the receiver tracing to a known\n// validator package (so an unrelated `.object(` never becomes a schema). An untraceable receiver\n// literally named `z` is accepted as a heuristic (covers `z` re-exported from a local module).\nfunction findValidatorObject(node: any, ts: TsModule, bindings: Bindings): any {\n let found: any = null;\n const find = (n: any) => {\n if (found || !n) return;\n if (ts.isCallExpression(n) && ts.isPropertyAccessExpression(n.expression) && n.expression.name.text === 'object') {\n const root = rootIdentifier(n.expression.expression, ts);\n const pkg = root ? npmPackageOf(bindings.resolve(root)) : undefined;\n const isValidator = (pkg && VALIDATOR_PACKAGES.has(pkg)) || (!pkg && root === 'z' && !bindings.locals.has(root));\n if (isValidator) {\n const arg = n.arguments[0];\n if (arg && ts.isObjectLiteralExpression(arg)) { found = arg; return; }\n }\n }\n ts.forEachChild(n, find);\n };\n find(node);\n return found;\n}\n\n// Read a validator object's fields (name + type/constraints). Nested objects/arrays are flattened to\n// dotted paths — `address.city`, `tags[].label` — the same coordinates `array_key_value` rules use.\nfunction zodObjectFields(node: any, ts: TsModule, bindings: Bindings): FieldShape[] {\n if (!node) return [];\n const lit = findValidatorObject(node.body ?? node, ts, bindings);\n return lit ? fieldsOfObject(lit, ts, bindings, '') : [];\n}\n\nfunction fieldsOfObject(objectLiteral: any, ts: TsModule, bindings: Bindings, prefix: string): FieldShape[] {\n const fields: FieldShape[] = [];\n for (const p of objectLiteral.properties) {\n if (!ts.isPropertyAssignment(p) || !p.name) continue;\n const fname = (p.name as any).text;\n if (!fname) continue;\n const shape = zodShape(p.initializer, ts);\n fields.push({ name: prefix + fname, ...shape });\n const nested = findValidatorObject(p.initializer, ts, bindings);\n if (nested) fields.push(...fieldsOfObject(nested, ts, bindings, prefix + fname + (shape.type === 'array' ? '[].' : '.')));\n }\n return fields;\n}\n\nfunction numericValue(arg: any, ts: TsModule): number | undefined {\n if (!arg) return undefined;\n if (ts.isNumericLiteral(arg)) return Number(arg.text);\n if (ts.isPrefixUnaryExpression(arg) && arg.operator === ts.SyntaxKind.MinusToken && ts.isNumericLiteral(arg.operand)) return -Number(arg.operand.text);\n return undefined;\n}\n\nfunction zodShape(node: any, ts: TsModule): Omit<FieldShape, 'name'> {\n const shape: Omit<FieldShape, 'name'> = {};\n let cur = node;\n while (cur && ts.isCallExpression(cur) && ts.isPropertyAccessExpression(cur.expression)) {\n const method = cur.expression.name.text;\n const arg0 = cur.arguments[0];\n if (ZOD_BASE.has(method) && !shape.type) shape.type = method;\n if (method === 'min') { const v = numericValue(arg0, ts); if (v !== undefined) shape.min = v; }\n if (method === 'max') { const v = numericValue(arg0, ts); if (v !== undefined) shape.max = v; }\n if (STRING_FORMATS.has(method) && !shape.format) shape.format = method;\n if (method === 'regex' && arg0 && ts.isRegularExpressionLiteral(arg0) && !shape.pattern) shape.pattern = arg0.text;\n if (method === 'optional' || method === 'nullish') shape.optional = true;\n cur = cur.expression.expression;\n }\n return shape;\n}\n\nexport const REQ_SOURCES = ['body', 'query', 'params'];\n\n// The request fields a handler reads, across the common idioms:\n// req.body.x / req.query.x / req.params.x (member access)\n// const { x } = req.body (destructuring)\n// ({ body }) => body.x / const { x } = body (destructured handler param)\n// const b = await request.json(); b.x / const { x } = await request.json() (fetch-style Request)\nfunction requestMemberAccesses(\n params: any,\n body: any,\n ts: TsModule,\n opts: { payloadParam?: boolean } = {},\n): Array<{ name: string; sources: InputSource[] }> {\n if (!body) return [];\n // Keyed by FIELD NAME, which two namespaces can share (`params.id` and `query.id` in one handler).\n // Last-write-wins silently picked one, and since the pick decided the coordinate, a handler reading\n // both compiled a rule pinned to `get.id` for data that arrives in the path segment — a wrong-input\n // pin, the one failure this whole layer exists to prevent. Collisions are now recorded, and the\n // first-seen source wins so the record is at least deterministic.\n const out = new Map<string, InputSource[]>();\n const record = (name: string, source: InputSource) => {\n const list = out.get(name) ?? [];\n if (!list.includes(source)) list.push(source);\n out.set(name, list);\n };\n const p0 = params?.[0];\n const reqName = p0 && ts.isIdentifier(p0.name) ? p0.name.text : undefined;\n // Identifiers that ARE a request-input object (destructured `({ body })` param, `await req.json()`),\n // mapped to the NAMESPACE each one came from. It has to be a map, not a set of names: with\n // `({ query: q })` the local is `q`, and matching the local against the literal 'query'/'params'\n // discards the namespace — which silently mis-addresses the input (`post.doc` for a query-string\n // field, and worse, a coordinate for a route param, which the resolver cannot address at all).\n const sourceNames = new Map<string, InputSource>();\n const payloadNames = new Set<string>();\n if (opts.payloadParam && p0 && ts.isIdentifier(p0.name)) payloadNames.add(p0.name.text);\n if (p0 && !reqName && ts.isObjectBindingPattern(p0.name)) {\n for (const el of p0.name.elements) {\n const key = bindingKey(el, ts);\n if (key && REQ_SOURCES.includes(key) && ts.isIdentifier(el.name)) {\n sourceNames.set(el.name.text, namespaceSource(key));\n }\n }\n }\n const unwrap = (e: any): any => {\n let cur = e;\n while (cur && (ts.isAwaitExpression(cur) || ts.isAsExpression(cur) || ts.isParenthesizedExpression(cur) || ts.isNonNullExpression(cur))) cur = cur.expression;\n return cur;\n };\n const isPayloadExpr = (e: any): boolean => ts.isIdentifier(e) && payloadNames.has(e.text);\n const isReqSourceExpr = (e: any): boolean =>\n isPayloadExpr(e) ||\n (ts.isPropertyAccessExpression(e) && ts.isIdentifier(e.expression) && e.expression.text === reqName && REQ_SOURCES.includes(e.name.text)) ||\n (ts.isIdentifier(e) && sourceNames.has(e.text));\n const isBodyReadCall = (e: any): boolean => {\n const inner = unwrap(e);\n return Boolean(inner && ts.isCallExpression(inner) && ts.isPropertyAccessExpression(inner.expression) &&\n ['json', 'formData'].includes(inner.expression.name.text) &&\n ts.isIdentifier(inner.expression.expression) && inner.expression.expression.text === reqName);\n };\n const visit = (n: any) => {\n // <source>.<field>\n if (ts.isPropertyAccessExpression(n) && isReqSourceExpr(n.expression)) {\n record(n.name.text, sourceOfExpr(n.expression));\n }\n if (ts.isVariableDeclaration(n) && n.initializer) {\n const init = unwrap(n.initializer);\n // const b = await request.json() → b is a request-input object from here on.\n if (ts.isIdentifier(n.name) && isBodyReadCall(n.initializer)) sourceNames.set(n.name.text, bodyReadSource(n.initializer));\n // const { query: q } = req → the SAME namespace capture as a destructured handler param, just one\n // statement later. Without this the fields read off `q` are invisible: no coordinate is emitted\n // (so nothing is mis-addressed) but the surface goes unreported, which reads as \"nothing here\".\n if (ts.isObjectBindingPattern(n.name) && ts.isIdentifier(init) && reqName && init.text === reqName) {\n for (const el of n.name.elements) {\n const key = bindingKey(el, ts);\n if (key && REQ_SOURCES.includes(key) && ts.isIdentifier(el.name)) sourceNames.set(el.name.text, namespaceSource(key));\n }\n }\n // const { a, b } = <source> | await request.json()\n if (ts.isObjectBindingPattern(n.name) && (isReqSourceExpr(init) || isBodyReadCall(n.initializer))) {\n const src = isBodyReadCall(n.initializer) ? bodyReadSource(n.initializer) : sourceOfExpr(init);\n for (const el of n.name.elements) {\n const key = bindingKey(el, ts);\n if (key) record(key, src);\n }\n }\n }\n ts.forEachChild(n, visit);\n };\n visit(body);\n return [...out].map(([name, sources]) => ({ name, sources }));\n\n // `req.body.x` / `req.query.x` / `req.params.x` — the namespace decides the runtime coordinate, and\n // route params notably have NONE, so this distinction is load-bearing rather than cosmetic.\n function sourceOfExpr(e: any): InputSource {\n if (isPayloadExpr(e)) return 'server-fn-data';\n if (ts.isPropertyAccessExpression(e)) {\n if (e.name.text === 'query') return 'query';\n if (e.name.text === 'params') return 'route-param';\n if (e.name.text === 'body') return 'body';\n }\n // The recorded namespace, so an ALIAS resolves correctly (`({ query: q }) => q.id` → query).\n if (ts.isIdentifier(e)) {\n const recorded = sourceNames.get(e.text);\n if (recorded) return recorded;\n }\n return 'body';\n }\n\n /** Map a request namespace key to the input source it implies. */\n function namespaceSource(key: string): InputSource {\n if (key === 'query') return 'query';\n if (key === 'params') return 'route-param';\n return 'body';\n }\n function bodyReadSource(init: any): InputSource {\n const t = init?.getText?.() ?? '';\n return /formData\\s*\\(/.test(t) ? 'form-body' : 'json-body';\n }\n}\n","import type { AddressSpace, ArgumentRole, Flow, InputField, Limitation, Sink, TsModule } from './types.js';\nimport { bindingKey, calleeName, isValueRead, lineOf, rootIdentifier } from './ast.js';\nimport { REQ_SOURCES } from './inputs.js';\nimport { addressSpaceOf } from './coordinates.js';\nimport { argumentRoleOf, CANDIDATE_FAMILIES } from './sinks.js';\n\n/** A tainted binding: the path prefix it stands for, and the request region it came from if known. */\ninterface Root { path: string; space?: AddressSpace }\n\n/** The address space a request-namespace binding key implies (`query` → get, `params` → route-param). */\nfunction spaceOfKey(key: string | undefined): AddressSpace | undefined {\n if (key === 'query') return 'get';\n if (key === 'params') return 'route-param';\n if (key === 'body') return 'post';\n // `data` / `input` / `payload`: a server-function argument, which the guard feeds through as the body.\n if (key === 'data' || key === 'input' || key === 'payload') return 'post';\n return undefined;\n}\n\n// --- input → sink flow linking ---------------------------------------------\n// Evidence-backed data links: for each sink, does an INPUT identifier/path appear inside the sink\n// call's arguments? \"Tainted\" roots are the handler's own parameter names (`{ data }`, `req`) plus any\n// local alias of them (`const body = await request.json()`, `const { title } = data`).\n//\n// Deliberately conservative: a match yields one of the two `*-local` tiers; no match yields `imported` /\n// `heuristic` / `unknown` depending on WHY nothing was seen. It never claims a flow it didn't see, which\n// is the point — a consumer pinning a rule should require a proven tier (see `isProvenFlow`) and treat\n// the rest as \"may reach\". Matching is per (address space, path): a read of `query.id` is not evidence\n// about the body field `id`.\n// Spread onto an endpoint: `flows`, plus `limitations` only when there are any (keeps the common case clean).\nexport function linkedFlows(body: any, params: any, inputs: InputField[], sinks: Sink[], ts: TsModule): { flows: Flow[]; limitations?: Limitation[] } {\n const { flows, limitations } = linkFlows(body, params, inputs, sinks, ts);\n return limitations.length > 0 ? { flows, limitations } : { flows };\n}\n\nfunction linkFlows(\n bodyNode: any,\n params: any,\n inputs: InputField[],\n sinks: Sink[],\n ts: TsModule,\n): { flows: Flow[]; limitations: Limitation[] } {\n if (!bodyNode || sinks.length === 0 || inputs.length === 0) return { flows: [], limitations: [] };\n\n // Tainted roots and the PATH each one stands for. `req` → '' (its own members are the path);\n // `const { billing } = await req.json()` → billing stands for 'billing', so a read of\n // `billing.email` normalizes to 'billing.email' and can be compared with the input path.\n // Bindings whose members ARE the input paths, so they contribute no segment: a request source\n // (`{ body }`), and the validated-payload conventions of the server-fn frameworks (`{ data }` for\n // TanStack). Getting this wrong shifts every path by one segment and silently kills all matching.\n const CONTAINER_KEYS = new Set([...REQ_SOURCES, 'data', 'input', 'payload']);\n // Each tainted root also carries the ADDRESS SPACE it was bound from, when that is known. A bare `req`\n // has none — its next segment decides (`req.query.x` vs `req.body.x`) — but `({ query: q })` fixes `q`\n // in `get` for good. Without this the space was dropped along with the namespace segment, so a read of\n // `query.id` was indistinguishable from a read of `body.id` and could match either input.\n const rootPath = new Map<string, Root>();\n const addRoot = (name: string, path: string, space?: AddressSpace) => {\n if (!rootPath.has(name)) rootPath.set(name, { path, space });\n };\n for (const p of params ?? []) {\n if (!p?.name) continue;\n if (ts.isIdentifier(p.name)) addRoot(p.name.text, '');\n else if (ts.isObjectBindingPattern(p.name)) {\n for (const el of p.name.elements) {\n if (!ts.isBindingElement(el) || !ts.isIdentifier(el.name)) continue;\n const key = bindingKey(el, ts);\n // A destructured request source (`{ body }`) is a container: its members ARE the paths.\n const container = key !== undefined && CONTAINER_KEYS.has(key);\n addRoot(el.name.text, container ? '' : key ?? el.name.text, container ? spaceOfKey(key) : undefined);\n }\n }\n }\n\n // Does this initializer carry request data? Includes `Schema.parse(await req.json())`: VALIDATION IS\n // NOT SANITIZATION — a validated value is still attacker-controlled, and treating it as clean would\n // silently drop every flow in a validated handler (the common TanStack/Next shape).\n const requestReadPath = (init: any): Root | undefined => {\n let cur = init;\n while (cur && (ts.isAwaitExpression(cur) || ts.isParenthesizedExpression(cur) || ts.isAsExpression(cur) || ts.isNonNullExpression(cur))) cur = cur.expression;\n if (!cur) return undefined;\n if (ts.isCallExpression(cur) && ts.isPropertyAccessExpression(cur.expression)) {\n const m = cur.expression.name.text;\n if (['json', 'formData', 'text'].includes(m)) {\n const root = rootIdentifier(cur.expression.expression, ts);\n // A body read: whatever the field names turn out to be, they are addressed in `post`.\n return root && rootPath.has(root) ? { path: '', space: 'post' } : undefined;\n }\n if (['parse', 'safeParse', 'validate', 'cast'].includes(m)) {\n for (const a of cur.arguments) {\n const inner = requestReadPath(a);\n if (inner !== undefined) return inner; // taint survives validation\n }\n return undefined;\n }\n }\n const p = pathFromTainted(cur, ts, rootPath);\n return p;\n };\n\n const aliasVisit = (n: any) => {\n if (ts.isVariableDeclaration(n) && n.initializer) {\n const base = requestReadPath(n.initializer);\n if (base !== undefined) {\n if (ts.isIdentifier(n.name)) addRoot(n.name.text, base.path, base.space);\n else if (ts.isObjectBindingPattern(n.name)) {\n for (const el of n.name.elements) {\n if (!ts.isBindingElement(el) || !ts.isIdentifier(el.name)) continue;\n const key = bindingKey(el, ts);\n // `const { query: q } = req` — the binding KEY names the space when the base has none yet.\n const space = base.space ?? (base.path === '' ? spaceOfKey(key) : undefined);\n const container = base.path === '' && key !== undefined && CONTAINER_KEYS.has(key);\n addRoot(el.name.text, container ? '' : join2(base.path, key ?? el.name.text), space);\n }\n }\n }\n }\n ts.forEachChild(n, aliasVisit);\n };\n aliasVisit(bodyNode);\n\n // Index every call by its start offset so a sink's span identifies its EXACT call node.\n // Keyed by start+end: in `db.from(t).insert(x)` BOTH calls start at `db`, so the start offset alone\n // is ambiguous — the end distinguishes them.\n const callBySpan = new Map<string, any>();\n const callVisit = (n: any) => {\n // NewExpression too, or `new Function(...)` — inventoried as an eval sink — could never be located,\n // leaving its flows permanently heuristic and its argument-role entry unreachable.\n if (ts.isCallExpression(n) || ts.isNewExpression(n)) {\n try { callBySpan.set(`${n.getStart()}:${n.getEnd()}`, n); } catch { /* synthetic */ }\n }\n ts.forEachChild(n, callVisit);\n };\n callVisit(bodyNode);\n\n const flows: Flow[] = [];\n const allLimits: Limitation[] = [];\n for (const sink of sinks) {\n // A sink from an imported module has no call site here — its flows can only be `imported`.\n const node = sink.file === undefined && sink.start !== undefined && sink.end !== undefined\n ? callBySpan.get(`${sink.start}:${sink.end}`)\n : undefined;\n // path → the argument ROLES it was read into. Per-argument attribution is what makes a candidate\n // possible: the same value in `url` vs `body`, or `path` vs `content`, implies different mitigations.\n // Keyed by `<space>:<path>` so a read of `query.id` cannot lend its evidence to the body field `id`.\n const reads = new Map<string, { read: Root; roles: Set<ArgumentRole>; exact: boolean }>();\n const sinkLimits: Limitation[] = [];\n if (node) {\n // ONLY this sink call's own arguments, plus other calls in the SAME fluent chain\n // (`.update({…}).eq('id', data.id)` is one operation). Never the enclosing statement: a sibling\n // expression such as `Promise.all([audit(data.title), db.insert({…})])` must not lend evidence.\n for (const call of fluentChainCalls(node, ts)) {\n const method = calleeName(call, ts);\n const args = call.arguments ?? [];\n for (const a of args) for (const l of sinkArgumentLimitations(a, ts, rootPath)) sinkLimits.push(l);\n for (let i = 0; i < args.length; i++) {\n const role = argumentRoleOf(sink.kind, method, i, args.length);\n // Is the ARGUMENT ITSELF the read (`readFileSync(req.body.p)`), or does the read sit inside a\n // larger expression (`readFileSync('/tmp/' + req.body.p)`)? Both mean the value arrives in the\n // same parameter, but only the first says what reaches the sink is exactly what arrived — the\n // distinction a server needs before promoting a rule to blocking without a human.\n const whole = pathFromTainted(args[i], ts, rootPath);\n for (const read of taintedReadPaths(args[i], ts, rootPath)) {\n const key = `${read.space ?? '*'}:${read.path}`;\n const exact = whole !== undefined && whole.path === read.path && whole.space === read.space;\n const entry = reads.get(key) ?? { read, roles: new Set<ArgumentRole>(), exact: false };\n entry.roles.add(role);\n entry.exact = entry.exact || exact;\n reads.set(key, entry);\n }\n }\n }\n }\n for (const input of inputs) {\n const inputPath = normalizePath(input.name);\n const inputSpace = addressSpaceOf(input.source);\n // Exact path, or the input is an ANCESTOR of what was read (`billing` covers `billing.email`).\n // A mere shared leaf name is NOT evidence: `billing.email` and `shipping.email` are different.\n // The SPACE must agree too, or the two `id`s of `query.id` / `body.id` trade evidence and a rule\n // gets pinned to whichever the extractor happened to keep. A read whose space is unknown (a bare\n // `req` handed to a helper, say) still matches on path alone — recall, at heuristic strength.\n const matched = [...reads.values()].filter(({ read }) =>\n (read.space === undefined || read.space === inputSpace)\n && (read.path === inputPath || read.path.startsWith(inputPath + '.')));\n const proven = matched.length > 0;\n // Weakest-honest tier that fits the evidence.\n const confidence: Flow['confidence'] = proven\n ? (matched.some((m) => m.exact) ? 'exact-local' : 'transformed-local')\n : sink.file !== undefined ? 'imported'\n // No span at all (a synthetic node) means no evidence is even possible. A sink whose span exists\n // but sits outside this handler — reached through a same-file helper — is ordinary co-occurrence:\n // located, just not attributable to an argument here. Calling that \"unknown\" would overstate it.\n : sink.start === undefined ? 'unknown'\n : 'heuristic';\n const roles = new Set<ArgumentRole>(matched.flatMap(({ roles: rs }) => [...rs]));\n // Prefer a role that maps to a mitigation class over a generic one (a value can reach two args).\n // A sink whose package does not establish this API cannot support the mitigation class either:\n // labelling a GraphQL `.query()` as the sql-injection family would mis-classify it for any consumer\n // that reads `candidateFamily` without also checking `ruleGeneratable`.\n const family = sink.apiUnconfirmed\n ? undefined\n : [...roles].map((r) => CANDIDATE_FAMILIES[sink.kind]?.[r]).find(Boolean);\n const argumentRole = family\n ? [...roles].find((r) => CANDIDATE_FAMILIES[sink.kind]?.[r])\n : [...roles].find((r) => r !== 'unknown') ?? (proven ? 'unknown' : undefined);\n\n // Deliberately SEPARATE from confidence: a proven tier means \"the source reaches the sink\", which is\n // not authorization to block traffic. Every remaining obstacle is listed, so this doubles as the\n // queue for improving the extractor/adapters rather than silently losing the opportunity.\n const reasons: string[] = [];\n if (!proven) reasons.push(`flow evidence is \"${confidence}\": no proven local read of this input into the sink call`);\n if (!input.runtimeParameter) reasons.push(input.runtimeParameterReason ?? 'input has no runtime parameter');\n if (sink.file !== undefined) reasons.push('sink is in an imported module: no local call-site evidence');\n if (sink.start === undefined) reasons.push('sink call could not be located in the source');\n // Only a receiver traced to a dependency ('import') or a genuine runtime global earns a rule.\n // 'inferred' is deliberately NOT enough: the package came from some OTHER import in the file, not\n // from the receiver, so `res.locals.db.query(x)` in a file that happens to import `pg` looks\n // identical to a real pool — and `res.locals.db` may be any app object. Such sinks stay in the\n // inventory for review; they just cannot compile a rule that blocks live traffic on a guess.\n if (sink.apiUnconfirmed) {\n reasons.push(`sink package \"${sink.package}\" is not a known ${sink.kind} provider: it does not establish a ${sink.kind} API (method name alone is not evidence)`);\n }\n if (sink.attribution !== 'import' && sink.attribution !== 'global') {\n reasons.push(sink.attribution === 'inferred'\n ? `sink package \"${sink.package}\" was inferred from the file's other imports, not from the receiver (${sink.kind}.${sink.op ?? '?'}): the receiver may be any app object`\n : `sink receiver could not be traced to a dependency (${sink.kind}.${sink.op ?? '?'} on an unresolved receiver): a rule here would be a guess`);\n }\n if (proven && argumentRole === 'unknown') reasons.push(`sink argument role is not modelled for ${sink.kind}.${sink.op ?? '?'}`);\n // A dynamic key or a spread in this sink's arguments means no coordinate can name the field that\n // actually reaches it — report the specific cause rather than a generic \"heuristic\".\n for (const l of sinkLimits) {\n reasons.push(l.kind === 'dynamic-key'\n ? `dynamic computed key reaches this sink (${l.detail}): the field cannot be named by a parameter`\n : `spread reaches this sink (${l.detail}): the specific field is not identifiable`);\n }\n // `!sink.apiUnconfirmed`: when the family was withheld because the PACKAGE does not establish this\n // API, the role is not what's wrong — role \"sql\" is normally blockable, and saying otherwise sends a\n // reviewer to look at the wrong thing. The package reason above already explains the refusal.\n if (proven && argumentRole && argumentRole !== 'unknown' && !family && !sink.apiUnconfirmed) {\n // e.g. a request value in a parameterized db `values` object: real reachability, but not a\n // pattern a generic blocking rule can express.\n reasons.push(`argument role \"${argumentRole}\" on a ${sink.kind} sink is not a blockable pattern on its own`);\n }\n flows.push({\n input: input.name,\n inputId: input.id,\n sink,\n confidence,\n line: sink.line,\n ...(argumentRole ? { argumentRole } : {}),\n ...(family ? { candidateFamily: family } : {}),\n ruleGeneratable: reasons.length === 0,\n ruleGeneratableReasons: reasons,\n });\n }\n for (const l of sinkLimits) allLimits.push(l);\n }\n return { flows, limitations: dedupeLimitations(allLimits) };\n}\n\nfunction dedupeLimitations(list: Limitation[]): Limitation[] {\n const seen = new Set<string>();\n return list.filter((l) => {\n const k = `${l.kind}:${l.detail}:${l.line}`;\n if (seen.has(k)) return false;\n seen.add(k);\n return true;\n });\n}\n\n/** Join two path segments, tolerating an empty base. */\nfunction join2(base: string, seg: string): string {\n return base ? `${base}.${seg}` : seg;\n}\n\n/**\n * Canonical form for comparing paths: index/array tokens are erased and empty segments collapsed, so\n * `tags[0].label`, `tags[].label` and `tags.label` all compare equal, while DISTINCT paths such as\n * `billing.email` and `shipping.email` stay distinct (the previous leaf-only comparison conflated them).\n */\nfunction normalizePath(path: string): string {\n return path\n .replace(/\\[\\d*\\]/g, '')\n .split('.')\n .filter(Boolean)\n .join('.');\n}\n\n/**\n * Calls belonging to the same fluent chain as `call` — the same logical operation. Walking UP stops at\n * anything that is not a continuation of the chain (an array literal, an argument position), which is\n * what keeps a sibling expression in the same statement from lending evidence.\n */\nfunction fluentChainCalls(call: any, ts: TsModule): any[] {\n let root = call;\n for (;;) {\n const p = root.parent;\n if (p && ts.isPropertyAccessExpression(p) && p.expression === root) { root = p; continue; }\n if (p && ts.isCallExpression(p) && p.expression === root) { root = p; continue; }\n if (p && (ts.isAwaitExpression(p) || ts.isParenthesizedExpression(p) || ts.isNonNullExpression(p)) && p.expression === root) { root = p; continue; }\n break;\n }\n const out: any[] = [];\n const collect = (n: any) => {\n if (!n) return;\n if (ts.isCallExpression(n) || ts.isNewExpression(n)) out.push(n);\n if (ts.isCallExpression(n) || ts.isPropertyAccessExpression(n) || ts.isAwaitExpression(n) || ts.isParenthesizedExpression(n) || ts.isNonNullExpression(n)) {\n collect(n.expression);\n }\n };\n collect(root);\n return out;\n}\n\n/**\n * The canonical PATHS of values genuinely read from a tainted source inside `node` — the evidence behind\n * a proven flow. Full paths, not leaf names: `data.shipping.email` yields `shipping.email`, so it can\n * never be mistaken for the distinct input `billing.email`. Array indices normalize to `[]`.\n * Property KEYS, member names and binding names are not reads.\n */\nfunction taintedReadPaths(node: any, ts: TsModule, rootPath: Map<string, Root>): Root[] {\n const out: Root[] = [];\n const seen = new Set<string>();\n const add = (r: Root) => {\n const key = `${r.space ?? '*'}:${r.path}`;\n if (!seen.has(key)) { seen.add(key); out.push(r); }\n };\n const visit = (n: any) => {\n if (!n) return;\n if (ts.isPropertyAccessExpression(n) || ts.isElementAccessExpression(n)) {\n const read = pathFromTainted(n, ts, rootPath);\n if (read !== undefined) { add(read); return; } // the inner nodes are the path, not separate reads\n }\n if (ts.isIdentifier(n) && rootPath.has(n.text) && isValueRead(n, ts)) {\n const r = rootPath.get(n.text)!;\n if (r.path) add({ path: normalizePath(r.path), space: r.space });\n }\n ts.forEachChild(n, visit);\n };\n visit(node);\n return out;\n}\n\n/**\n * Shapes that defeat parameter pinning, found in a sink call's arguments. Reporting these is the point:\n * \"we could not model this\" is far more useful to an operator than an endpoint that silently shows no\n * flow, and it is the queue for improving the extractor.\n * - `insert({ v: body[field] })` → the field is chosen at runtime; no coordinate can name it.\n * - `insert({ ...body })` → the whole payload reaches the sink; which field is unidentifiable.\n */\nfunction sinkArgumentLimitations(node: any, ts: TsModule, rootPath: Map<string, Root>): Limitation[] {\n const out: Limitation[] = [];\n const seen = new Set<string>();\n const add = (kind: Limitation['kind'], detail: string, n: any) => {\n const key = `${kind}:${detail}`;\n if (seen.has(key)) return;\n seen.add(key);\n out.push({ kind, detail, line: lineOf(n) });\n };\n const text = (n: any) => {\n try { return String(n.getText()).replace(/\\s+/g, ' ').slice(0, 120); } catch { return '<expression>'; }\n };\n const visit = (n: any) => {\n if (!n) return;\n // A computed member read off tainted data with a non-literal index.\n if (ts.isElementAccessExpression(n)) {\n const root = rootIdentifier(n.expression, ts);\n const arg = n.argumentExpression;\n if (root && rootPath.has(root) && arg && !ts.isStringLiteralLike(arg) && !ts.isNumericLiteral(arg)) {\n add('dynamic-key', text(n), n);\n }\n }\n // A spread of tainted data into the sink's argument.\n if ((ts.isSpreadAssignment?.(n) || ts.isSpreadElement(n)) && n.expression) {\n const root = rootIdentifier(n.expression, ts);\n if (root && rootPath.has(root)) add('spread-into-sink', text(n.parent ?? n), n);\n }\n ts.forEachChild(n, visit);\n };\n visit(node);\n return out;\n}\n\n/** Canonical path of a member/element access rooted in a tainted binding, or undefined if not tainted. */\nfunction pathFromTainted(node: any, ts: TsModule, rootPath: Map<string, Root>): Root | undefined {\n const segs: string[] = [];\n let cur = node;\n for (;;) {\n if (ts.isPropertyAccessExpression(cur)) { segs.unshift(cur.name.text); cur = cur.expression; continue; }\n if (ts.isElementAccessExpression(cur)) {\n const a = cur.argumentExpression;\n segs.unshift(a && ts.isStringLiteralLike(a) ? a.text : '[]');\n cur = cur.expression;\n continue;\n }\n if (ts.isNonNullExpression(cur) || ts.isParenthesizedExpression(cur) || ts.isAwaitExpression(cur)) { cur = cur.expression; continue; }\n break;\n }\n if (!cur || !ts.isIdentifier(cur)) return undefined;\n const base = rootPath.get(cur.text);\n if (base === undefined) return undefined;\n let space = base.space;\n // Drop a leading NAMESPACE segment (`req.body.webhookUrl` → `webhookUrl`). Input names — and the\n // runtime coordinates derived from them — are relative to their namespace (`post.webhookUrl`), so\n // leaving `body.` in the read path would fail to match the very inputs it came from. Without this,\n // the highest-value flows (`req.body.webhookUrl` → fetch, `req.body.command` → exec) never reach\n // proven.\n // The dropped segment is exactly what names the address space, so capture it before discarding it —\n // losing it is what made `req.query.id` and `req.body.id` the same read.\n if (base.path === '' && segs.length > 1 && REQ_SOURCES.includes(segs[0]!)) {\n space = spaceOfKey(segs[0]!) ?? space;\n segs.shift();\n }\n return { path: normalizePath([base.path, ...segs].filter(Boolean).join('.')), space };\n}\n","import type { Endpoint, Sink, TsModule } from './types.js';\nimport { hasExport, isFnLike, methodFromObjectArg, spanOf, unwindChain } from './ast.js';\nimport type { Bindings } from './bindings.js';\nimport { functionNameFromPath, ROUTE_REGISTER, routeFromChain, routeObject } from './routes.js';\nimport { withCoordinates } from './coordinates.js';\nimport { inputsFromHandler, inputsFromValidator } from './inputs.js';\nimport { sinksFrom, type SinkContext } from './sinks.js';\nimport { linkedFlows } from './flows.js';\n\nconst HTTP_METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']);\n\n// --- entry-point recognizers -----------------------------------------------\nexport function extractFromFile(sf: any, ts: TsModule, localSinks: Map<string, Sink[]>, bindings: Bindings, ctx: SinkContext): Omit<Endpoint, 'file'>[] {\n const out: Omit<Endpoint, 'file'>[] = [];\n const isServerActionsFile = fileHasUseServer(sf, ts);\n\n const visit = (node: any) => {\n if (ts.isVariableStatement(node) && hasExport(node, ts)) {\n for (const decl of node.declarationList.declarations) {\n // (1) TanStack Start: `export const NAME = createServerFn({method}).inputValidator(fn).handler(fn)`\n if (decl.initializer && ts.isCallExpression(decl.initializer)) {\n const chain = unwindChain(decl.initializer, ts);\n if (chain.baseName === 'createServerFn' && ts.isIdentifier(decl.name)) {\n const validatorCall = chain.calls['inputValidator'] ?? chain.calls['validator'];\n const inputs = withCoordinates(inputsFromValidator(validatorCall, ts, bindings), 'server-fn-data');\n const handlerFn = chain.calls['handler']?.arguments?.[0];\n const sinks = sinksFrom(handlerFn, ts, localSinks, bindings, ctx);\n const handlerBody = handlerFn && isFnLike(handlerFn, ts) ? handlerFn.body : undefined;\n const ep: Omit<Endpoint, 'file'> = {\n name: decl.name.text,\n entryKind: 'server-fn',\n method: methodFromObjectArg(chain.baseCall, ts),\n ...spanOf(decl),\n inputs,\n sinks,\n ...linkedFlows(handlerBody, handlerFn?.parameters, inputs, sinks, ts),\n };\n // Honesty marker: a validator EXISTS but couldn't be read — inputs are unknown, not \"none\".\n if (validatorCall && inputs.length === 0) ep.inputsResolved = false;\n out.push(ep);\n continue;\n }\n }\n // (2b) `export const POST = (req) => …` route handler, or a `'use server'` action arrow.\n if (ts.isIdentifier(decl.name) && decl.initializer && isFnLike(decl.initializer, ts)) {\n if (HTTP_METHODS.has(decl.name.text)) {\n out.push(handlerEntry(decl.name.text, decl.name.text, decl.initializer.parameters, decl.initializer.body, ts, localSinks, bindings, ctx, spanOf(decl)));\n } else if (isServerActionsFile) {\n out.push(handlerEntry(decl.name.text, 'server-action', decl.initializer.parameters, decl.initializer.body, ts, localSinks, bindings, ctx, spanOf(decl)));\n }\n }\n }\n }\n\n // (2a) Route handlers / server actions declared as functions.\n if (ts.isFunctionDeclaration(node) && node.name && hasExport(node, ts)) {\n if (HTTP_METHODS.has(node.name.text)) {\n out.push(handlerEntry(node.name.text, node.name.text, node.parameters, node.body, ts, localSinks, bindings, ctx, spanOf(node)));\n } else if (isServerActionsFile || hasUseServerDirective(node, ts)) {\n out.push(handlerEntry(node.name.text, 'server-action', node.parameters, node.body, ts, localSinks, bindings, ctx, spanOf(node)));\n }\n }\n\n // (2c) Deno / WinterCG function entry: `Deno.serve(handler)` or `serve(handler)` — Supabase Edge\n // Functions, Base44 backend functions, Deno workers. These platforms have no router and no route\n // file: one handler per module, invoked by the function's NAME, so the endpoint's identity comes\n // from the file location. Without this recognizer such a project maps to nothing at all.\n if (ts.isCallExpression(node)) {\n const c = node.expression;\n const denoServe = ts.isPropertyAccessExpression(c) && c.name.text === 'serve' &&\n ts.isIdentifier(c.expression) && c.expression.text === 'Deno';\n const bareServe = ts.isIdentifier(c) && c.text === 'serve';\n if (denoServe || bareServe) {\n const handler = node.arguments.find((a: any) => isFnLike(a, ts));\n if (handler) {\n out.push(handlerEntry(functionNameFromPath(ctx.file) ?? 'serve', 'edge-function', handler.parameters, handler.body, ts, localSinks, bindings, ctx, spanOf(node)));\n }\n }\n }\n\n if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {\n const mname = node.expression.name.text;\n // (3a) Route registrations: `app.post('/path', …, handler)` (Express/Fastify/Hono/Koa) and the\n // chained `router.route('/x').get(handler)` idiom (path lives on the inner `.route()` call).\n if (ROUTE_REGISTER.has(mname)) {\n const args = node.arguments;\n const first = args[0];\n const route = first && ts.isStringLiteralLike(first) ? first.text : routeFromChain(node.expression.expression, ts);\n const handler = args[args.length - 1];\n if (route !== undefined && handler && isFnLike(handler, ts)) {\n out.push(handlerEntry(route, 'route-registration', handler.parameters, handler.body, ts, localSinks, bindings, ctx, {\n // `use`/`all` register handlers but are not HTTP methods — leave method undefined.\n method: HTTP_METHODS.has(mname.toUpperCase()) ? mname.toUpperCase() : undefined,\n route,\n ...spanOf(node),\n }));\n }\n }\n // (3b) Fastify object form: `app.route({ method, url, handler })` — one endpoint per method.\n if (mname === 'route') {\n const arg = node.arguments[0];\n if (arg && ts.isObjectLiteralExpression(arg)) {\n const reg = routeObject(arg, ts);\n if (reg.url && reg.handler) {\n for (const m of reg.methods.length ? reg.methods : [undefined]) {\n out.push(handlerEntry(reg.url, 'route-registration', reg.handler.parameters, reg.handler.body, ts, localSinks, bindings, ctx, { method: m, route: reg.url, ...spanOf(node) }));\n }\n }\n }\n }\n }\n\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return out;\n}\n\n// Next server actions: a `'use server'` directive at the top of a module (whole file) or a function body.\nfunction fileHasUseServer(sf: any, ts: TsModule): boolean {\n const first = sf.statements?.[0];\n return Boolean(first && ts.isExpressionStatement(first) && ts.isStringLiteralLike(first.expression) && first.expression.text === 'use server');\n}\nfunction hasUseServerDirective(fn: any, ts: TsModule): boolean {\n const first = fn.body?.statements?.[0];\n return Boolean(first && ts.isExpressionStatement(first) && ts.isStringLiteralLike(first.expression) && first.expression.text === 'use server');\n}\n\nfunction handlerEntry(\n name: string,\n kindLabel: string,\n params: any,\n body: any,\n ts: TsModule,\n localSinks: Map<string, Sink[]>,\n bindings: Bindings,\n ctx: SinkContext,\n extra: { method?: string; route?: string; line?: number; start?: number; end?: number } = {},\n): Omit<Endpoint, 'file'> {\n const entryKind = kindLabel === 'route-registration' || kindLabel === 'server-action' || kindLabel === 'edge-function'\n ? kindLabel\n : 'route-handler';\n // A server action receives its payload as the first argument; a route handler receives a Request.\n const payloadStyle = kindLabel === 'server-action';\n const inputs = inputsFromHandler(params, body, ts, bindings, {\n payloadParam: payloadStyle,\n validatorSource: payloadStyle ? 'server-fn-data' : 'json-body',\n });\n const sinks = sinksFrom({ body, parameters: params, isSyntheticBody: true }, ts, localSinks, bindings, ctx);\n return {\n name,\n entryKind,\n method: extra.method ?? (HTTP_METHODS.has(name) ? name : undefined),\n route: extra.route,\n line: extra.line,\n start: extra.start,\n end: extra.end,\n inputs,\n sinks,\n ...linkedFlows(body, params, inputs, sinks, ts),\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ImportedPackage, ImportSite, TsModule } from './types.js';\nimport { npmPackageOf } from './bindings.js';\nimport { recognizedSinkKinds } from './sinks.js';\n\n// The app's IMPORT inventory — \"which packages does this code pull in\", answered for every source file,\n// not just the ones that hold an entry point.\n//\n// Why it is separate from sink collection: a sink is only recorded for the few API families the extractor\n// models, and only inside a recognized handler. That makes sinks the wrong instrument for the question a\n// vulnerability correlator actually asks — \"does this app use package P at all?\" — because P may be used\n// heavily through an API we have no recognizer for, or from a file with no entry point in it. Answering\n// that question from the sink list yields a confident \"no\", which is the worst possible wrong answer:\n// it closes a real vulnerability as unreachable. So imports are collected on their own terms.\n//\n// Two fidelities, deliberately. Files with an entry-point signal are fully parsed anyway, so their imports\n// come from the AST (specifiers AND bound names). The rest — most of a project — are only scanned for\n// module specifiers, which is far cheaper than building a syntax tree for every file and is the half that\n// matters for correlation. The mixed fidelity is reported per package as `namesComplete` rather than\n// smoothed over.\n\n/** A `compilerOptions.paths` entry: `\"@/*\"` is a prefix, `\"foo\"` matches only the specifier `foo`. */\nexport interface PathAlias {\n prefix: string;\n wildcard: boolean;\n}\n\n/** One import edge as found in a single file. */\nexport interface RawImport {\n /** Module specifier exactly as written (`node:fs`, `lodash/merge`, `./db`). */\n specifier: string;\n /** Bound names: real named bindings, plus the markers `default`, `*`, `require`, `import()`. */\n names: string[];\n /** 1-based line of the import. */\n line?: number;\n}\n\n/** Cap per package: enough to point a reviewer at the usage, bounded so a big app can't bloat the map. */\nconst MAX_SITES = 5;\n\n/**\n * A bare specifier that is a legal npm package name. Bare does NOT mean \"package\": every AI-built app\n * configures a path alias (`@/components` → `./src/components`), and those are the app's OWN code. Letting\n * them into the inventory is not cosmetic — each one lands in the \"no recognized sink family\" bucket and\n * inflates the count a reviewer reads as unanalysable dependencies.\n */\nconst NPM_NAME = /^(?:@[^/@\\s~][^/@\\s]*\\/)?[^/@\\s.~][^/@\\s]*$/;\nfunction isNpmPackageName(pkg: string): boolean {\n return pkg.startsWith('node:') || NPM_NAME.test(pkg);\n}\n\n/**\n * Path-alias prefixes declared in `tsconfig.json` / `jsconfig.json` (`compilerOptions.paths`). Best-effort\n * and deliberately shallow: `extends` chains and bundler-config aliases (a `vite.config.ts` `resolve.alias`\n * is code, not data) are not followed, so the name check above remains the backstop. Reads tolerantly —\n * these files routinely carry comments and trailing commas, which `JSON.parse` rejects.\n */\nexport function readPathAliases(cwd: string): PathAlias[] {\n const aliases: PathAlias[] = [];\n for (const name of ['tsconfig.json', 'jsconfig.json']) {\n let paths: Record<string, unknown> | undefined;\n try {\n const raw = readFileSync(join(cwd, name), 'utf8');\n const parsed = JSON.parse(stripJsonComments(raw)) as { compilerOptions?: { paths?: Record<string, unknown> } };\n paths = parsed.compilerOptions?.paths;\n } catch {\n continue; // absent or unparseable: fall back to the name check\n }\n for (const key of Object.keys(paths ?? {})) {\n if (key.startsWith('.')) continue; // a relative alias is already excluded as a non-package\n // The wildcard has to be carried, not flattened into a prefix: an alias `\"foo\"` covers the\n // specifier `foo` and nothing else, so prefix-matching it would also swallow the real npm\n // package `foobar`. Only `\"foo/*\"` is a prefix.\n if (key.endsWith('*')) aliases.push({ prefix: key.slice(0, -1), wildcard: true });\n else aliases.push({ prefix: key, wildcard: false });\n }\n }\n return aliases;\n}\n\nfunction stripJsonComments(text: string): string {\n let out = '';\n let inString = false;\n let quote = '';\n for (let i = 0; i < text.length; i++) {\n const c = text[i];\n const next = text[i + 1];\n if (inString) {\n out += c;\n if (c === '\\\\') { out += next ?? ''; i++; continue; }\n if (c === quote) inString = false;\n continue;\n }\n if (c === '\"' || c === \"'\") { inString = true; quote = c; out += c; continue; }\n if (c === '/' && next === '/') { while (i < text.length && text[i] !== '\\n') i++; out += '\\n'; continue; }\n if (c === '/' && next === '*') { i += 2; while (i < text.length && !(text[i] === '*' && text[i + 1] === '/')) i++; i++; continue; }\n out += c;\n }\n return out.replace(/,(\\s*[}\\]])/g, '$1'); // trailing commas\n}\n\n/**\n * Import edges from a parsed source file: `import`/`export … from`, `require(…)` and dynamic `import(…)`.\n * Relative specifiers are included here and filtered later — the caller decides what counts as a package,\n * and keeping the raw edge makes this function reusable and easy to test.\n */\nexport function collectFileImports(sf: any, ts: TsModule): RawImport[] {\n const found: RawImport[] = [];\n const lineOf = (node: any): number | undefined => {\n try {\n return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;\n } catch {\n return undefined;\n }\n };\n\n const visit = (node: any) => {\n // import x, { a as b }, * as ns from 'mod' / import 'mod'\n if (ts.isImportDeclaration(node) && ts.isStringLiteralLike(node.moduleSpecifier)) {\n const names: string[] = [];\n const clause = node.importClause;\n if (clause?.name) names.push('default');\n const nb = clause?.namedBindings;\n if (nb) {\n if (ts.isNamespaceImport(nb)) names.push('*');\n else if (ts.isNamedImports(nb)) {\n // The EXPORTED name is what an advisory names; `import { merge as m }` is still `merge`.\n for (const el of nb.elements) names.push((el.propertyName ?? el.name).text);\n }\n }\n found.push({ specifier: node.moduleSpecifier.text, names, line: lineOf(node) });\n }\n // export { a } from 'mod' — an import edge that re-exports; the package is still pulled in.\n if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteralLike(node.moduleSpecifier)) {\n const names: string[] = [];\n const ec = node.exportClause;\n if (ec && ts.isNamedExports(ec)) for (const el of ec.elements) names.push((el.propertyName ?? el.name).text);\n else if (ec && ts.isNamespaceExport(ec)) names.push('*');\n else names.push('*'); // export * from 'mod'\n found.push({ specifier: node.moduleSpecifier.text, names, line: lineOf(node) });\n }\n // require('mod') and import('mod') — the call form carries no binding info at the call site, so the\n // marker name records HOW it was imported instead of inventing a binding.\n if (ts.isCallExpression(node)) {\n const arg = node.arguments[0];\n const isRequire = ts.isIdentifier(node.expression) && node.expression.text === 'require';\n const isDynamic = node.expression.kind === ts.SyntaxKind.ImportKeyword;\n if ((isRequire || isDynamic) && arg && ts.isStringLiteralLike(arg)) {\n found.push({ specifier: arg.text, names: [isRequire ? 'require' : 'import()'], line: lineOf(node) });\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return found;\n}\n\n/**\n * Module specifiers from raw text, without building a syntax tree — TypeScript's own pre-processor, the\n * same scan the compiler uses to discover a file's dependencies. Token-accurate (a specifier inside a\n * comment or string is not reported), and cheap enough to run over every file in a project.\n * Names are not recoverable this way; callers mark the result as name-incomplete.\n *\n * Returns **null** when the scan itself failed. That is deliberately distinct from an empty array: a file\n * we could not scan is not a file that imports nothing, and collapsing the two is what would let a server\n * conclude \"package absent\" from a gap in our own analysis.\n */\nexport function scanFileImports(text: string, ts: TsModule): RawImport[] | null {\n let refs: Array<{ fileName: string; pos: number }>;\n try {\n const pre = ts.preProcessFile(text, /* readImportFiles */ true, /* detectJavaScriptImports */ true);\n refs = pre.importedFiles ?? [];\n } catch {\n return null; // fail-open for the map, but the caller must record that the inventory is now partial\n }\n if (refs.length === 0) return [];\n const lineStarts = lineStartOffsets(text);\n return refs.map((r) => ({ specifier: r.fileName, names: [], line: lineAt(lineStarts, r.pos) }));\n}\n\n/**\n * Count imports whose module cannot be determined statically. Two shapes, one number — both feed\n * `coverage.importCoverageGaps.unresolvableImports`:\n *\n * 1. a COMPUTED specifier — `require(REGISTRY[kind])`, `import(name)`, `require(\"a\" + b)`\n * 2. an ESCAPED loader — `const r = require`, `(require)(x)`, `module.exports = require`\n *\n * The second is reported at the escape rather than at the later call: once the loader is behind another\n * name, what it loads is unknowable here whether or not the argument is a literal.\n *\n * `scanFileImports` cannot see these. It reads `ts.preProcessFile(...).importedFiles`, which reports\n * resolved literal specifiers only — a computed specifier produces no entry at all, so the import is\n * not merely unrecorded, it is invisible. That matters because the inventory's contract says a\n * package's ABSENCE is evidence when `importsComplete` is true, and `require(REGISTRY[kind])` makes\n * absence unprovable while leaving every read-and-scan check satisfied.\n *\n * Tokenised rather than parsed: this runs on files deliberately kept out of the AST pass, so it must\n * stay at scanner cost. Tokenising (rather than a regex) is what keeps `// require(x)` in a comment\n * and `\"require(y)\"` in a string from counting — a text match would clear the completeness flag on\n * prose about `require`, which trades a false negative for a permanent false alarm.\n */\nexport function countUnresolvableImports(text: string, ts: TsModule): number {\n let scanner: any;\n try {\n scanner = ts.createScanner(ts.ScriptTarget.Latest, /* skipTrivia */ true, undefined, text);\n } catch {\n return 0; // fail-open: the caller already treats an unscannable file as incomplete\n }\n\n // `require` does NOT arrive as an identifier: TypeScript scans it as the contextual `RequireKeyword`\n // (it appears in `import x = require(…)`). Keying on the token TEXT with a kind allowlist covers both\n // spellings, and survives a TS version that classifies it differently — which is worth the small\n // looseness here, because the failure mode of a missed kind is a silent zero count, i.e. exactly the\n // false \"complete\" this function exists to prevent.\n const CALLEE_KINDS = new Set<number>([\n ts.SyntaxKind.Identifier,\n ts.SyntaxKind.RequireKeyword,\n ts.SyntaxKind.ImportKeyword,\n ].filter((k) => k !== undefined) as number[]);\n\n // Three tokens of history, because one is not enough to identify the callee. The token that decides\n // whether this is CommonJS `require` sits on a different side of the name in each form:\n //\n // require(x) callee is the previous token\n // require?.(x) `?.` sits BETWEEN the name and `(` — the callee is two back\n // loader.require(x) an app method that merely shares the name — `.` sits BEFORE the callee\n // loader.require?.(x) both at once, so the qualifier is three back\n //\n // Getting either direction wrong is a real failure, and they fail in opposite ways: missing the\n // optional form leaves `importsComplete` true over an unresolvable import, while counting a member\n // method makes it permanently false for an app that named a method `require` — which trains a reader\n // to ignore the field. Hence a qualifier check rather than a looser name match.\n const DOT_KINDS = new Set<number>([ts.SyntaxKind.DotToken, ts.SyntaxKind.QuestionDotToken]\n .filter((k) => k !== undefined) as number[]);\n\n interface Token { kind: number | undefined; text: string }\n const EMPTY: Token = { kind: undefined, text: '' };\n // Most recent first: history[0] is the token before the current one.\n const history: [Token, Token, Token] = [EMPTY, EMPTY, EMPTY];\n const remember = (kind: number, text: string): void => {\n history[2] = history[1];\n history[1] = history[0];\n history[0] = { kind, text };\n };\n\n /**\n * Did the token just before `next` leave a bare `require` unresolvable?\n *\n * Deliberately asked about `require` only. `import` is a keyword that legitimately appears without a\n * following paren in every ESM file (`import qs from \"qs\"`, `import.meta.url`), so the same rule there\n * would report a gap for ordinary static imports — the exact always-false flag the member-method guard\n * exists to prevent.\n */\n const escapedLoaderReference = (next: number): boolean => {\n const callee = history[0];\n const qualifier = history[1];\n\n if (callee.kind === undefined || !CALLEE_KINDS.has(callee.kind) || callee.text !== 'require') return false;\n // Someone's method named `require` — not the loader.\n if (qualifier.kind !== undefined && DOT_KINDS.has(qualifier.kind)) return false;\n\n // Called in place (`require(…)` / `require?.(…)`) is the resolvable form the rest of this function\n // judges, and `require.resolve` / `require.cache` reach a property of the loader without loading a\n // module at all. Anything else means the loader itself became a value.\n return next !== ts.SyntaxKind.OpenParenToken\n && next !== ts.SyntaxKind.QuestionDotToken\n && next !== ts.SyntaxKind.DotToken;\n };\n\n let count = 0;\n\n try {\n for (let token = scanner.scan(); token !== ts.SyntaxKind.EndOfFileToken; token = scanner.scan()) {\n const text = scanner.getTokenText();\n\n // `require` used as a VALUE rather than called in place: `const r = require`, `(require)(x)`,\n // `module.exports = require`. Once the loader is behind another name, resolving what it loads\n // needs dataflow this scan does not do — so the honest answer is that the inventory has a gap,\n // and the conservative one is the same answer. Counted at the ESCAPE, not at the later call:\n // whatever `r(…)` loads is unknowable from here, literal argument or not.\n if (escapedLoaderReference(token)) count++;\n\n if (token !== ts.SyntaxKind.OpenParenToken) {\n remember(token, text);\n continue;\n }\n\n // `?.` immediately before the paren shifts both the callee and its qualifier one place back.\n const optionalCall = history[0].kind === ts.SyntaxKind.QuestionDotToken;\n const callee = optionalCall ? history[1] : history[0];\n const qualifier = optionalCall ? history[2] : history[1];\n\n const isRequireCall = callee.kind !== undefined\n && CALLEE_KINDS.has(callee.kind)\n && (callee.text === 'require' || callee.text === 'import')\n // A dot before the name means it is a property of something else, so this is that object's\n // method and says nothing about module loading.\n && !(qualifier.kind !== undefined && DOT_KINDS.has(qualifier.kind));\n\n if (!isRequireCall) {\n remember(token, text);\n continue;\n }\n\n remember(token, text);\n\n const argument = scanner.scan();\n const argumentText = scanner.getTokenText();\n remember(argument, argumentText);\n\n const isLiteral = argument === ts.SyntaxKind.StringLiteral\n || argument === ts.SyntaxKind.NoSubstitutionTemplateLiteral;\n\n if (!isLiteral) {\n // A template WITH substitutions (`require(\\`./\\${name}\\`)`) lands here too, correctly: its\n // value is not knowable statically either.\n count++;\n continue;\n }\n\n // Starting with a literal is not the same as BEING one: `require(\"node-\" + pkg)` opens with a\n // string and is still computed. The literal is the whole specifier only if the argument ends\n // right here — a `)`, or a `,` for `import(\"./m\", { with: … })`, where the literal is complete\n // and only import attributes follow. Anything else continues the expression.\n const following = scanner.scan();\n remember(following, scanner.getTokenText());\n\n const argumentEnded = following === ts.SyntaxKind.CloseParenToken\n || following === ts.SyntaxKind.CommaToken;\n\n if (!argumentEnded) count++;\n }\n\n // The loop exits on EOF without processing it, so a file ENDING in a bare `require`\n // (`module.exports = require`) would otherwise escape unnoticed.\n if (escapedLoaderReference(ts.SyntaxKind.EndOfFileToken)) count++;\n } catch {\n return count; // whatever was counted before the scanner gave up still clears the flag\n }\n\n return count;\n}\n\n/**\n * Aggregates per-file import edges into the per-package inventory. Order-independent: the output is\n * sorted, so two runs over the same tree produce byte-identical documents.\n */\nexport function createImportInventory(aliases: PathAlias[] = []) {\n interface Acc {\n specifiers: Set<string>;\n names: Set<string>;\n namesComplete: boolean;\n sites: ImportSite[];\n siteCount: number;\n }\n const byPackage = new Map<string, Acc>();\n\n return {\n /** @param parsed whether these edges came from a full parse (names are trustworthy) or the scan. */\n add(relFile: string, edges: RawImport[], parsed: boolean): void {\n for (const edge of edges) {\n const aliased = aliases.some((a) => (a.wildcard ? edge.specifier.startsWith(a.prefix) : edge.specifier === a.prefix));\n if (aliased) continue;\n const pkg = npmPackageOf(edge.specifier);\n if (!pkg) continue; // relative/absolute path: app code, not a dependency\n if (!isNpmPackageName(pkg)) continue; // an unaliased-but-bare path (`@/x`, `~/lib`)\n let acc = byPackage.get(pkg);\n if (!acc) {\n acc = { specifiers: new Set(), names: new Set(), namesComplete: true, sites: [], siteCount: 0 };\n byPackage.set(pkg, acc);\n }\n acc.specifiers.add(edge.specifier);\n for (const n of edge.names) acc.names.add(n);\n // One unparsed site makes the whole package's name set a subset — say so rather than imply\n // completeness from the names that happen to be present.\n if (!parsed) acc.namesComplete = false;\n acc.siteCount++;\n if (acc.sites.length < MAX_SITES) acc.sites.push({ file: relFile, line: edge.line });\n }\n },\n\n list(): ImportedPackage[] {\n return [...byPackage.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([pkg, acc]) => {\n const names = [...acc.names].sort();\n const entry: ImportedPackage = {\n package: pkg,\n specifiers: [...acc.specifiers].sort(),\n namesComplete: acc.namesComplete,\n sites: acc.sites,\n siteCount: acc.siteCount,\n recognizedSinkKinds: recognizedSinkKinds(pkg),\n };\n if (names.length > 0) entry.names = names;\n return entry;\n });\n },\n };\n}\n\nfunction lineStartOffsets(text: string): number[] {\n const starts = [0];\n for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) === 10) starts.push(i + 1);\n return starts;\n}\n\n/** 1-based line containing `pos`, by binary search over the line starts. */\nfunction lineAt(starts: number[], pos: number): number {\n let lo = 0;\n let hi = starts.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if ((starts[mid] ?? 0) <= pos) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1;\n}\n","import type { ApiInvocation, InvocationResolution, TsModule } from './types.js';\nimport { isShadowedByEnclosingBinding, rootIdentifier, spanOf } from './ast.js';\nimport { npmPackageOf, type Bindings } from './bindings.js';\nimport type { ModuleGraph } from './sinks.js';\n\n// Which dependency APIs the app actually CALLS — a different question from the sink analysis, and a much\n// cheaper one.\n//\n// A sink answers \"can request input reach a dangerous operation\". That is only askable for the handful of\n// API families the extractor models, which measured out at ~3.6% of real advisories. This answers \"is this\n// package's API invoked at all\", which is askable for every package and is the whole answer for an advisory\n// whose precondition is *calling* the vulnerable function rather than feeding it untrusted input.\n//\n// The discipline is the sink discipline, deliberately: a receiver we cannot trace to a dependency is not an\n// invocation of that dependency, no matter how suggestive the method name. `inferred` attribution — the\n// package guessed from another import in the same file — does not qualify at all here, because unlike a\n// sink there is no second signal (an argument role, a dangerous operation) to corroborate it.\n//\n// A record has two halves — the package and the API NAME — and tracing the value only establishes the first.\n// A name the APP chose is not part of the package's surface however faithfully the value traces: `loadConfig`\n// (a local function re-exported from a helper module) and `log` (`const log = createLogger()`) both trace to\n// a real dependency, and neither is an API that dependency has. Reporting one is worse than reporting\n// nothing: a consumer asking \"is the vulnerable function called\" gets a name that appears in no advisory,\n// while the call that IS in the advisory's surface goes unmentioned. So a name is reported only where it came\n// from the package itself, and calls we cannot name are counted, not invented.\n//\n// PARTIAL BY CONSTRUCTION, and that is not a parsing budget problem. Parsing every file would raise recall,\n// but dynamic property access (`client[method]()`), dynamic `import()`/`require()` with a computed\n// specifier, reflection, aliases we do not follow, generated code and syntax we cannot parse all remain\n// invisible. So absence here NEVER licenses \"the vulnerable API is not called\"; the document says so in\n// `coverage.apiInventoryLimitations` rather than carrying a boolean a consumer could misread.\n\n/** Sites kept per distinct invocation, so a hot API cannot dominate the document. */\nconst MAX_SITES = 3;\n\nexport interface InvocationContext {\n /** Absolute path of the file being analysed, for resolving relative re-exports. */\n file: string;\n /** The same file, repo-relative — part of the record's identity, so it must not vary by machine. */\n owner: string;\n graph: ModuleGraph;\n}\n\n/**\n * How the call expressions in a file classified. Four buckets rather than resolved-vs-not, because\n * \"resolved / everything else\" measures the APP, not the resolver: a codebase full of local helpers would\n * score badly through no fault of ours, and widening the parse would *lower* the number by finding more\n * local calls — precisely backwards for a metric meant to justify widening the parse.\n *\n * total every call/new expression seen — workload scale\n * dependency traced to a package AND nameable: exactly what the inventory records\n * local the callee is a known local binding or an enclosing parameter — correctly not a dependency\n * ambiguous a receiver we could not classify either way, a computed/dynamic callee, or a value that\n * traces to a package under a name the app chose (nothing to record — see `named` below)\n *\n * Resolver quality is `dependency / (dependency + ambiguous)`. `local` belongs in neither term: excluding a\n * local helper is a correct answer, not a miss.\n */\nexport interface CallCounts {\n total: number;\n dependency: number;\n local: number;\n ambiguous: number;\n}\n\n/** A value traced to a package, and how strong that trace is. */\ninterface Traced {\n pkg: string;\n specifier: string;\n resolution: InvocationResolution;\n /** Whether the name this value is known by here is the PACKAGE's own name for it. */\n named: boolean;\n /** The package's own name, when an intermediate module renamed the binding on import. */\n apiName?: string;\n}\n\n/** Collect resolved dependency calls from one parsed file, with the call classification alongside. */\nexport function collectInvocations(\n sf: any,\n ts: TsModule,\n bindings: Bindings,\n ctx: InvocationContext,\n): { invocations: ApiInvocation[]; counts: CallCounts } {\n const found: ApiInvocation[] = [];\n const counts: CallCounts = { total: 0, dependency: 0, local: 0, ambiguous: 0 };\n\n /** A name we can positively account for as app-local: declared in-file, or an enclosing parameter. */\n const isLocalName = (name: string, node: any): boolean =>\n bindings.locals.has(name) || isShadowedByEnclosingBinding(node, name, ts);\n\n const lineOf = (node: any): number | undefined => {\n try {\n return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;\n } catch {\n return undefined;\n }\n };\n\n /**\n * The package a local name traces to, and how — including one hop for a re-exported dependency value.\n *\n * `named` answers the second question a record needs: is this name the PACKAGE's, or the app's? It is\n * true only for a binding that came straight out of the package — an import/require here, or a\n * pass-through re-export from a local module. A value the app derived (`const log = createLogger()`, or a\n * local function whose return value happens to root in the package) carries a name the app invented, so\n * `named` is false and there is no API to report even though the package is certain. `apiName` carries the\n * package's own name for a pass-through, since an intermediate module may have renamed it on import.\n */\n const traceRoot = (root: string): Traced | null => {\n const specifier = bindings.resolve(root);\n if (specifier === undefined) return null;\n\n const direct = npmPackageOf(specifier);\n if (direct !== undefined) {\n // `direct` vs `factory` is already recorded by the bindings; default to direct when unknown so a\n // missing origin cannot silently upgrade a weaker claim.\n const resolution = bindings.originOf(root) ?? 'direct';\n return { pkg: direct, specifier, resolution, named: resolution === 'direct' };\n }\n\n // A relative specifier: the value may still be a dependency re-exported from a local module\n // (`export const db = createClient(...)` in lib/db.ts — the layout generated apps actually use).\n const exportName = bindings.exportNameOf(root) ?? root;\n const viaModule = ctx.graph.importedBinding(ctx.file, specifier, exportName);\n if (viaModule !== undefined) {\n return {\n pkg: viaModule.package,\n specifier,\n resolution: 'reexport',\n named: viaModule.origin === 'direct',\n apiName: viaModule.name,\n };\n }\n\n return null;\n };\n\n const push = (\n traced: Traced,\n api: string,\n receiver: string | undefined,\n kind: ApiInvocation['kind'],\n node: any,\n ) => {\n const span = spanOf(node);\n found.push({\n package: traced.pkg,\n specifiers: [traced.specifier],\n api,\n ...(receiver !== undefined ? { receiver } : {}),\n symbol: receiver !== undefined ? `${receiver}.${api}` : api,\n kind,\n // Only ever `import`: a global has no package to correlate against, and an inferred package is not\n // evidence about the value being called.\n attribution: 'import',\n resolution: traced.resolution,\n callCount: 1,\n sites: [{ file: ctx.owner, line: lineOf(node), start: span.start, end: span.end }],\n });\n };\n\n const visit = (node: any) => {\n if (ts.isCallExpression(node) || ts.isNewExpression(node)) {\n const callee = node.expression;\n counts.total++;\n\n if (ts.isIdentifier(callee)) {\n // `merge(a, b)` / `new Pool()` — the callee itself is the imported binding.\n const traced = traceRoot(callee.text);\n if (traced?.named) {\n // The package's own name for the binding: from the target module for a pass-through re-export,\n // otherwise this file's (`import { saveOrder as write }` → `saveOrder`).\n const api = traced.apiName ?? bindings.exportNameOf(callee.text) ?? callee.text;\n push(traced, api, undefined, ts.isNewExpression(node) ? 'construct' : 'call', node);\n counts.dependency++;\n } else if (traced) {\n // Traced to a package, under a name the app chose — `loadConfig()` from a helper module, or a\n // factory result called directly. The only name available is one the package does not export, so\n // there is nothing to record. Counted AMBIGUOUS rather than local or dependency: we failed to\n // name an API here, and filing that as either a correct exclusion or a recorded call would hide\n // the miss. (The real call is recorded where it is written — in the module that makes it.)\n counts.ambiguous++;\n } else if (isLocalName(callee.text, node)) {\n counts.local++;\n } else {\n counts.ambiguous++;\n }\n } else if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.name)) {\n // `pool.query(sql)` / `helper.exec(cmd)` — resolve the RECEIVER, never the method name. A\n // dangerous-looking method on an untraceable object is exactly the lookalike the corpus exists for.\n const root = rootIdentifier(callee.expression, ts);\n const traced = root !== undefined ? traceRoot(root) : null;\n if (traced && root !== undefined) {\n counts.dependency++;\n // A receiver name is only reported when the package itself supplies that name — a NAMED member\n // binding (`import { promises as fsp } from 'node:fs'` → `promises`). Everything else is the\n // app's own word for a value: `pool` re-exported from `./lib`, `Student` returned by\n // `sequelize.define()`, and — the quiet one — `JSON5` in `const JSON5 = require('json5')`, where\n // the module object's local name is pure convention. Reporting any of them makes `symbol` a\n // string no advisory contains: `JSON5.parse` where the advisory says `parse`.\n const receiver = traced.resolution === 'direct' && bindings.isPackageMember(root)\n ? bindings.exportNameOf(root) ?? root\n : undefined;\n push(traced, callee.name.text, receiver, 'member', node);\n } else if (root !== undefined && ts.isIdentifier(callee.expression) && isLocalName(root, node)) {\n // A method called DIRECTLY on a local binding or a handler parameter — `res.json()`,\n // `shape.build()`. Declining to attribute that to a package is a correct answer.\n counts.local++;\n } else {\n // Anything deeper is ambiguous even when the ROOT is local: in `res.locals.db.query()` the value\n // being called is whatever was stashed on `res.locals`, not the parameter itself, and a database\n // client is exactly what apps put there. Filing it as \"local\" would hide a real miss.\n counts.ambiguous++;\n }\n } else {\n counts.ambiguous++; // computed callee, IIFE, dynamic import — see the limitations note\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n\n return { invocations: found, counts };\n}\n\n/**\n * Aggregate invocations across files.\n *\n * Keyed by package + symbol + kind + resolution, so two call sites with DIFFERENT evidence stay separate\n * entries rather than being merged under whichever was seen first — the strength of the claim is part of\n * the record, not a detail to round off.\n */\nexport function createInvocationInventory() {\n const byKey = new Map<string, ApiInvocation>();\n\n return {\n add(invocations: ApiInvocation[]): void {\n for (const invocation of invocations) {\n const key = `${invocation.package}|${invocation.symbol}|${invocation.kind}|${invocation.resolution}`;\n const existing = byKey.get(key);\n if (existing === undefined) {\n byKey.set(key, { ...invocation });\n continue;\n }\n existing.callCount += invocation.callCount;\n for (const specifier of invocation.specifiers) {\n if (!existing.specifiers.includes(specifier)) existing.specifiers.push(specifier);\n }\n if (existing.sites.length < MAX_SITES) existing.sites.push(...invocation.sites.slice(0, MAX_SITES - existing.sites.length));\n }\n },\n\n list(): ApiInvocation[] {\n return [...byKey.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([, invocation]) => ({ ...invocation, specifiers: [...invocation.specifiers].sort() }));\n },\n };\n}\n","import { loadTypeScript } from './ts-loader.js';\nimport { extractInputMap, type ExtractOptions } from './extract.js';\nimport type { SiteInputMap } from './types.js';\n\nexport type { SiteInputMap, Endpoint, InputField, Sink, Flow, Coverage } from './types.js';\nexport type { ExtractOptions } from './extract.js';\n\n/**\n * Build the app's input-flow (\"attack surface\") map at build time. Resolves the target app's own\n * TypeScript to parse the source; returns { map: null, error } (never throws) when TS can't be\n * resolved, so the CLI can degrade with a clear message.\n */\nexport async function buildInputMap(\n cwd: string,\n options: ExtractOptions = {},\n): Promise<{ map: SiteInputMap | null; error?: string }> {\n const ts = await loadTypeScript(cwd);\n if (!ts) {\n return {\n map: null,\n error:\n 'Could not resolve a TypeScript compiler to parse the app. `map` uses your project’s own ' +\n '`typescript` (already a devDependency of a TypeScript app) — install it and retry.',\n };\n }\n const map = await extractInputMap(cwd, ts, options);\n return { map };\n}\n","import { readFileSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nimport type { PackageManager } from './guide.js';\nimport { runProtect, runVerify } from './protect/install/index.js';\nimport type { ProtectResult, VerifyReport } from './protect/install/types.js';\n\nconst SCAN_COMMAND = 'patchstack-connect scan';\nconst MARK_BUILD_COMMAND = 'patchstack-connect mark-build';\n\ninterface PackageJson {\n scripts?: Record<string, string>;\n [key: string]: unknown;\n}\n\nexport interface WireBuildScriptsResult {\n changed: boolean;\n strategy: 'build-chain' | 'lifecycle-hooks' | 'postinstall-only';\n detail: string;\n}\n\nexport interface SetupProtectionResult {\n install: ProtectResult;\n verification: VerifyReport;\n}\n\n/**\n * Install the runtime guard after setup has provisioned a site UUID, then inspect\n * the resulting seam. Verification is deliberately separate from the installer's\n * best-effort result: an adapter can scaffold files but still need a manual merge\n * when an existing framework seam cannot safely be overwritten.\n */\nexport function setupProtection(cwd: string): SetupProtectionResult {\n const install = runProtect(cwd);\n const verification = runVerify(cwd);\n return { install, verification };\n}\n\n/** Add `command` after an existing lifecycle hook without duplicating it. */\nfunction appendHook(existing: string | undefined, command: string): string {\n if (existing === undefined || existing.trim().length === 0) {\n return command;\n }\n if (existing.includes(command)) {\n return existing;\n }\n return `${existing} && ${command}`;\n}\n\n/**\n * Wire a scan after dependency installs and around the project's build without\n * invoking a shell. Bun skips npm-style pre/post build hooks, so Bun projects get\n * a direct build chain; other package managers get lifecycle hooks. Existing\n * commands are preserved and the operation is idempotent.\n */\nexport function wireBuildScripts(\n cwd: string,\n packageManager: PackageManager,\n): WireBuildScriptsResult {\n const target = path.join(cwd, 'package.json');\n const raw = readFileSync(target, 'utf8');\n const pkg = JSON.parse(raw) as PackageJson;\n const scripts = pkg.scripts ?? {};\n const build = scripts.build;\n const postinstall = appendHook(scripts.postinstall, SCAN_COMMAND);\n\n if (build === undefined || build.trim().length === 0) {\n if (postinstall === scripts.postinstall) {\n return {\n changed: false,\n strategy: 'postinstall-only',\n detail: 'dependency-install scan already wired; no build script to integrate.',\n };\n }\n scripts.postinstall = postinstall;\n } else if (packageManager === 'bun') {\n let nextBuild = build;\n if (!nextBuild.includes(SCAN_COMMAND)) {\n nextBuild = `${SCAN_COMMAND} && ${nextBuild}`;\n }\n if (!nextBuild.includes(MARK_BUILD_COMMAND)) {\n nextBuild = `${nextBuild} && ${MARK_BUILD_COMMAND}`;\n }\n if (nextBuild === build && postinstall === scripts.postinstall) {\n return {\n changed: false,\n strategy: 'build-chain',\n detail: 'dependency-install scan and build chain already wired.',\n };\n }\n scripts.postinstall = postinstall;\n scripts.build = nextBuild;\n } else {\n const prebuild = appendHook(scripts.prebuild, SCAN_COMMAND);\n const postbuild = appendHook(scripts.postbuild, MARK_BUILD_COMMAND);\n if (\n prebuild === scripts.prebuild &&\n postbuild === scripts.postbuild &&\n postinstall === scripts.postinstall\n ) {\n return {\n changed: false,\n strategy: 'lifecycle-hooks',\n detail: 'dependency-install, prebuild, and postbuild hooks are already wired.',\n };\n }\n scripts.postinstall = postinstall;\n scripts.prebuild = prebuild;\n scripts.postbuild = postbuild;\n }\n\n pkg.scripts = scripts;\n const indentMatch = raw.match(/^[\\t ]+(?=\")/m)?.[0];\n const indent = indentMatch?.includes('\\t') ? '\\t' : indentMatch?.length ?? 2;\n const trailingNewline = raw.endsWith('\\n') ? '\\n' : '';\n writeFileSync(target, `${JSON.stringify(pkg, null, indent)}${trailingNewline}`, 'utf8');\n\n if (build === undefined || build.trim().length === 0) {\n return {\n changed: true,\n strategy: 'postinstall-only',\n detail: 'added a dependency-install scan; package.json has no build script.',\n };\n }\n\n return packageManager === 'bun'\n ? {\n changed: true,\n strategy: 'build-chain',\n detail: 'added a dependency-install scan and chained scan/mark-build around the build.',\n }\n : {\n changed: true,\n strategy: 'lifecycle-hooks',\n detail: 'added scans to postinstall/prebuild and mark-build to postbuild.',\n };\n}\n"],"mappings":"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","names":["readFileSync","writeFileSync","path","readFile","path","readFile","path","readFile","path","path","readFile","readFile","readFile","readFile","path","readFile","path","path","path","path","readFile","readFile","readFile","path","path","path","readFile","path","path","walk","existsSync","readFileSync","readdirSync","statSync","path","readFileSync","existsSync","writeFileSync","join","writeFileSync","existsSync","join","join","existsSync","writeFileSync","existsSync","mkdirSync","copyFileSync","join","join","existsSync","detect","wire","mkdirSync","copyFileSync","verify","join","existsSync","mkdirSync","copyFileSync","join","dirname","dirname","existsSync","join","mkdirSync","copyFileSync","detect","join","wire","verify","join","SPEC","detect","join","wire","verify","SPEC","detect","wire","verify","readFileSync","existsSync","readdirSync","join","dirname","walk","writeFileSync","existsSync","join","readFileSync","existsSync","mkdirSync","copyFileSync","readdirSync","lstatSync","join","existsSync","join","mkdirSync","copyFileSync","walk","readdirSync","lstatSync","readFileSync","join","changed","writeFileSync","existsSync","SPEC","SPEC","SPEC","existsSync","readFileSync","writeFileSync","path","WIDGET_NEEDLE","existsSync","path","readFileSync","walk","readdirSync","statSync","readFileSync","writeFileSync","path","createHash","createHash","path","writeFileSync","readFileSync","join","readFileSync","realpathSync","createHash","relative","readFileSync","readdirSync","statSync","join","relative","readFileSync","join","statSync","SKIP_DIRS","readdirSync","relative","path","readFileSync","join","createHash","relative","createHash","readFileSync","realpathSync","statSync","dirname","join","relative","readFileSync","realpathSync","relative","dirname","join","statSync","path","path","join2","read","readFileSync","join","readFileSync","join","lineOf","text","MAX_SITES","lineOf","realpathSync","readFileSync","relative","createHash","readFileSync","writeFileSync","path","path","readFileSync","writeFileSync","c","writeFileSync","readFileSync"]}
|