@@ -8,11 +8,15 @@ derived from the iPhone shell at `../zennotesiphone` — the two shells share th
88same structure and bridge modules; platform-specific divergences are noted
99below.
1010
11- The zennotes repo is consumed ** read-only at the exact commit in
12- ` .zennotes-commit ` ** . ` npm run source:prepare ` checks that commit out under the
13- ignored ` .zennotes-source/ ` directory and installs its locked dependencies.
14- Every typecheck and release build verifies the pin; no ambient sibling checkout
15- can silently change a mobile binary.
11+ The app consumes the public ` @zennotes/app-core ` , ` @zennotes/bridge-contract ` ,
12+ and ` @zennotes/shared-domain ` packages. The exact archives are vendored under
13+ ` vendor/zennotes/ ` with their source identity and checksums (` manifest.json ` ),
14+ and ` package-lock.json ` pins the complete install. No source checkout is used.
15+ The vendored set is the published desktop release
16+ [ core-2.51.0-core.h49d73b531d346192] ( https://github.com/ZenNotes/zennotes/releases/tag/core-2.51.0-core.h49d73b531d346192 )
17+ (desktop commit ` 8ff2cb86 ` , tag v2.51.0, clean tree). Run `npm run
18+ boundaries: check ` to verify archives, installed versions, singleton
19+ editor/React peers, and imports.
1620
1721## Architecture
1822
3135 widgets.ts publishes it through the ZenWidgets plugin on every change
3236 ui-mobile/
3337 MobileShell.tsx bottom nav (capture ⊕ / search / sidebar / palette),
34- phone drawer behavior via the shared Zustand store
38+ phone drawer behavior through public core APIs
3539 mobile.css safe areas, overlay drawers, keyboard handling
3640 widget-links.ts the zennotes:// links the widgets fire; deep-links.ts runs them
3741android/ Capacitor-generated Gradle project (appId md.zennotes)
@@ -50,9 +54,10 @@ Key decisions (all forced by "don't modify the zennotes repo"):
5054 Every desktop-only affordance in app-core gates on ` runtime === 'desktop' ` ,
5155 so ` 'web' ` + the capability flags produces correct mobile behavior. When the
5256 contract gains ` 'mobile' ` + the new capability flags (spec 02), flip it here.
53- - ** ` platform: 'linux' ` ** (iOS shell reports ` 'darwin' ` ) — gives app-core
54- Ctrl-based keymaps and hides Mac-only chrome; right for Android hardware
55- keyboards.
57+ - ** ` platform: 'android' ` + ` hostKind: 'android' ` ** (iOS shell reports
58+ ` 'ios' ` ) — app-core only special-cases ` 'darwin' ` , so Android still gets
59+ Ctrl-based keymaps and no Mac-only chrome; ` hostKind ` is how core tells the
60+ native shells apart (it replaced the earlier ` 'linux' ` stand-in in 1.1.21).
5661- ** Vault location** — app-scoped external storage:
5762 ` /Android/data/md.zennotes/files/ZenNotes/<vault> ` (` Directory.External ` ),
5863 the spec-03 Android default tier: no permission prompt, works under scoped
@@ -117,7 +122,7 @@ Key decisions (all forced by "don't modify the zennotes repo"):
117122 the misspelling is intentional and load-bearing), same ` .zennotes/ `
118123 metadata (vault.json, workspace.json, comments/), same naming/collision
119124 rules, same NoteMeta extraction regexes, ` systemFolderPaths ` remaps honored
120- via ` @shared/system-folder-paths ` .
125+ via ` @zennotes/ shared-domain /system-folder-paths ` .
121126- ** Share sheet → quick capture** : Android needs no app extension — a
122127 ` text/plain ` ` ACTION_SEND ` intent-filter on MainActivity stashes captures in
123128 SharedPreferences; the app-local ` ShareInbox ` plugin (same ` jsName ` and
@@ -163,7 +168,7 @@ Key decisions (all forced by "don't modify the zennotes repo"):
163168 task rows, kanban cards, and calendar day cells), subtask rollups, archived
164169 notes retiring their tasks, inline mermaid while writing, text
165170 replacements, configurable tab size, manual kanban card order, and
166- absence-aware remote reads (` @shared/remote-absence ` ).
171+ absence-aware remote reads (` @zennotes/ shared-domain /remote-absence ` ).
167172
168173## Build & run
169174
@@ -183,10 +188,12 @@ points at the SDK. Dev loop against a browser (no emulator): `npm run dev` —
183188Capacitor plugins are absent in a plain browser, so vault I/O won't work; use
184189the emulator for real testing.
185190
186- ` npm run upstream ` verifies the generated checkout matches ` .zennotes-commit `
187- and typechecks the bridge against that exact source. To adopt a newer core,
188- update the pin to a reviewed full commit SHA and commit it with the dependent
189- mobile changes.
191+ ` npm run upstream ` verifies the package boundary and typechecks the host.
192+ To adopt a new core candidate, copy its three immutable archives into
193+ ` vendor/zennotes/ ` , update the manifest and ` file: ` dependencies, then run
194+ ` npm install ` , the boundary check, tests, typecheck, production build, and native
195+ runtime checks together. Keep the previous validated package version available
196+ for rollback. A package update must not require private core imports.
190197
191198## Boot-order gotcha (load-bearing)
192199
@@ -251,3 +258,5 @@ signed object upload, completion, manifest, and cleanup with a deterministic
251258 (` useSystemBackClose ` is Android-only: iOS has no system back gesture).
252259 Underline stayed out on purpose: ZenNotes markdown has no underline
253260 construct on any platform — an upstream schema decision, not a shell one.
261+
262+ For device-level package checks, see [ native boundary validation] ( docs/native-boundary-validation.md ) .
0 commit comments