- http-cache-semantics ^4.3.0 (GHSA-ch52-4w7c-c8xp, high): 4.3.0 is out of
the <=4.2.0 range although the advisory lists no patched version. Single
copy via @expo/ngrok > got > cacheable-request (^4.0.0), dev tunnel only.
- postcss-selector-parser@^6.0.0 -> ^6.1.3 (GHSA-w9m9-85wc-3x92, low),
version-scoped to the tailwindcss@3 major. Resolves to 6.1.4.
Lockfile: two stanzas, package count unchanged (2084). npm audit 33 -> 31.
Android JS bundle (expo export --no-bytecode, cache cleared) is byte-identical
before and after. Smoke test guards both floors.
Resolves#128Resolves#129
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brace-expansion: nine new DoS advisories outdate the floors set in #103.
Raise the three version-scoped overrides to the patched head of each
major (1.1.21, 2.1.7, 5.0.12). undici: raise the @expo/cli scoped
override to ^6.28.1 (resolves to 6.29.0).
Add smoke checks locking the floors and the minimatch brace/glob
behaviour for every installed minimatch major, so a return to a blanket
override fails the suite.
npm audit: 12 -> 10 entries. The rest is tracked in #123 and #126.
Fixes#124Fixes#125
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Advisories published on 2026-09-08 land above the current floors:
- @xmldom/xmldom <= 0.8.14 (GHSA-c7q8-3ch8-vqpv, GHSA-x4fp-j954-r2f4,
GHSA-93r5-fhx6-vmg9 and 7 more), patched in 0.8.15 (lts line)
- js-yaml < 3.15.2 / < 4.3.2 (GHSA-2883-xcg3-v3hh)
Raise the three overrides. Lock diff is limited to the three entries.
All consumers are build-time tooling (@expo/plist, plist via xcode,
@expo/xcpretty, @istanbuljs/load-nyc-config); the Android bundle hash
is unchanged.
Fixes#121
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@react-navigation/core <= 7.22.0 depends on query-string, which pulls
decode-uri-component <= 0.4.2 (GHSA-vcc3-ghjq-m6fr, DoS on malformed
percent-encoded input). 7.22.1 parses queries itself and drops the
dependency. A scoped override bumps it without touching anything else:
the lock diff is limited to @react-navigation/core and /routers.
Add smoke-test guards for the failure mode of the superseded PR #118
(blanket npm audit fix): babel-preset-expo and @expo/metro-config must
resolve from the root node_modules, only one Expo SDK major may be
installed, every metro copy must stay on 0.83.x. Replayed against the
PR #118 lock, all four checks fail. Also add a deep link round trip
through getStateFromPath/getPathFromState with query params.
Fixes#117
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
browserslist <= 4.28.6 carries two HIGH advisories published 2026-09-01:
GHSA-c83g-rgw3-j3cx (unbounded memory growth, no cache eviction, leading
to OOM) and GHSA-73wf-gq98-2v4g (uncaught crash / prototype write via an
untrusted browserslist-stats.json in normalizeStats). Both report
first_patched_version = 4.28.7.
Unlike the image-size root fixed in #114, this one has a published fix,
so a plain version floor is enough. Every requester already uses a caret
range compatible with 4.28.7 (@babel/helper-compilation-targets ^4.24.0,
@expo/metro-config ^4.25.0, core-js-compat ^4.28.1, update-browserslist-db
peer >= 4.21.0) -- the lock was simply pinned at 4.28.1. The override
records the security floor the same way as the existing esbuild,
@xmldom/xmldom, postcss, brace-expansion and @babel/core entries.
Resolves to 4.28.9. npm audit: 11 -> 10 total, 1 HIGH -> 0 HIGH. No high
or critical finding remains in the tree.
Verified: the lock stays unchanged under re-resolution against
package.json, npm ci accepts the pair (what EAS runs), npm test 11/11,
and expo export --platform android emits a byte-identical Hermes bundle
(index-3d9ab1a7942c6dfccc79d9b280b8ce80.hbc, 8.17 MB) -- the compilation
targets browserslist resolves are unchanged.
Refs #115
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Y4GzEsmDryrwtQcmBNw9P
metro@0.83.8 (published 2026-08-19) removed the image-size dependency and
vendored a reduced dimension parser (src/lib/imageSize.js) that supports
only bmp/gif/jpeg/ktx/png/psd/svg/tiff/webp. The ICNS, JXL and HEIF
parsers named by GHSA-w3rx-r6r6-pgpr and GHSA-5p2g-fcmc-qvqq are absent
from it, so the DoS is eliminated by construction rather than by an
upstream patch: image-size still publishes no fixed version (latest is
2.0.2, and both advisories report first_patched_version = None).
metro@0.83.3 was the only requester of image-size in the whole tree, so
every transitive HIGH finding collapses with it.
@expo/metro@54.2.0 pins the 14 metro packages to exact 0.83.3, so npm
update cannot move them and an override is required. All 14 are moved
together to avoid a mixed metro tree; the existing nested ws override is
preserved through the "." key.
npm audit: 19 -> 11 total, 9 HIGH -> 1 HIGH. The remaining HIGH
(browserslist) is unrelated and pre-existing on master.
Verified: image-size absent from both the lock file and node_modules,
14 metro packages resolved to 0.83.8 with no duplicates, patch-package
postinstall still applies, npm test 11/11, and expo export --platform
android produces a Hermes bundle with PNG dimension variations resolved
through the vendored parser.
Refs #108
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Y4GzEsmDryrwtQcmBNw9P
- brace-expansion -> ^1.1.18 / ^2.1.4 / ^5.0.9 (version-scoped per major):
DoS advisories (exponential-time expansion + unbounded OOM). Version-scoping
bumps each major within its own major, preserving the CJS export contract
(default export for 1.x/2.x, named for 5.x) that a blanket override would have
broken. This is #103's original blocker, now resolved. Verified: minimatch@3
glob resolution works (the exact call that TypeError'd under a blanket).
- @babel/core -> ^7.29.6 (resolves 7.29.7): GHSA-4x5r-pxfx-6jf8 arbitrary file
read via sourceMappingURL (vulnerable <=7.29.0, ~87 deduped instances).
Both build/dev-time only, not bundled in the shipped APK. npm audit 14 -> 12;
the remaining 12 high are entirely the image-size upstream-locked cascade
(no published fix, tracked in #108). Smoke test 11/11, lock diff is 1:1 version
replacements (large count driven by @babel/core's deduped instances).
Fixes#103Fixes#110
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- @expo/cli > undici ^6.27.0 -> ^6.28.0: GHSA-8xcm-r25x-g524 / m8rv-5g2x-5cg5
/ v3r7-h72x-cjcm (response desync, CRLF & cookie injection; vulnerable <6.28.0)
- js-yaml -> ^3.15.1 (3.x) + ^4.3.1 (4.x): CVE-2026-59870 / GHSA-5p4m-2wfm-xmqj
(quadratic CPU in !!omap resolution; vulnerable 3.x<3.15.1, 4.x<4.3.1)
js-yaml moved from parent-scoped overrides (@expo/xcpretty,
@istanbuljs/load-nyc-config) to version-scoped ones (js-yaml@^3 / js-yaml@^4):
the 4.x instance is reached via @expo/cli, which is itself overridden, and a
nested override does not propagate through an overridden parent (npm left
js-yaml@4.3.0 "invalid"). Version-scoped targeting resolves it regardless of
the parent path.
Both build/dev-time only, not bundled in the shipped APK. npm audit drops
undici + js-yaml (16 -> 14). Remaining 13 high = image-size + its metro/RN
cascade (upstream-locked, tracked in #108) + @babel/core low. Smoke test green,
widget patch reapplied, lock diff limited to the 3 bumped packages.
Fixes#106Fixes#107
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- postcss ^8.5.10 -> ^8.5.18 (resolves to 8.5.26): GHSA-r28c-9q8g-f849,
path traversal in source-map auto-loading (vulnerable <=8.5.17)
- @expo/cli > tar ^7.5.19 -> ^7.5.21 (resolves to 7.5.22): GHSA-r292-9mhp-454m,
uncontrolled recursion stack-overflow DoS (vulnerable <=7.5.20)
- nanoid 3.3.11 -> 3.3.18 pulled in by postcss re-resolution (bonus)
Both are build/dev-time only, not bundled in the shipped APK. npm audit no
longer lists postcss (nor its transitive inflation expo/@expo/cli/
@expo/metro-config) nor tar. Smoke test green (11/11), widget patch-package
reapplied, diff limited to package.json + package-lock.json.
Fixes#102Fixes#104
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Upgrade react-native-android-widget 0.20.1 -> 0.21.0 (expedited
WorkManager upstream, clickable-area ripple corner fix)
- patch-package on the lib:
1. WIDGET_CLICK bypasses WorkManager and runs the headless JS task
directly on the ReactHost (goAsync + WorkManager fallback), removing
two Room writes + worker dispatch from every tap and WorkManager
init from the cold path
2. WEBP_LOSSLESS (effort 0) encoding instead of PNG q100 on API 30+,
several times faster for widget-sized bitmaps
3. Copy identical light/dark collection item files instead of
compressing every row bitmap twice when the config is single-mode
- Extract dependency-light src/services/widgetState.ts so the headless
click handler no longer pulls DB/drizzle/date-fns at cold start
- Smoke tests: lock the light import graph + patch/postinstall wiring
- Bump v1.6.5 (versionCode 17) for the preview build
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds scoped overrides for shell-quote (GHSA-w7jw-789q-3m8p, critical),
undici (4 CVEs, high), ws (GHSA-96hv-2xvq-fx4p, high — distinct from the
CVE already fixed in #92/#94), js-yaml (GHSA-h67p-54hq-rp68, moderate,
two incompatible majors need separate scopes), and tar
(GHSA-vmf3-w455-68vh, moderate). All 5 are dev-tooling-only (Expo CLI,
Metro, react-devtools-core) with no runtime app code path.
Verified: npm audit clean on all 5 packages, smoke test passes, Metro
Bundler boots and serves /status normally after the ws bump (the only
scope touching Fast Refresh/dev-middleware runtime).
Fixes#95, Fixes#96, Fixes#97, Fixes#98, Fixes#99
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
npm audit flagged ws 8.0.0-8.20.0 (moderate, uninitialized memory
disclosure) pulled in via expo > @expo/cli > ws@8.20.0. Scope the
override to @expo/cli so only the vulnerable 8.x instance is bumped
(resolved to 8.21.0); metro's ws@7.5.10 and react-native's ws@6.2.3
stay on their majors to avoid breaking the Metro dev server.
All ws here is dev/build tooling (Expo CLI, Metro, react-devtools),
absent from the shipped APK, so this was not exploitable in production
- but the override clears npm audit and stops the Defenseur re-flagging.
npm audit: 0 vulnerabilities. Root smoke green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The previous override ^11.0.0 allowed the vulnerable range 11.0.0 - 11.1.0.
npm resolved on 11.1.0, leaving the buffer-bounds-check CVE active in
v3/v5/v6 with buf arg. Bumping to ^11.1.1 stays in the 11.x major (CJS
compat preserved per past revert at 800f777) and fixes the advisory.
npm audit: 0 vulnerabilities. smoke tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Plain-node script invoked via `npm test`. Catches the buffer-bounds
regression area from GHSA-w5hq-g745-h8pq (uuid v3/v5 with buffer arg)
and validates package.json structure. No jest/Expo runtime needed —
runs in seconds, suitable for the defenseur-auto chain to gate auto-PRs.
Security release: 5 CVE resolved in build-time dep chain via overrides
(@xmldom/xmldom, uuid, postcss). 4 HIGH + 1 MEDIUM cleared.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves GHSA-qx2v-qp2m-jg93 (PostCSS XSS via Unescaped </style> in CSS
Stringify Output) in the @expo/metro-config + tailwindcss build chain.
Build-time only, not runtime-exploitable in RN, but cleared for audit hygiene.
Defenseur scan post-override: 13/13 passed, 0 findings (the residual uuid
cascade is suppressed via defenseurs allowlist for GHSA-w5hq-g745-h8pq).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves GHSA-w5hq-g745-h8pq in the transitive chain (xcode + @expo/ngrok).
Per spec decision D3, we pin ^11.0.0 (not ^14.0.0) to avoid ESM-only breaking
CJS consumers. Actual vulnerable code paths (v3/v5/v6 with buf param) are not
used by xcode or @expo/ngrok — they only call uuid.v4() — so the override is
safe in practice even though npm advisory range is <14.0.0.
Refs #75
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves 4 HIGH CVE in the xmldom transitive dep chain (Expo CLI + xcode/plist).
Not runtime-exploitable in APK (build-time deps only) but cleaned for audit hygiene.
- GHSA-2v35-w6hq-6mfw (DoS — uncontrolled recursion in XML serialization)
- GHSA-f6ww-3ggp-fr8h (XML injection via DOCTYPE serialization)
- GHSA-x6wf-f3px-wcqx (XML injection via processing instruction serialization)
- GHSA-j759-j44w-7fr8 (XML injection via comment serialization)
Refs #74
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The (app)/layout.tsx was calling cookieStore.set() which is forbidden in
Server Components under Next.js 16 (only allowed in Server Actions and
Route Handlers). This caused a 500 error immediately after Logto login.
Also includes: mobile sync client improvements, i18n updates, web API
rate limiting, Bearer token support for mobile clients, and Dockerfile
optimizations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The transitive dependency chain drizzle-kit -> @esbuild-kit/esm-loader ->
@esbuild-kit/core-utils pulled in esbuild@0.18.20 which is vulnerable to
GHSA-67mh-4wv8-2f99. Adding an npm override forces all nested esbuild
instances to use ^0.25.0, resolving all 4 moderate audit findings.
Ref: simpl-liste#16
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Buttons (X, back, save, delete, export) had ~28px hit areas,
causing missed taps. Increased padding to p-2.5 + hitSlop for
~44px touch targets. Bump version to 1.2.4.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace manual keyboard listeners and RN KeyboardAvoidingView with
react-native-keyboard-controller which handles edge-to-edge correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
KeyboardAvoidingView does not work with edgeToEdgeEnabled on Android.
New approach: listen to Keyboard events, dynamically set spacer height
to actual keyboard height, and scrollToEnd when subtask input is focused.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Widget adapts to app theme (light/dark/system) via AsyncStorage
- Add "Check for updates" button querying Forgejo releases API
- Add "Contact us or report a bug" mailto link in settings
- Bump version to 1.0.1
Closes#1, closes#2, closes#3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds home screen widgets (Small 2×2, Medium 4×2, Large 4×4) using
react-native-android-widget. Widgets display upcoming tasks sorted by
urgency, support tap-to-complete and deep linking into the app, and
refresh on every task mutation + every 30 minutes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace static delete buttons with swipe gestures (left to delete, right
to complete) and add drag-to-reorder support using react-native-draggable-flatlist.
Inbox is pinned at top of lists tab with a GripVertical drag handle for
custom lists. Polling is paused during drag operations to prevent state conflicts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Scheduled task reminders via expo-notifications with configurable
offset (at time, 1h, 3h, 1 day before)
- Optional calendar sync via expo-calendar (creates/updates/removes
events in a dedicated Simpl-Liste calendar)
- ICS export with RRULE support for inbox, lists, and individual tasks
- New migration adding calendar_event_id to tasks table
- Settings UI for notifications toggle, reminder offset, and calendar sync
- Export buttons in inbox toolbar, list header, and task detail
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Clicking a list now shows its tasks instead of opening new task form
- Add list/[id] detail screen
- Replace crypto.randomUUID() with expo-crypto (Hermes compatibility)
- Add SQL transformer for Drizzle migration files
- Improve priority color visibility in dark mode (lighter variants)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>