
Product
Socket Threat Intel Now Shows Which Malware Campaigns Were Blocked or Detected
Socket Threat Intel now shows which malware campaigns were blocked or detected in your organization, with links to scans and Firewall events.
@pdpp/local-collector
Advanced tools
Local collector runtime for PDPP: filesystem-class connectors (Claude Code, Codex, Google Takeout, iMessage, Apple Photos, Google Messages) plus the device-exporter ingest client.
Publishable PDPP local collector runtime for filesystem-class connectors.
This package is intentionally narrower than @pdpp/polyfill-connectors: it
ships only the local collector runner, the device-exporter client, and bundled
Claude Code / Codex connector entrypoints. Browser/Patchright-backed connectors
stay out of this package until each has its own publishability review.
For filesystem-class collectors, the local device or host supervisor decides
when the process runs. The reference server owns enrollment, ingestion, state,
health diagnostics, and optional desired-freshness/request-run signals, but it
does not start local processes. PDPP_CONNECTION_ID is the stable
connection/source identity for a specific device/account/home binding; the
enrollment response currently names that value source_instance_id.
Install or upgrade to the current release. Check the affected range below
first: @latest resolves to whatever npm currently marks latest, which is an
affected version until a corrected release is published.
npm i -g @pdpp/local-collector@latest
Or run without installing, which always resolves the current release:
npx -y @pdpp/local-collector@latest advertise
Every published version from 1.3.0 through 1.5.4 is unrunnable. Those
tarballs contain a compiled import ... from "@pdpp/reference-contract" that
is not declared as a dependency and does not exist on the npm registry. The
import resolved for developers through the workspace link and failed closed on
every real install, so any invocation — including --version — exits with:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@pdpp/reference-contract'
There is no workaround within that range; upgrading is the fix once a corrected
version is published. At the time of writing no such version exists yet, so
@latest still resolves to 1.5.4. Name the first fixed version here when it
publishes.
Two gates run before any publish and are what detect this failure mode:
validate:package rejects any bare import the manifest does not declare, and
pack-install-run installs the packed tarball into a clean project and drives
the real CLI against a reference server. They cover the import-resolution
failures they test for; they are not a guarantee against every packaging
defect.
Guided path — one command pairs the host and saves credentials, no manual JSON/env-var copying:
# @pdpp/local-collector package, npx-launched pdpp-local-collector binary
npx -y @pdpp/local-collector setup \
--base-url https://<reference-host> \
--code <one-time-code> \
--connector claude_code \
--sample 20 # bounded proof pass: verify without collecting the whole archive
# credentials are saved to ~/.config/pdpp/collectors/claude_code.env (0600);
# run resolves them automatically from --connection-id alone:
npx -y @pdpp/local-collector run --connection-id <source_instance_id>
run prints live progress to stderr as records are found (--quiet to
suppress). --sample <n> works on run too, any time you want a bounded
preview instead of a full collection.
connect: declare a collection horizon at pairing timeconnect performs the same one-time-code exchange as setup, plus an
optional collection-horizon REQUEST — no separate owner-side call needed
first:
# Recent history only (defaults to 30 days if --recent is given no value):
npx -y @pdpp/local-collector connect \
--base-url https://<reference-host> \
--code <one-time-code> \
--connector claude_code \
--recent 30
# Explicit full history:
npx -y @pdpp/local-collector connect --base-url https://<reference-host> \
--code <one-time-code> --connector codex --all
# Custom boundary — since a timestamp, and/or specific project roots:
npx -y @pdpp/local-collector connect --base-url https://<reference-host> \
--code <one-time-code> --connector claude_code \
--since 2026-07-01T00:00:00.000Z --source-roots ~/code/project-a,~/code/project-b
Exactly one of --recent, --all, or --since/--source-roots may be
given; passing none defers entirely to the server. --since is validated
locally (must parse as a date/time) and --source-roots entries that look
like filesystem paths are ~-expanded, resolved to absolute paths, and must
exist on this host — before any request is sent, not after a round trip that
would silently collect nothing.
The scope flags are a REQUEST, never a local completeness authority: the server is the sole arbiter of the effective boundary. A device-declared scope can only NARROW whatever the server already declared (or defaulted) — a request that would WIDEN a server-declared boundary is rejected with a typed error, not silently clamped. When neither side declares a boundary the server defaults to recent history (30 days), never an implicit full pass.
If a profile already exists at the target name (default: the connector id),
connect refuses to overwrite it — doing so silently would leave the OLD
device credential live and un-revoked on the server with no local record left
to revoke it. Pass --force to revoke the existing credential first, then
connect and overwrite the profile; a failed revoke aborts before the new code
is consumed, so nothing is lost on a failed retry.
The one-time --code above comes from the owner-authenticated
POST /v1/owner/connections/intents call that mints it (see
docs/reference/local-collector.md). That
same call accepts an optional collection_scope — { since, source_roots }
— declaring the boundary the collector should run within: recent history
(e.g. since 30 days ago), a specific project (source_roots), or the
default of no bound (full history). This is the same shape connect's scope
flags above build; declaring it at intent-mint time (owner-side, before a
device ever enrolls) and declaring it via connect (device-side, at
enrollment) both apply to every run against that connection from then on —
there is no run-time flag that can widen or override it, by design: a
local flag must never be able to claim more coverage than the server
actually granted.
status and doctor report the boundary currently in force for a lane under
scope.active (a fingerprint string; "unscoped" means a full pass), so you
can always see what a "complete" run on this connection is complete within.
A run only reports coverage as committed once it has exhaustively enumerated
that boundary — --sample, an interrupted run, or one stopped by the per-run
scan budget always reports coverage_note as NOT committed, never a partial
count read as done.
# List connector ids this build accepts.
npx -y @pdpp/local-collector connectors
# Revoke this device's credential on the reference server, then remove its
# saved local profile. Add --local-only to skip the server call (only for an
# unreachable/decommissioned server — the device token stays live otherwise).
npx -y @pdpp/local-collector logout --connector claude_code
# Preview host-local recovery for a stalled collector lane. This loads the
# enrolled local profile for the source instance and changes nothing.
npx -y @pdpp/local-collector recover --source-instance-id <source_instance_id>
# Apply recovery: requeue retryable uploads, rebuild rejected terminal commits from
# a completed pass, and retain old terminal evidence until the replacement is accepted.
npx -y @pdpp/local-collector recover --source-instance-id <source_instance_id> --apply
Low-level / scriptable primitives (unchanged, still supported):
# @pdpp/local-collector package, npx-launched pdpp-local-collector binary
npx -y @pdpp/local-collector advertise
# enroll prints the raw JSON response instead of saving a profile.
npx -y @pdpp/local-collector enroll \
--base-url https://<reference-host> \
--code <one-time-code>
# run with credentials supplied entirely via env vars/flags.
PDPP_LOCAL_DEVICE_ID=<device_id> \
PDPP_LOCAL_DEVICE_TOKEN=<device_token> \
PDPP_CONNECTION_ID=<source_instance_id> \
npx -y @pdpp/local-collector run \
--base-url https://<reference-host> \
--connector claude_code
The collector sends X-PDPP-Collector-Protocol on enrollment and every
device-exporter request. The reference server rejects incompatible versions
before persisting records or state.
Install globally if you prefer a persistent binary:
# @pdpp/local-collector package, installs the pdpp-local-collector binary
npm i -g @pdpp/local-collector
pdpp-local-collector advertise
device_token is write-capable for its collector lane. Store it in a secret
manager or root-readable env file, and do not print it in logs, issues, or
support transcripts.
For a full operator runbook, including Docker move guidance and troubleshooting
for 403 after source migration and 409 collector_protocol_mismatch, see
docs/reference/local-collector.md.
Decision D-29 records the operative assumption for every officially bundled
connector this package ships: official connector source is code-trusted at
the same privilege level as the runner until confinement lands. Repository
separation (this package living apart from connector content) is governance
and release separation, not runtime containment. Custom/untrusted connector
execution stays disabled — the published CLI's run --connector accepts only
the bundled connector ids.
Under that trust posture, the exact current child-process authority is:
process.env, then
the runtime's own reserved keys (PDPP_LOCAL_DEVICE_TOKEN,
PDPP_REFERENCE_BASE_URL, PDPP_RUN_ID) are applied, then the connector's
own declared env is merged in last — a connector can override the
runtime's reserved keys.PDPP_LOCAL_DEVICE_TOKEN.node_modules/.bin from both the package root and the repo
root prepended to PATH.cwd is the collector's own package
root.This supersedes older, narrower design text that described the connector child as receiving no device token and an allowlisted-from-scratch environment — that description does not match what this runtime does today for the officially bundled connectors. Sandboxing, credential brokering (a narrower, per-connector token instead of the full device token), and a built-from-scratch allowlisted child environment remain future enablement gates, not requirements this package meets now.
FAQs
Local collector runtime for PDPP: installs pinned, signed Collection Profiles for filesystem-class connectors (Claude Code, Codex, Google Takeout, iMessage, Apple Photos) and runs them with the device-exporter ingest client.
The npm package @pdpp/local-collector receives a total of 0 weekly downloads. As such, @pdpp/local-collector popularity was classified as not popular.
We found that @pdpp/local-collector demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.

Product
Socket Threat Intel now shows which malware campaigns were blocked or detected in your organization, with links to scans and Firewall events.

Security News
Fixes for eMudhra and Brotli are out. Getting them everywhere they’re needed means tracking down bundled libraries, runtimes, and certificate stores.

Threat Research
/Security News
Socket uncovered secret-stealing workflows that ran in LiteLLM’s GitHub repository 11 days before the supply chain attack on PyPI and Docker.