···5858- DMs are intentionally deferred from the current browser-smoke tranche; see `docs/BROWSER_SMOKE.md` for current scope and rationale.
5959- Fresh-account creation is still available through the explicit `bootstrap-*` commands, but it is no longer the normal path for repeated browser smoke runs.
6060- Detailed browser-smoke workflow, current interaction coverage, and the env-gated `prove` wrapper live in `docs/BROWSER_SMOKE.md`.
6161-- Extraction work toward a cross-PDS standalone package now starts in `pds-smoke-suite/`, with bring-your-own-account and `perlsky` adapter helpers defining the neutral config boundary.
6262-- For now, `script/perlsky-browser-smoke` remains the active `perlsky` adapter and runtime entrypoint while the generic package boundary stabilizes.
6161+- Extraction work toward a cross-PDS standalone package now lives in `pds-smoke-suite/`, which owns the browser runtime, package CLI, example configs, and bring-your-own-account plus `perlsky` adapter helpers.
6262+- For now, `script/perlsky-browser-smoke` remains the active `perlsky` adapter entrypoint in this repo, forwarding into the generic package while the external package boundary stabilizes.
63636464Moderation and labels:
6565
+15
docs/BROWSER_SMOKE.md
···8484That wrapper still uses `script/perlsky-browser-smoke`, so the script remains the canonical entrypoint.
8585It also fails the test run if the browser harness finishes with `summary.ok = false`, so late browser/runtime regressions are no longer silently accepted.
86868787+## Extraction
8888+8989+The generic runtime now lives under [pds-smoke-suite](../pds-smoke-suite/README.md).
9090+`perlsky` still keeps [script/perlsky-browser-smoke](/Users/sarah/src/tries/2026-03-10-perlds/script/perlsky-browser-smoke)
9191+as the ergonomic adapter for this repo, but the standalone package now owns:
9292+9393+- browser runtime entrypoints
9494+- reusable generic config builders
9595+- bring-your-own and `perlsky` adapter helpers
9696+- package-owned examples and README
9797+9898+This keeps the current `perlsky` workflow stable while making extraction to a
9999+repo-independent package much more straightforward.
100100+87101## Notes
8810289103- The reusable dual-account path is intentionally conservative about account creation. Fresh actors are only created through explicit `bootstrap-*` commands.
···92106- The current broad smoke automates only dedicated smoke accounts. It does not log into `@alice.mosphere.at`.
93107- The smoke accounts can still visit and interact with `@alice.mosphere.at` as a public target, but the harness does not authenticate as that account.
94108- DMs are intentionally out of scope for now. If we revisit them later, they should be added as a separate documented tranche rather than silently folded into the existing smoke.
109109+- V2 should add direct PDS/AppView contract checks under this browser layer rather than replacing the browser layer outright.
+43-8
pds-smoke-suite/README.md
···2233This directory is the extraction staging area for a standalone `bsky.app`
44compatibility smoke suite that can be used by multiple PDS implementations, not
55-just `perlsky`.
55+just `perlsky`. The browser runtime now lives here, while the old
66+`tools/browser-automation/*` paths remain as thin compatibility wrappers for
77+the current `perlsky` workflow.
6879## Current Scope
810···29312. A bring-your-own-accounts mode with minimal configuration
30323. Thin per-PDS adapters for provisioning and implementation-specific defaults
31333232-Right now, the runtime still lives under `tools/browser-automation/`, while this
3333-directory captures the neutral config and adapter surface we want to preserve
3434-during extraction.
3434+The generic runtime, config builders, and adapter helpers now live here. The
3535+older `tools/browser-automation/` entrypoints simply forward into this package
3636+so the existing repo scripts keep working during the extraction.
3737+3838+## Current CLI
3939+4040+The package now has its own CLI entrypoint:
4141+4242+```sh
4343+node pds-smoke-suite/bin/pds-smoke-suite.mjs print-example --mode dual
4444+node pds-smoke-suite/bin/pds-smoke-suite.mjs validate --mode dual --config pds-smoke-suite/examples/bring-your-own-dual.json
4545+node pds-smoke-suite/bin/pds-smoke-suite.mjs run-dual --config pds-smoke-suite/examples/bring-your-own-dual.json
4646+```
4747+4848+Examples live in [examples/](./examples):
4949+5050+- `bring-your-own-single.json`
5151+- `bring-your-own-dual.json`
5252+- `perlsky-dual.json`
35533654## Minimal Configuration Goal
3755···6583 `handle`, `password`, `birthdate`, `postText`, `mediaPostText`, `quoteText`,
6684 `replyText`, `profileNote`, `cleanupPostPrefixes`
67858686+`pdsHost` is derived automatically from `pdsUrl`, so callers do not need any
8787+perlsky-specific host-setting knowledge just to point the browser at a custom
8888+PDS.
8989+9090+## V2 Ideas
9191+9292+The long-term direction is a test pyramid, not a browser-only harness and not a
9393+pure endpoint-only harness:
9494+9595+1. direct PDS/AppView contract tests
9696+2. cross-service integration checks
9797+3. a thinner `bsky.app` smoke on top
9898+9999+The browser layer stays because it catches real `social-app` assumptions and
100100+AppView proxying issues. The direct API/AppView layers belong underneath it so
101101+regressions become easier to debug and less brittle when the UI changes.
102102+68103## Planned Next Steps
691047070-- move the actual browser runtime from `tools/browser-automation/` into this
7171- package
7272-- add package-owned CLI entrypoints for single-account and dual-account runs
7373-- keep `script/perlsky-browser-smoke` as a thin `perlsky` adapter over the
105105+- keep `script/perlsky-browser-smoke` as a thin `perlsky` adapter over this
74106 generic package
107107+- add a repo-independent install story once the extracted package boundary
108108+ settles
109109+- add direct API/AppView contract tests as the first major v2 expansion
75110- revisit a JS-to-TS migration later, after the standalone package boundary is
76111 stable
···11export * from './config.mjs';
22export * from './adapters/bring-your-own.mjs';
33export * from './adapters/perlsky.mjs';
44+export * from './browser/run-single.mjs';
55+export * from './browser/run-dual.mjs';
66+export * from './cli.mjs';