Skip to content

refactor(core): move the Inbox thread's pure rules into @plannotator/core - #2224

Merged
backnotprop merged 4 commits into
mainfrom
refactor/inbox-thread-core-move
Oct 27, 2026
Merged

backnotprop merged 4 commits into
mainfrom
refactor/inbox-thread-core-move

Conversation

@backnotprop

@backnotprop backnotprop commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Slice 1 of the Inbox thread extract (plan record, not in this repo). The Inbox thread's pure rules move into @plannotator/core unchanged, so a host of the shared thread parts can use the Inbox's own rules. Plannotator's behaviour does not change.

From (packages/inbox) To (packages/core, new subpath)
folding.ts inbox-folding.ts (@plannotator/core/inbox-folding)
deliveryLine.ts inbox-delivery-line.ts (./inbox-delivery-line; inbox-delivery.ts already exists)
openQuestions.ts inbox-open-questions.ts (./inbox-open-questions)
format.ts inbox-format.ts (./inbox-format; openQuestions needs its formatCount)
  • Only the import specifiers change. @plannotator/core/x becomes ./x, and ./format becomes ./inbox-format. git diff origin/main:packages/inbox/folding.ts :packages/core/inbox-folding.ts (and the same for the other three) shows import lines only. The modules stay browser-safe and import only core.
  • The old paths are export * shims, so every importer (60+) and every test (folding.test.ts, deliveryLine.test.ts, format.test.ts, openQuestions.test.tsx, rowDelivery.test.ts …) runs unedited.
  • Core gets 4 new exports. files (**/*.ts) already ships them. No version bump: the owner publishes core by hand.
  • The inbox- prefix keeps inbox-e2e.yml triggering on packages/core/inbox*.
  • Pi: vendor.sh needs nothing. Pi imports none of these modules, and its core vendor list is explicit.
  • Docs: packages/ui/HANDOFF.md gets a new section (marked experimental until Workspaces ships on these subpaths). The guide paths in inbox-messages.md, inbox-window.md and inbox-compose.md now point to the new subpaths.

Proof (local, dev builds, sandboxed)

All of this was run on the branch with origin/main 86538b3 (0.28.32) merged in. The merge brought main's reload-hosts change to deliveryLine.ts (#2213: restartNote for Pi, Oh My Pi and OpenCode 2). It is carried into packages/core/inbox-delivery-line.ts unchanged: each of the four core files still differs from main's packages/inbox original only in its import lines. The guide conflict in inbox-messages.md takes main's text, with waitCount pointing at @plannotator/core/inbox-format.

  • Parity harness (test(inbox): pixel and DOM parity harness for the thread #2222, with its follow-ups), a dev build of this branch against a dev build of its merge-base 86538b3: 709 screenshots compared at zero pixels and 829 outerHTML and page-error files. The DOM is identical in all 829 files. One screenshot differs, iphone-15-dark/choices-year-later.png, by 12 pixels. All of them are on the single pixel row where the thread's scroller clips a picture tile, a few colour levels apart. That is WebKit raster noise: the same capture differed when main ran against itself, and its DOM matches. A second main-vs-main run was identical (709 and 829, 0 differing).
    • The harness covers: the list's rows; each thread page by page, expanded, with its open questions and Artifacts; tooltips; the Files band; later clocks (3 and 400 days on); the 👍 Undo window; and live delivery (Undelivered, Send now, the restart line).
    • It runs on: desktop light and dark; the pane at 360 px light and dark, and at 320 px; iPhone 15 (WebKit) light and dark; Pixel 7.
  • Earlier harness runs (199 screenshots, 239 DOM files) were IDENTICAL against 948fe2f and against e789a3d. The expanded harness (708/828) was IDENTICAL against e789a3d.
  • Unit tests only: format.ts's yesterday branch is covered by the unedited format.test.ts.
  • Build order review → hook → opencode → pi, against main 86538b3 built the same way:
    • Every built HTML is byte-identical: apps/hook/dist/{index,review,inbox,surface,redline}.html, apps/review/dist/index.html, and the OpenCode and Pi copies.
    • Pi and OpenCode npm pack --dry-run are identical: 306 and 17 files, same sizes, same tarball shasum.
  • bun run typecheck: passes. It covers core's own tsconfig (types: [], so no node:), packages/inbox, apps/inbox, packages/ui/tsconfig.strict-consumer.json and Pi's vendor step.
  • bun test packages/inbox packages/core plus packages/server/inbox-thread-folding.test.ts: 0 fail.
  • DOM list, the CI way (the 3 DOM_TESTS=1 steps of today's test.yml, the third with --isolate): 6 pass, 40 pass, then 2937 pass with 1 skip. 0 fail.
  • Inbox e2e on this branch's binary:
    • inbox-reload-hosts, inbox-restart and inbox-send-now, which draw the moved delivery line: 14 passed, 1 skipped.
    • The full test:e2e:inbox before main 0.28.32: 517 passed. Its two timing flakes passed on rerun.

Not merged, and no versions bumped.

…core

Slice 1 of the Inbox thread extract. folding.ts, deliveryLine.ts,
openQuestions.ts and format.ts move from packages/inbox to core as
inbox-folding, inbox-delivery-line, inbox-open-questions and inbox-format
(the inbox- prefix keeps the Inbox e2e workflow triggering). Only their
import specifiers change (@plannotator/core/x -> ./x, ./format ->
./inbox-format). The old paths are export * shims, so every Inbox import
and test runs unedited. Four new core subpaths; no version bump (the
owner publishes core by hand).
…-core-move

# Conflicts:
#	docs/agent-guides/inbox-messages.md
#	packages/inbox/deliveryLine.ts
@backnotprop
backnotprop merged commit 4c2c9ae into main Oct 27, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant