Sign in
Join now
chalky.town
tyler.fun
/
Star
Starred
Star
Something went wrong. Try again.
Fork
0
Eye filled
Watch
Watching
Watch
a local-first atmospheric chalky task planner
Star
Starred
Star
Something went wrong. Try again.
Fork
Eye filled
Watch
Watching
Watch
Overview
Overview
Issues
Issues
Pulls
Pulls
Pipelines
Pipelines
chalky.town
/
src
/
lib
5 folders
·
19 files
at
main
tyler.fun
·
app: checking a task off checks off its subtasks too — toggleDone folds the unchecked subtasks (stamped with completedAt) into the same patch as done, so one undo reverts both; un-checking leaves subtasks as they are. Recurring occurrences are excluded: their subtasks live on the series template, so checking them would check them on every day of the series. Not gated on the auto-done setting. Verified in the preview by clicking the checkbox on a 1/2 task (became 2/2, both stamped; un-check left both checked); not exercised signed-in; pnpm check 0 errors 0 warnings
·
4d ago
ecfe6e95
atproto
deps: atproto Spaces alpha SDK moves to the 2026-10-22 build (0.0.0-spaces-alpha-20261022141228, published 13 min after atproto ac0c9f1, the next pds-spaces-alpha image), and space reads accept either PDS build's commit shape so this client deploys ahead of the PDS flip — ac0c9f1 replaced `#signedCommit` {ver,hash,ikm,sig,mac,rev} with `#commit` {ver,repo,space,rev,data}, and the SDK validates every response, so the 10-15 SDK rejects the new PDS's getLatestCommit and any listRepoOps page that reaches the head (every sync cycle), and the 10-22 SDK rejects the old PDS's the same way. repo.ts's commitShapeMismatch takes a body rejected at Output/commit as-is: head() reads commit.rev (both shapes carry it), listOps() drops the unused commit and re-validates the rest, so a page wrong anywhere else still throws. Drop it once bag.laugh.town runs ac0c9f1. The rest of the range doesn't touch chalky: commit MACs only apply to space-credential / Atproto-Space-Want-Mac reads (OAuth reads skip them), getRepo (CAR→STAR, excludeValues gone) and getSpaceCredential (auth in body) aren't called, and the only DID-doc entry read is #atproto_pds, not #atproto_space. oauth-client-browser's dist is byte-identical, so the WebKit null-IDB patch carries over (renamed; same patch_hash). Verified by driving SpaceRepo through Vite SSR against mocked responses: main fails head/listOps on the new shape, the bump alone fails on the old one, bump + fallback passes on both and still rejects a page with invalid ops; not exercised signed-in against a real PDS; pnpm check 0 errors 0 warnings, pnpm build ok, Dockerfile build ok
1w ago
components
app: a repeating task's details card dates its header by the day it was opened from, not the series start — whenLabel read task.day, which for a recurring task is the anchor, so Movie night (weekly on Fri since Aug 7) opened from Oct 23 said 'Fri, Aug 7'. It now uses ui.detailsDay for recurring tasks (the same open day repeatAnchor and snooze already use) and falls back to task.day; non-recurring tasks keep task.day so a task moved with the card open never shows a stale day. Found while taking atstore.fyi screenshots. Not verified in the browser; pnpm check 0 errors 0 warnings
1w ago
db
app: sync survives iOS PWA suspension — cycle watchdog + reopen the OAuth client's dead IndexedDB connection (r.expiresAt crash, then a hung cycle wedged the loop until relaunch), idb.ts drops/retries dead connections; drop the SVG-filter chalk grain — Safari re-rasterized it on every repaint, 30–60Mpx frames mid-drag
1mo ago
fonts
app: self-host the Gluten webfont so it renders offline
3mo ago
store
app: checking a task off checks off its subtasks too — toggleDone folds the unchecked subtasks (stamped with completedAt) into the same patch as done, so one undo reverts both; un-checking leaves subtasks as they are. Recurring occurrences are excluded: their subtasks live on the series template, so checking them would check them on every day of the series. Not gated on the auto-done setting. Verified in the preview by clicking the checkbox on a 1/2 task (became 2/2, both stamped; un-check left both checked); not exercised signed-in; pnpm check 0 errors 0 warnings
4d ago
checklist.ts
app: add console occurrence migration, nested checklist paste, click-to-open Someday
3mo ago
config.ts
app: integer-only order/rank on the wire — lex-data rejects floats, so halved orders and x.5 movedRanks stranded dirty edits behind a failing batch; day renumbering, scaled integer `rank` (legacy movedRank read ×1024), wire-boundary coercion, per-record push failures no longer abort the rest; recurring drag reorders the series template; patch oauth-client-browser to treat WebKit's null IDB miss as not-found (r.expiresAt crash) and stop reopening on it
1mo ago
date.ts
app: the month grid no longer shows a fall-back DST day twice — addDays stepped in 24h of ms, so on a 25h day (Oct 25 in Europe, Nov 1 in the US) midnight + 24h landed on 23:00 the same day: the grid printed it twice and every later cell was a day off, next-week navigation from that week landed back in it, and an "after N times" daily/weekly recurrence could compute its until bound a day early. addDays now steps by calendar date like shiftKey. Verified: October grid and +7d correct under Europe/Warsaw, America/New_York, Australia/Sydney and UTC; November grid in the LA preview shows Nov 1 once; pnpm check 0 errors 0 warnings
2w ago
debug-cursor.ts
app: re-prime cursor paint on tab wake to heal the stuck pencil
2mo ago
demo.ts
app: add a read-only /demo/<handle> board
2mo ago
export.ts
app: add task sort strategies, simplify copy menu, drop occurrence migration
3mo ago
haptics.svelte.ts
app: full-height drag drop zones, touch haptics + press-and-hold drag
3mo ago
hlc.ts
app: field-level LWW sync on hybrid logical clocks
1mo ago
linkify.ts
app: 3-day view, malleable sort with pinnable manual order, clickable subtask links
1mo ago
markdown.ts
app: right-click a subtask for Copy / Delete — the details panel's checklist rows open the shared ContextMenu (above the panel, z 45 over 41) via a new ui.subContext {taskId, subId, day}. Copy writes the subtask's plain text (autolink brackets unwrapped, no checkbox prefix); Delete goes through store.setSubtaskText(…, "", day) like the row's trash button, so one undo restores it. The edit textarea keeps the native menu and Ctrl+Shift stays the fast-delete. The menu's Escape now listens in capture and stops there, so it closes only the menu, not the details panel under it. Verified in the preview with synthesized contextmenu events: Copy → "second https://example.com", Delete drops the row and ⌘Z brings it back, body Escape leaves the panel open
3w ago
oauth-scope.ts
app: private mode syncs direct to the PDS via atproto Spaces — HappyView retired
1mo ago
palette.ts
app: hueful replaces the hand-rolled colour math - palette.ts drops hexToRgb/relativeLuminance/contrastRatio for hueful's WCAG 2 contrast (inkFor keeps its rule: LIGHT_INK only when strictly higher than DARK_INK, anything unparseable gets DARK_INK), and a new normalizeHex turns any CSS colour hueful parses (3/4/8-digit hex, rgb(), hsl(), oklch(), names like rebeccapurple, bare hex without the #) into the lowercase 6-digit #rrggbb that stored records and --hl-<id> vars expect, rounding and clamping channels (hueful doesn't clamp, so out-of-gamut oklch lands on the gamut edge) and dropping alpha. The picker's color text field now routes through it, so typing rebeccapurple or oklch(0.7 0.15 30) works; the aria-label is Color value. hueful pinned at 0.7.0 (MIT, zero deps) and listed in THIRD_PARTY_LICENSES.md. Presets, defaults, ids and the lexicon are untouched. Verified: no test runner in the repo, so a throwaway node:test file checked inkFor (#ffa3a3 dark ink, #1a1a40 light ink, junk dark ink, every default and preset dark ink) and normalizeHex (#fa0 -> #ffaa00, rebeccapurple -> #663399, oklch(0.7 0.15 30) -> #ed7665, rgb(10 20 30 / 0.5) -> #0a141e, oklch(0.7 0.4 30) -> #ff0000, garbage and empty -> null); pnpm check 0 errors 0 warnings; pnpm build ok
3w ago
recur.ts
app: build the repeat picker with richer recurrence rules and per-occurrence records
3mo ago
share-stats.ts
app: drag-to-reorder no longer gets worse the longer a drag goes on, plus a dependency sweep — svelte-dnd-action 0.9.74's getBoundingRectNoTransforms read rect.x/rect.y off getVisibleRectRecursive's result, which has neither, so any row measured mid-flip came back NaN; the shadow-rect cache (cleared only on scroll or drop) then held a NaN for that index and its hysteresis check pinned the placeholder whenever the pointer reached that row, one more row per flip the observer happened to catch. Upgraded to 0.9.80 (upstream reads rect.left/top) and re-ported both chalky patch hunks (no synthetic click on touchend with delayTouchStart; no preventDefault on touch handle starts). Also: svelte 5.57.2, vite 8.3.4, vite-plugin-svelte 7.3.1, svelte-check 4.7.7, bits-ui 2.19.5, @lucide/svelte 1.59.0, milkdown crepe+kit 7.22.3, marked 18.1.1, idb 8.0.4, typescript 6.0.3, @types/node 24.19.2, hueful 0.8.1, satori 0.62.0. Satori now lays out with Taffy (layout.wasm replaces yoga.wasm) and defaults to content-box, which pushed the share cards' padding outside every fixed width (values off the right edge, footer cut, tiles two per row) — the card helper sets boxSizing border-box; THIRD_PARTY_LICENSES swaps yoga-layout for taffy. Held back: TypeScript 7 (svelte-check refuses it), @types/node 26 (runtime is Node 22), the atproto spaces-alpha SDK (must match the PDS build; separate task). Verified in the visible preview: a scripted 25s drag left 6 of 7 targets on the wrong row before and 0 after; both share cards render 1080x1350 and look right; hueful's normalizeHex/inkFor outputs unchanged; notes editor renders; pnpm check 0 errors 0 warnings; pnpm build ok (main chunk +17KB vs live); touch not exercised on a device
2w ago
stats.ts
app: a Stats page in the account menu, shareable as two images, and a setting to hide it — stats.ts computes usage from the local store (tasks created/done, current and best daily streak, active days, busiest day, median created→done and same-day share, peak hour, done per weekday, created/done per month, color counts, still open / in idk when, moved, notes, subtasks, recurring series and occurrence hits; tombstones skipped, local time). StatsModal shows it as tiles plus bar rows (palette-colored for colors) and is wired like Credits: ui.statsOpen, ?panel=stats, Escape. Share renders two 1080×1350 cards (headline tiles + odds and ends; months, colors, weekdays), both titled "chalky.town stats", with Satori in the chalkboard palette, pre-rendered when the modal opens so the tap hands them to navigator.share inside Safari's user activation; where files can't be shared (or the share is refused) an in-app menu previews both with Copy and Save per card and a Post to Bluesky draft — never a silent download (the first version downloaded two files and browsers dropped the second, which is why the shared image looked empty). Satori is pinned to 0.33.5 (the four releases from the last day skipped) via its standalone build, initialized with yoga.wasm by URL; harfbuzzjs fetches /hb.wasm from the page directory, so a small vite plugin serves it in dev and emits it in the build; Gluten comes from @fontsource/gluten 5.3.0's woff files since Satori can't read woff2. All of it lazy-loads on the first Stats open. Settings gains "Hide the Stats page" (settings.hideStats, synced through town.chalky.config's new hideStats field, lexicon updated but not yet republished), which drops the menu item and ignores ?panel=stats. THIRD_PARTY_LICENSES lists satori (MPL-2.0), yoga-layout and harfbuzzjs. Verified: page numbers match an independent count of the PDS space records; both cards checked visually; iOS 26 simulator Safari opens the native share sheet with the PNG; the preview pane falls back to the menu; hide toggles both ways; pnpm check 0 errors 0 warnings; pnpm build ok
3w ago
swipe.ts
app: swipe sideways to page the board — a one-finger flick over Day, 3 Day or Week steps it like ←/→ (a day, the window by a day, a week), with a light haptic and a 180ms slide-in (skipped under reduced motion). Touch events, passive, judged on lift: axis locks after 10px so a scroll that starts vertical stays one; needs ≥60px, |dx| ≥ 2|dy|, under 700ms. Ignored from the 24px screen edges (Safari's back swipe), text fields/editors, sideways scrollers, and while a drag, marquee, inline edit, details panel or context menu owns the touch. Month is excluded (its grid scrolls sideways on phones) and Someday sits outside the wrapper. Verified in the preview at 375px with synthesized touches: day 10-05→06→07→06, week 10-12→19→12, 3 Day 10-13→14; month, Someday, vertical-ish and edge swipes don't move
3w ago
sync-log.ts
app: add a persistent sync debug trail for the debug account
2mo ago
types.ts
app: integer-only order/rank on the wire — lex-data rejects floats, so halved orders and x.5 movedRanks stranded dirty edits behind a failing batch; day renumbering, scaled integer `rank` (legacy movedRank read ×1024), wire-boundary coercion, per-record push failures no longer abort the rest; recurring drag reorders the series template; patch oauth-client-browser to treat WebKit's null IDB miss as not-found (r.expiresAt crash) and stop reopening on it
1mo ago
url.ts
app: a Stats page in the account menu, shareable as two images, and a setting to hide it — stats.ts computes usage from the local store (tasks created/done, current and best daily streak, active days, busiest day, median created→done and same-day share, peak hour, done per weekday, created/done per month, color counts, still open / in idk when, moved, notes, subtasks, recurring series and occurrence hits; tombstones skipped, local time). StatsModal shows it as tiles plus bar rows (palette-colored for colors) and is wired like Credits: ui.statsOpen, ?panel=stats, Escape. Share renders two 1080×1350 cards (headline tiles + odds and ends; months, colors, weekdays), both titled "chalky.town stats", with Satori in the chalkboard palette, pre-rendered when the modal opens so the tap hands them to navigator.share inside Safari's user activation; where files can't be shared (or the share is refused) an in-app menu previews both with Copy and Save per card and a Post to Bluesky draft — never a silent download (the first version downloaded two files and browsers dropped the second, which is why the shared image looked empty). Satori is pinned to 0.33.5 (the four releases from the last day skipped) via its standalone build, initialized with yoga.wasm by URL; harfbuzzjs fetches /hb.wasm from the page directory, so a small vite plugin serves it in dev and emits it in the build; Gluten comes from @fontsource/gluten 5.3.0's woff files since Satori can't read woff2. All of it lazy-loads on the first Stats open. Settings gains "Hide the Stats page" (settings.hideStats, synced through town.chalky.config's new hideStats field, lexicon updated but not yet republished), which drops the menu item and ignores ?panel=stats. THIRD_PARTY_LICENSES lists satori (MPL-2.0), yoga-layout and harfbuzzjs. Verified: page numbers match an independent count of the PDS space records; both cards checked visually; iOS 26 simulator Safari opens the native share sheet with the PNG; the preview pane falls back to the menu; hide toggles both ways; pnpm check 0 errors 0 warnings; pnpm build ok
3w ago