v2.0.3 fix: decode XML-plist recurrence rules, hide templates from someday#2
Merged
Conversation
Current Things writes the recurrence rule as an XML plist (fu=NSCalendarUnit, fa=interval, of=weekday/day), not the binary-plist format the decoder sniffed for, so every repeat read as UNKNOWN. Rewrite the decoder to parse it. Repeating-task templates are stored with start=2 (same as Someday) but the app hides them; somedayTasks and the stats someday count now exclude rows with a recurrence rule so templates stop masquerading as Someday tasks. rt1_nextInstanceStartDate is a bit-packed calendar date, not Unix seconds — decode it with thingsDateToIso/formatThingsShortDate instead of the never-true >= 1e9 guard. Fixture emits real recurrence XML plus a Someday-template row; regression tests cover the someday exclusion, frequency decode, and next-instance date.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
Two recurring-task bugs, both from the same wrong-format assumption as 2.0.2 — the code expected an older recurrence encoding that current Things no longer writes. Found while auditing a real database where
somedayreturned 26 items (app showed ~10) and every repeat decoded asUNKNOWN.src/lib/rrule.js— recurrence decoder rewrite. Current Things storesrt1_recurrenceRuleas an XML property list (fu= NSCalendarUnit unit: 4=year, 8=month, 16=day, 256=weekday;fa= interval;of= weekday/day-of-month), not the binary-plistfrequency/intervalformat the old heuristic sniffed for. Parse the XML so cadences decode (every week,every 2 weeks,every month,every 2 days).src/lib/queries.js+src/commands/stats.js— stop templates leaking into Someday. Repeating-task templates are stored withstart = 2(same value as Someday); the app hides them and shows only generated instances.somedayTasksand thestatssomeday count now exclude rows with a recurrence rule.src/commands/repeating.js— next-instance decoding.rt1_nextInstanceStartDateis a bit-packed calendar date, not Unix seconds. The old>= 1000000000guard was never true for packed dates, sonextInstancewas always null. Now decoded withthingsDateToIso/formatThingsShortDate.Test Coverage
test/fixtures/build.js: fixture now emits real recurrence-rule XML and adds a Someday-template row (start=2,todayIndex=0, recurrence rule) that reproduces the real-DB leak.test/integration/lists.test.js: someday excludes the template; repeating lists it and decodesfreq/interval; nextInstance resolves to a real calendar date.test/unit/rrule.test.js: decodes daily/weekly/monthly/yearly fromfu, reads interval fromfa, extracts weekday/day-of-month, accepts string or Buffer.Tests: 79 → 79 passing (added recurrence + someday-exclusion regression cases).
Verification (real database)
someday: 26 → 10 items (templates gone, matches the app)repeating: all 33 repeaters decode with cadence + next-instance date (genuinely-null next-instances stay null)Pre-Landing Review
Self-reviewed; no SQL/trust-boundary/side-effect issues (read-only queries, no user input interpolated). No prompt files (evals skipped), no frontend (design review skipped).
Test plan
🤖 Generated with Claude Code