Repository navigation
Conversation
Two merged Dependabot PRs left the lockfile unresolvable: - eslint 10 (#39): @react-native/eslint-config peers on eslint ^8 || ^9. Pin eslint back to ^9.39.5. - react-dom 19.2.8 (#38): react-dom requires the exact same react version. Bump react to 19.2.8 to match. Also group react + react-dom in Dependabot and ignore eslint majors so this doesn't recur. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Detector (src/safety/crisis.ts):
- A benign idiom anywhere in a message ("I killed it at work") used to
return 'none' before hard patterns ran, masking real ideation in the
same message. Now the idiom is blanked out and detection continues.
- "wanna die" was missed (pattern required "wanna to").
- Curly apostrophes (iOS default) are normalized, so "don’t want to have
been alive" matches.
Helplines:
- Route by region first, language only when no region is given. Adds
CA/AU/NZ/IE/AT/CH, Spain's 024, and gives es-US/fr-CA 988. Unknown
regions get the directories, never another country's number.
Crisis modal:
- Memoize resources; a fresh array each render re-ran the effect whose
cleanup cleared the 1.5s dismiss timer, so dismiss never completed.
- Drop canOpenURL pre-check (false for tel:/sms: on Android 11+ without
manifest queries); openURL's rejection drives the inline error.
- Fallback text no longer tells every locale to call 988; SMS number is
read from the resource instead of hardcoded.
Chat:
- Show the modal before any storage await, and don't stack an error
alert on it if persistence fails.
- newId() falls back when crypto.randomUUID is unavailable.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
…failures - clearAll(): a failed keychain delete used to be ignored and its key dropped from the index, orphaning that chat forever while the app reported success. Failed keys now stay indexed for a retry, and clearAll() throws so ProfileScreen's "Couldn't complete reset" shows. - New getAllChatSessions() reads every indexed session. Data export and the profile chat counter used getChats(), which returns [] after the legacy migration, so exports had no chat history. - setChatSession() uses the strict write, so a failed save rejects and ChatScreen keeps the draft + alerts instead of silently losing it. (SDK 57 SecureStore enforces no size cap, per the docs, but the native write can still fail.) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
- Gate on the same checks as CI (needs: quality). - Drop --no-wait so `eas submit --latest` submits the build just made, not the previous one. - Add eas.json: remote app versioning + autoIncrement (counter survives ephemeral runners), production submit profile with Play internal track. - Write the Play service-account secret to a temp file for eas submit; iOS uses the ASC API key stored on EAS. Fail fast while ascAppId is still a placeholder. - Remove the version-bump step that called scripts that don't exist and pushed to a branch the tag checkout doesn't have. - EAS CLI ^13 -> ^25. RELEASING.md updated to match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0ed6fd550b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- ChatScreen: clear the single-flight session-create promise in finally, so one rejected create doesn't leave every later send stuck on it. - ChatScreen: once the user message is saved, a later failure no longer restores the draft (a retry would save it twice); it says the reply couldn't be saved instead. - getAllChatSessions(): merge in the legacy sessions getChats() returns when migration fails, so export/stats don't show zero chats. - release.yml: submit by the build ID from this run instead of --latest, so overlapping runs can't submit the wrong build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Delete ChatScreen, the chat API client and its test, and the now-unused newId helper. Drop the Chat tab (a11y labels now "tab N of 4"), the Today "Open Fernly" card, the deprecated CrisisModal matchedPhrase prop, and stale ChatScreen references (eslint override, CODEOWNERS, SECURITY.md). Chat storage and crisis detection are kept so old chats can still be exported and deleted by Reset. Ignore .superpowers/ in prettier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Covers the "corrupt storage" review-focus case directly (previously only the non-array case was tested). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
Clears the critical shell-quote advisory and other fixable transitive advisories. Remaining high advisories (node-forge, braces, image-size) are in Expo CLI / Metro build tooling with no non-breaking fix upstream. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB
|
CI status: Why it isn't this PR's code: the failing advisories are in transitive dependencies of What I pushed (d3d531b): Still failing (no non-breaking fix upstream):
These are build/dev-server tools, not code shipped in the app binary. Fixing the step needs a policy decision from the owner (e.g. lower the gate to Generated by Claude Code |
Summary
This PR has two parts.
Part 1 — fixes (reviewed earlier)
npm ci(eslint 10 / react-dom mismatch from Dependabot); Dependabot grouping + eslint-major ignore.eas.json, gate on CI, submit by build ID).Part 2 — free guided-meditation redesign
Spec:
docs/superpowers/specs/2026-10-18-free-meditation-library-design.md· Plan:docs/superpowers/plans/2026-10-18-free-meditation-library.mdsrc/data/sessions.ts, scriptscontent/scripts/*.md, audioassets/audio/*.m4a(silent placeholders for now).scripts/generate-audio.ts(dev-only, OpenAI TTS + ffmpeg) + parser tests over every script.expo-audio): background + lock-screen controls, back-15s, progress; completion at ≥ 90 %, once per play-through.scripts/check-audio.tsruns inrelease.ymland blocks a release while placeholder audio is present.Testing
npm ci+npm run ci: typecheck, lint, format, 230 tests pass.npx expo export --platform webbuilds; Playwright screenshots of all tabs, help modal, onboarding.Before release (owner)
content/scripts/.OPENAI_API_KEY=… npx tsx scripts/generate-audio.ts sos-panic(one session first; TTS params unverified), then all; updatedurationSecfrom its output; commit audio.ascAppIdineas.json.🤖 Generated with Claude Code
https://claude.ai/code/session_012Y4Z1cauBe8qpx7pDxmDmB