Skip to content

Interleave v0.1.1 — grade cards in the process loop + queue/review hardening

Choose a tag to compare

@antoinefink antoinefink released this 01 Jun 06:05
· 370 commits to main since this release
0d2b2e0

A hardening release on top of v0.1.0, focused on the daily queue + review surfaces. No new features — the incremental-reading loop is the same — but the one-at-a-time process loop is now a first-class review surface, plus a round of correctness, design, and test fixes across the stack.

Headline fix — grade cards inline in the process loop

In v0.1.0, when a card came up in the /process one-at-a-time loop you couldn't actually review it: the card face showed a placeholder ("grading lands with the review session") and an Open in review button that bounced you out to /review. That was a leftover stub from before the FSRS review session existed.

Now a card grades inline, end to end, without leaving the loop — exactly as the milestone intended ("process ten mixed sources/extracts/cards without returning to a list"):

  • Space reveals the answer (cloze unmasks / Q&A answer + the source reference appear).
  • 1–4 grade Again / Hard / Good / Easy, with next-interval previews.
  • The grade writes a durable review_logs row, advances FSRS, and the cursor moves to the next item — all in /process.
  • A shared CardFront component now backs both /review and /process, so the two card faces can't drift apart again.

This is verified by a new end-to-end test that grades a card inside /process and confirms the review log survives an app restart.

Other hardening (per-component deep-review pass)

  • Queue domain — a card's thin "postpone" defer no longer flips its lifecycle status onto the attention scheduler (the FSRS-vs-attention split is preserved); fresh-DB topic-interval now resolves to the canonical 7-day default instead of falling through to the by-priority band.
  • IPC boundary — malformed asOf clocks are rejected at the typed boundary so an Invalid Date can never reach FSRS or land in review_states / review_logs; leech-marking is guarded to cards only.
  • Review session — guards against a double-grade; the progress meter reaches 100% when cards are removed (suspend/delete) without a grade; the leech "Add context" affordance and the repair bar share one source-context drawer; a hardcoded overlay color became an OKLCH design token.
  • Queue list — keyboard-navigation bounds, selection state, and an accessible empty state.
  • Home command center — per-type row routing respects the FSRS/attention split; failed reads render a calm em-dash placeholder instead of fabricated zeros or a false "Queue clear".

Also since v0.1.0: native-pnpm CI (typecheck · lint · test · renderer build), README screenshots, and the agent build/deep-review workflow skills.

Quality gates (all green at this commit)

  • pnpm typecheck — 10/10 projects
  • pnpm lint — Biome clean (354 files)
  • pnpm test — Vitest 1040 passing (89 files)
  • Targeted pnpm e2e — process-queue (incl. the new inline-grade + restart test), review, review-edit, sibling-burying, leech, queue, home — all passing
  • pnpm --filter @interleave/desktop dist — produces the .dmg below

⚠️ Re-download if you grabbed this before Jun 1. The first v0.1.1 DMG failed with "Interleave is damaged and can't be opened" (it shipped without a valid code signature). The asset below has been replaced with an ad-hoc-signed build that launches correctly. It also now carries the real Interleave app icon instead of the default Electron icon.

Install

  1. Download Interleave-0.1.1-arm64.dmg below (requires an Apple-Silicon / arm64 Mac), open it, and drag Interleave to Applications.
  2. The build is ad-hoc signed but not notarized, so clear the download quarantine once — right-click → Open does not work for this (and that menu item was removed in macOS Sequoia):
    xattr -dr com.apple.quarantine /Applications/Interleave.app
  3. Open Interleave normally.

A fully Developer-ID-signed + notarized build (no xattr step) is a planned later release.

sha256(Interleave-0.1.1-arm64.dmg) = 36e2740cbea6a731dacbb476844517e6c3dd19f71e915a1880f9c978ab58f52e

Full changelog: v0.1.0...v0.1.1