Fix blank screen on detail view for projects with no filesystem paths#53
Merged
Merged
Conversation
Core's toFull() omits the `paths` field entirely when a project has no filesystem paths (non-code projects: trips, partnerships, tutorials), but the renderer's ProjectFull type declared `paths: string[]` as always present. ProjectDetailView read `project.paths.length` unguarded, throwing a TypeError on every render. With no React error boundary in the tree, that throw unmounted the whole app — a blank screen with no recourse. - api.ts: ProjectFull.paths is now optional, matching reality and the rest of the renderer's guards (so TypeScript catches this class of bug). - ProjectDetailView.tsx: guard the three `project.paths` reads. - ErrorBoundary.tsx + App.tsx: wrap the view switch so a single view's render throw shows a recoverable card instead of blanking the app. - e2e: regression test — a path-less project's detail view renders fully and the error boundary does not fire. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014iR9LcchEebnoyt5GLRzev
The packages/skills workspace (added in 494f778, the prototype-driven migration) was committed without updating the root lockfile, and the release commits bumped workspace versions beta.11 -> beta.21 without re-running install. `npm ci` therefore fails with "Missing: @setlist/skills from lock file", breaking the CI `check` job on every PR. check.yml only runs on pull_request (not push to main), so the breakage stayed invisible until the first PR after the migration. Regenerated with `npm install --package-lock-only` — only package-lock.json changes (skills workspace entry + workspace version sync, no third-party dependency changes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014iR9LcchEebnoyt5GLRzev
Owner
Author
🤖 Codex review — APPROVELocal Codex review of this PR's changes against No blocking correctness, security, IPC-contract, or better-sqlite3 ABI issues found in the HEAD vs origin/main diff. Static review covered the changed source, generated Electron output, and surrounding path/IPC call sites. I could not run typecheck/tests because this worktree has no node_modules installed. No issues found. |
This was referenced Jun 25, 2026
spaceshipmike
added a commit
that referenced
this pull request
Jun 25, 2026
First /close. Reconciles the model against the blank-screen fix (#53): - INVARIANTS: + projection-optionality contract (PROSE); + two CI open tensions (renderer types unchecked in CI; CI not run on push to main). - SURFACES: + "core projection shape ↔ consumer types" cross-cutting edge. - MODEL_DECISIONS: + D-006 (local Codex review + hosted CI; no self-hosted runner because setlist is public). - lessons.md: + #desktop-app candidate (esbuild doesn't typecheck the renderer; add an error boundary so a render throw can't blank the app). - steward.json: establish lastClose marker. Follow-ups filed: #55 (renderer tsc in CI), #56 (CI on push to main). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014iR9LcchEebnoyt5GLRzev
2 tasks
spaceshipmike
added a commit
that referenced
this pull request
Jun 25, 2026
Ships the blank-screen fix (#53): detail views for projects with no filesystem paths now render instead of crashing the renderer. Includes the lockfile sync, agent-model reconciliation, and the local Codex review script. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014iR9LcchEebnoyt5GLRzev
spaceshipmike
added a commit
that referenced
this pull request
Jun 25, 2026
Second /close. Covers the post-#53 work (#54 Codex script, RELEASING.md runbook, the notarized beta.22 release). INVARIANTS: filled the 'Release / propagation' placeholder with a PROSE invariant (CI-only notarized distribution; tag==versions+lockfile; tag/secrets clauses already ENFORCED by release.yml). lessons: +#desktop-app candidate (single-instance-lock-on-shared-userData trap; e2e tests out/ not the packaged artifact). Follow-up #57 (lockfile-sync gate). steward marker → 7b443be. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014iR9LcchEebnoyt5GLRzev
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Clicking certain projects blanked the entire app, not just the detail pane.
Two compounding bugs:
toFull()(packages/core/src/models.ts:318) omits thepathsfield entirely when a project has no filesystem paths (non-code projects: trips, partnerships, the tutorial). But the renderer'sProjectFulltype declaredpaths: string[]as always-present, soProjectDetailViewreadproject.paths.lengthunguarded →TypeErroron every render.Reproduced against the real registry DB: exactly 4 path-less projects crashed the detail view (
claude-tutorial,country-visit-aug-2026,prague-trip-2026,stray-dog-partnership).Fix
paths?: string[](was required)api.tsproject.pathsreadsProjectDetailView.tsxErrorBoundary, wrapped around the view switchErrorBoundary.tsx,App.tsxVerification
Notes (pre-existing, not addressed here)
main(RegisterProjectDialog.tsx:161,OverviewTab.tsx:55) that the esbuild build silently ignores — this is how thepathstype-lie survived. Worth a follow-up to wiretsc --noEmitinto CI.🤖 Generated with Claude Code