Paths are relative to the Ax108/radixel repository root.
Product code lives under src/ (not Expo Router). Native shells android/ and ios/ are generated by prebuild (gitignored).
radixel/
├── README.md
├── docs/
├── package.json
├── .env.example # Template for ANDROID_UPLOAD_* (copy to gitignored `.env`)
├── app.json # Expo app config (name, ids, plugins, store policy flags)
├── app.config.js # Dynamic config — OTA URL + runtimeVersion
├── eas.json # Optional EAS Build / Submit (not EAS Update)
├── index.ts
├── babel.config.js
├── tsconfig.json
├── scripts/
│ ├── publish-ota.mjs # bun run ota:export:* → stage OTA repo (--out)
│ └── prebuild-ios.mjs
├── plugins/android/
│ ├── withGradleJvmArgs.js
│ ├── withAndroidLinkingQueries.js
│ └── withAndroidReleaseSigning.js
├── assets/
├── credentials/ # gitignored — upload keystore (not under plugins/)
├── src/
├── android/ # GENERATED
└── ios/ # GENERATED
OTA publish target: clone github.com/Ax108/radixel-ota and pass --out to ota:export:*, or rely on the script default relative path if your checkout layout matches. Served at ax108.github.io/radixel-ota/.
| Area | Rule |
|---|---|
plugins/ |
Expo config plugins only — do not hand-edit android/ / ios/ |
.env / credentials/ |
Local only (gitignored) — upload keystore + passwords |
eas.json |
Optional cloud builds; JS OTA stays on GitHub Pages CDN |
docs/ |
Markdown for humans; no runtime imports |
src/
├── App.tsx # Boot: splash, bootstrapApp(), AppRoot
├── appStore/
│ ├── appStore.ts # Zustand root
│ ├── sessionSlice.ts # Calc + Bitwise + shared session actions
│ ├── settingsSlice.ts # Theme, defaults, resetApp, loadSettings
│ └── historySlice.ts # History entries + load/clear
├── constants/
│ ├── index.ts # palette re-exports
│ └── theme.ts # resolveAppTheme, semantic light/dark tokens
├── modules/
│ ├── app/ # AppRoot, MainShellScreen, header, toast, BaseRows
│ ├── navigation/ # NavStackMain, route types
│ ├── calculator/ # CalculatorScreen, calcController, keypad
│ ├── bitwise/ # BitwiseScreen, bitwiseController, bit grid
│ └── settings/ # Settings + History stack, menu data, FlashList rows
├── shared/
│ ├── boot/bootstrapApp.ts # OTA sync + settings hydration
│ ├── storage/ # settingsStorage, historyStorage
│ ├── history/ # history cap constants, bitwise history format
│ ├── math/intMath.ts # word mask, bases, overflow helpers
│ ├── ota/ # syncOtaUpdate, storeVersion
│ ├── hooks/useAppTheme.ts
│ └── utils/logger.ts # dev-only console
└── tests/ # Jest — 14 files, 212 tests — see testing.md
├── helpers/sessionTestHarness.ts
├── intMath.test.ts # math helpers — all bases × word sizes
├── mathModes.test.ts # calc + bitwise mode matrix (store layer)
├── calcSession.test.ts
├── bitwiseSession.test.ts
├── settingsSession.test.ts
├── history.test.ts
├── bootstrapApp.test.ts
├── updatesController.test.ts
├── storeVersion.test.ts
├── theme.test.ts
├── appStore.test.ts
├── App.test.tsx
├── settingsUi.test.tsx
└── CustomSplashScreen.test.tsx
Path aliases: @modules/*, @store/*, @shared/*, @constants, @navigation/*, @settings/*, @/*.