This file describes the source layout and the rules that keep it in order.
src/ is the Node CLI, expo-explore. TypeScript compiles it to dist/.
viewer/ is the browser Viewer. It uses React and Vite, and builds to dist/viewer.
viewer-host/ hosts the central Viewer (see viewer-host/README.md).
action.yml, templates/ and skills/ are the CI and setup integration.
test/ holds the tests: node/, browser/, e2e/ (Playwright) and ci/ (local CI runs), with shared fixtures/ and helpers/.
src/cli.tsis the bin. It maps each command to a handler insrc/cli/.src/types.tsholds the public types. The package exports it as@expo/explore/types.src/source/plan-worker.tsis a process entry point.src/ci/verified-plan.tsstarts it by path to generate the plan again in a fresh process.src/capture/agent/mcp-bridge-worker.tsis a stdio MCP bridge. The local Claude CLI starts it (seesrc/capture/agent/session-local.ts).
| Folder | What it does | Main files |
|---|---|---|
config |
Reads and validates .expo-explore/config.yaml, the exploration inputs, and the setup command. |
explore-config.ts, exploration-inputs.ts, setup.ts |
source |
Source analysis: the route inventory, navigation extraction, git diff and dependency impact, and the deterministic capture plan. | route-inventory.ts, navigation.ts, git-diff.ts, impact.ts, capture-plan.ts |
source/route-providers |
Route discovery for Expo Router and React Navigation. | expo-router.ts, react-navigation.ts |
capture |
Runs the capture on EAS Simulator. | run.ts (entry), eas-build.ts, simulator.ts, controller.ts, route-capture.ts, setup-actions.ts, observer.ts, health.ts |
capture/agent |
Agent mode: Claude or Codex sessions, the pinned runtimes, the navigation runtime, readiness checks and change notes. | session.ts, codex-config.ts, claude-runtime.ts, runtime.ts, readiness.ts, change-notes.ts |
review |
Compares base and head evidence, and prepares the local report assets. ci calls evidence-assessment.ts and capture-review.ts. |
evidence-assessment.ts, capture-review.ts, visual-evidence.ts, runtime-evidence.ts, evidence-comparator.ts, reviewer-changes.ts |
report |
The report artifact, the pull-request comment, and the Viewer links. | artifact.ts, pr-comment*.ts, viewer-links.ts |
ci |
The pipeline behind source:verify, capture:review and capture:baseline. |
pipeline.ts, verified-plan.ts, artifact-cache.ts |
cli |
Argument parsing, help, and the command handlers. | args.ts, help.ts, *-commands.ts |
map |
The local map store, build catalogs and comparisons, and the server for expo-explore view. |
store.ts, build-workspace.ts, compare.ts, viewer-server.ts |
contracts |
The modules that viewer/src imports from src/, by value or by type: data shapes, validators and projections that the CLI and the Viewer share. capture.ts also defines the review types that the Viewer reads, such as PublicReview, and review-validation.ts validates them. |
capture.ts, review.ts, review-validation.ts, source-validation.ts |
shared |
Small Node utilities that several folders use, and the pinned agent-device version that capture and review both check. |
ci-errors.ts, canonical-json.ts, bounded-bytes.ts, png-evidence.ts, agent-device-version.ts, timings.ts (a capture job's timings and its summary, CI-FLOW §4.0) |
The list below shows the value imports between folders. Type-only imports are not in it, because TypeScript erases them. Each layer imports only from the layers below it.
contracts/andsrc/types.tsimport nothing else insrc/;shared/imports onlycontracts/.configandreportimport onlycontracts/andshared/.source/route-providersimports nothing else insrc/.sourceimportssource/route-providers.captureimportscapture/agent,configandmap.capture/agentimportscaptureandconfig.reviewimportscaptureandmap.ciimportsconfig,source,capture,capture/agent,reviewandreport.cliimportsci,map,configandreport.src/cli.tsimportscli,mapandshared.
Every folder may import contracts/, shared/ and src/types.ts.
The exception is contracts/: its value imports stay inside contracts/ or go to src/types.ts.
The only cycle is capture and capture/agent, which are one feature.
Do not add a new import that points up a layer.
viewer/src imports src/ only through src/contracts/ and src/types.ts.
The Viewer may bundle any file in src/contracts/, so each file must stay browser-safe. They follow these rules:
- No
node:imports, also not type-only ones. - No
require, nocreateRequireand noprocess.getBuiltinModule. - Value imports only from
src/contracts/orsrc/types.ts.
Other type-only imports may point anywhere, because TypeScript erases them.
test/node/src-layout.test.mjs enforces the boundary.
To share a new module with the Viewer, move it into src/contracts/ and keep it free of Node APIs.
- A file name says what the file does. It does not repeat its folder or a parent folder:
src/config/setup.ts, notsrc/config/config-setup.tsorsrc/config/config.ts.test/node/src-layout.test.mjsenforces this. - A
*-worker.tsfile is a process entry point that other code starts by path. When you move one, update the code that starts it. - Files in
src/contractskeep a feature prefix (source-validation.ts,review-validation.ts), because the folder spans features. src/holds only.tsfiles, so documentation stays outsidesrc/.