Commit log

c217644 docs(readme): remove license badges

Amolith created

d2e95ff docs(readme): add liberapay badge

Amolith created

b44d4a7 docs(license): add service license

Amolith created

8c2f6ec fix(web): restore title display after edit

Click to expand commit body
When editing the room title, roomTitleEl.style.display was set to
'none'
but never restored when the edit finished. This caused the title to
remain
hidden until the next WebSocket message triggered renderTitle().

Closes: 4eba213
Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

5a10305 fix(client): graceful websocket reconnect

Click to expand commit body
- replace disconnect alert with automatic retry/backoff while UI stays
  disabled
- pause keyboard shortcuts when the list is offline so input waits for
  reconnection

Closes: bug-fab8338
Assisted-by: GPT-5 via Crush

Amolith created

84017f1 fix(ui): align Add all button to right side

Click to expand commit body
Implements: 73ce387
Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

8b632d5 feat(db): track all room activity types for expiry

Click to expand commit body
Room expiry now tracks ALL activity, not just creation timestamps:
- Voting and unvoting
- Resetting votes
- Editing items
- Deleting items
- Setting room title
- Breaking ties

Added last_activity column to rooms table (schema v3→v4). All
activity operations now update this timestamp. deleteInactiveRooms
simplified to use last_activity directly instead of complex joins.

Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

d3b89a5 docs(contrib): add example systemd service

Amolith created

053f344 feat(cli): add host and port config flags

Click to expand commit body
Add CLI arguments to configure server bind address and port:
- --host : Bind to specific interface (default: localhost)
- --port : Listen on specific port (default: 8294)

Update documentation in README.md and AGENTS.md to reflect new options.
Use onListen callback to suppress Deno's default "Listening
on..." message.

Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

7970b61 docs(agents): update AGENTS.md

Click to expand commit body
- Reflect ES module split (app.js → render.js/ui.js)
- Document tie-breaker protocol (break_tie/tie_broken)
- Note daily inactive-room cleanup
- Update file structure, noscript fallback, and protocol/testing details

Assisted-by: GPT-5 via Crush

Amolith created

3361523 feat(cleanup): auto-expire inactive rooms daily

Click to expand commit body
Adds deleteInactiveRooms() function to db.ts that finds and removes
rooms
where the most recent item or vote activity is older than 30 days.

The cleanup runs automatically on server startup and then every 24 hours
via setInterval. Foreign key CASCADE constraints handle automatic
deletion
of associated items and votes.

Implements: b3d438a
Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

e55e9aa fix(frontend): add module type to script tag

Click to expand commit body
The refactor in HEAD^ split app.js into modules with import statements,
but the script tag wasn't updated to support module syntax, causing
'Uncaught SyntaxError: import declarations may only appear at top
level
of a module' and breaking deep links and room joining.

Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

3985247 feat(frontend): add noscript fallback message

Click to expand commit body
Users without JavaScript enabled now see a helpful message explaining
that Sift requires JavaScript to function, with an explanation about
WebSocket requirements.

Implements: 6a9a677
Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

0e4b2fc refactor: split large files into focused modules

Click to expand commit body
Extract database operations to db.ts, rendering utilities to render.js,
and UI handlers to ui.js. This keeps files under 500 lines and improves
maintainability.

Also fix all lint issues:
- Replace 'as any' with proper message type interfaces
- Remove unused isReady variable
- Wrap switch case blocks with braces
- Replace window with globalThis

Implements: 09cd703
Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

8369950 fix(frontend): scroll only on local actions

Click to expand commit body
Previously, the selected item would scroll into view on every render,
including when receiving updates from other clients. Now scrolling only
occurs when the user performs a local action (voting, deleting, or
navigating with keyboard).

Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

524fdcb feat: add tie-breaker button for top-score ties

Click to expand commit body
When multiple items share the top score, a 'Break the tie'
button appears
above the list. Clicking it sends a break_tie message to the server,
which
randomly selects one of the tied items and broadcasts the winner to all
clients. The result is displayed next to the button and clears when
votes
change or the tie is resolved.

Server uses crypto.getRandomValues for uniform random selection. No
database
writes are performed; the winner is ephemeral and only shown until state
changes.

Implements: 95021dc

Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

650505f feat(frontend): add source code links

Click to expand commit body
Implements: 55d3982
Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

f5e8a99 docs(readme): add light mode to scrot

Amolith created

de37d81 feat: add OKLCH palette and visual enhancements

Click to expand commit body
Introduces a comprehensive OKLCH-based color system via palette.css,
replacing the previous RGB/hex approach with perceptually uniform
colors.
Adds visual feedback for top-voted items with checkmark indicator and
3D tactile button press effects. Room URLs now auto-update to include
the room code for easier sharing.

The new palette provides better dark mode support and color consistency
across the interface while maintaining the existing green theme
identity.

Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

9c93bf2 docs(readme): update scrot

Amolith created

ce000a1 fix(web): use svg icon for copy button feedback

Click to expand commit body
Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

cb1f447 docs(readme): try to fix image, fix bullets

Amolith created

2ecf809 fix(web): restore SVG icons after copy action

Click to expand commit body
Copy buttons were using textContent to save/restore button content, but
SVG elements have empty textContent. Changed to innerHTML so the icons
properly restore after showing the checkmark.

Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

f72f339 docs(readme): add image

Amolith created

95d7c73 docs(readme): improve badges

Amolith created

31f7aa0 docs(readme): add scratchanitch badge

Amolith created

6aad834 docs(readme): add license, fix reuse badge

Amolith created

5a4f6d5 docs(readme): add

Amolith created

a4a721a docs(license): add

Amolith created

78e6961 docs(agents): update

Amolith created

cd98207 feat: initial Sift collaborative list app

Click to expand commit body
Complete WebSocket-based collaborative list application with:
- Deno backend with SQLite database
- Real-time voting system (upvote, downvote, veto)
- Room-based collaboration with unique IDs
- Automatic item sorting by score
- Client-side keyboard shortcuts (j/k nav, voting, edit, delete)
- Light/dark theme support
- Input validation and security constraints

Assisted-by: Claude Sonnet 4.5 via Crush

Amolith created

b00fe68 docs(agents): add

Amolith created