Scripts #
Local atproto dev network (pnpm dev:network) #
Starts an ephemeral @atproto/dev-env PDS + PLC, a dev-only microcosm stub
(SQLite + firehose indexer), two .test accounts, and seeds the five
content/walkthroughs/*.md dev fixtures as published
at.protocube.walkthrough records (all carrying tag:protocube; no drafts).
- PDS:
http://localhost:2584(envDEV_PDS_URL) - Stub:
http://127.0.0.1:2599(envMICROCOSM_STUB_URL) — Slingshot + Constellation query shapes only; not used in production builds. - App: run
pnpm devseparately and openhttp://[::1]:3000(IPv6 loopback). Do not usehttp://localhost:3000for OAuth against this PDS.
State under .dev/ is gitignored. DIDs change on every boot; handles and
passwords are printed when the command starts.
Clean restart: pnpm dev:network:clean wipes the persistent .dev/ state
(the stub's SQLite index, whose rows are keyed by the previous run's DIDs)
before booting, so no record or identity from an earlier run survives. Stop a
running dev:network first — it holds that file open. The PDS and PLC are
in-memory and are reborn fresh on every boot regardless.
First run: if the PDS fails with a missing better_sqlite3.node, run
pnpm rebuild better-sqlite3 (native addon; listed in pnpm.onlyBuiltDependencies).
The transitive @atproto/pds copy may need the same:
cd node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3 && npm run build-release.
Production lexicons on the real network: pnpm lexicons:publish.
Live network (pnpm dev:network:live) #
Runs the local app against the real network: no local PDS, PLC or stub.
- Reads: public Slingshot (
https://slingshot.microcosm.blue) for records, handle resolution and profiles, plus public Constellation (https://constellation.microcosm.blue) for backlinks — feeds, tags and likes. The stub serves both on one port; this mode sets them separately. - Identity: the real PLC directory (
https://plc.directory), overriding the local value in.env. - Writes: the PDS of the account you sign in with. Sign in with a real
account;
.testaccounts exist only onpnpm dev:network. Records published here are public. - OAuth scope: defaults to direct granular scopes
(
atproto repo:at.protocube.walkthrough repo:at.protocube.like repo:at.protocube.series repo:at.protocube.path), so sign-in works before the authority permission set exists. Pass--permission-setto request the productionatproto include:at.protocube.authFullscope; that requires_lexicon.protocube.atand the authority lexicon records (pnpm lexicons:publish).
If sign-in reports that protocube's permissions could not be loaded, the
authority permission set is missing on the network — drop --permission-set
for local testing, or publish the lexicons first. ("Your PDS does not support
granular permissions yet" is reserved for hosts that actually reject granular
scopes.)
Any URL can be overridden with the matching NUXT_PUBLIC_* shell variable;
extra args go to nuxt dev (pnpm dev:network:live -- --port 3001).
OAuth (issue 05) #
With pnpm dev:network running, the default NUXT_PUBLIC_SLINGSHOT_URL
(http://127.0.0.1:2599) already wires OAuth handle resolution and profile
reads to the stub. Set the PLC directory from the dev:network output:
export NUXT_PUBLIC_ATPROTO_PLC_DIRECTORY_URL=http://localhost:2583 # example; use printed DEV_PLC_URL
pnpm dev # nuxt.config binds [::1]:3000 by default for the OAuth-safe URL
Validate production public/client-metadata.json (vendored from the
atproto-oauth skill): pnpm oauth:validate-metadata.
Other: pnpm bundle:report — per-route initial JS from a production build.