Commit Graph
101 Commits
Author SHA1 Message Date
tim.mccarthy 83b8ed0411 Renumber consolidated release to v26 after v25 2026-09-04 20:33:09 -07:00
tim.mccarthy 79f3d40fcd Hide empty testing batches in changelog 2026-09-04 20:32:35 -07:00
tim.mccarthy 4eb9e6c96a Consolidate September 4 changes into grouped version 50 2026-09-04 20:31:27 -07:00
tim.mccarthy 6e5d57e4fc Batch testing changes and document explicit release workflow 2026-09-04 20:28:52 -07:00
tim.mccarthy c4f5980fbb Apply refreshed themes to both rules pages 2026-09-04 20:23:12 -07:00
tim.mccarthy 8b40864cc4 Refresh nautical themes and use solid notebook panels 2026-09-04 20:19:17 -07:00
tim.mccarthy 145f526634 Add per-player autosaving game notebooks 2026-09-04 20:13:14 -07:00
tim.mccarthy 0ae1701b82 Improve character suggestions and serve pools from the API 2026-09-04 19:58:35 -07:00
tim.mccarthy 1dac2141e6 Add standalone TL;DR rulebook reference 2026-09-04 19:51:15 -07:00
tim.mccarthy 5c761b079d Require visual verification for aesthetic changes 2026-09-04 19:44:25 -07:00
tim.mccarthy ad9f450343 Join crew objectives toggle and checklist in one panel 2026-09-04 19:42:11 -07:00
tim.mccarthy 9b673cb8bc Keep crew roster order stable across role changes 2026-09-04 19:40:10 -07:00
tim.mccarthy 53df97e3a5 Require Gat descriptions and keep them consistent across ownership changes 2026-09-04 19:38:20 -07:00
tim.mccarthy a5e3969d0a Let players dismiss completed duel feedback 2026-09-04 19:35:49 -07:00
tim.mccarthy 811a80a4c9 Mark played-card outcomes with corner checks and crosses 2026-09-04 19:34:26 -07:00
tim.mccarthy 22880cc466 Keep completed duel outcomes visible throughout the scene 2026-09-04 19:33:39 -07:00
tim.mccarthy fcbc617fe3 Show live player presence and Captain/Gat roster badges 2026-09-04 19:32:22 -07:00
tim.mccarthy 8b67d78f25 Defer challenge redraws until resolution and limit card plays 2026-09-04 19:28:20 -07:00
tim.mccarthy cf63ffed47 Verify and explain defender-only PvP redraws 2026-09-04 19:27:25 -07:00
tim.mccarthy 2f8f67a24c Award personal objectives through group votes 2026-09-04 19:26:37 -07:00
tim.mccarthy 8fdd10f7a3 Limit assistance to challenges with multiple active obstacles 2026-09-04 19:23:35 -07:00
tim.mccarthy 673a26f271 Align crew hand sizes and card refresh with the rules 2026-09-04 19:22:52 -07:00
tim.mccarthy 749bef6ff1 Discard completed obstacles automatically and verify scene refresh rules 2026-09-04 19:21:35 -07:00
tim.mccarthy 1837bf04e6 Advance after final rank vote and allow ballot changes 2026-09-04 19:18:38 -07:00
tim.mccarthy 88f8781dce Show visual voting progress and submitted nominee 2026-09-04 19:15:19 -07:00
tim.mccarthy d78d23d269 Remove deck size from the table 2026-09-04 19:13:19 -07:00
tim.mccarthy edcb3c08a2 Stabilize event log toggle and omit dev mode events 2026-09-04 19:13:06 -07:00
tim.mccarthy 376765dd0f Condense UI labels and align obstacle statistics 2026-09-04 19:12:36 -07:00
tim.mccarthy 52dda12c47 Fix deprecated Nix system access 2026-07-28 16:00:51 -07:00
tim.mccarthy d8d68a80a3 Pin event log across all phases 2026-07-10 19:24:04 -07:00
tim.mccarthy b9cbbda1a2 Keep crew roster in a consistent sidebar 2026-07-10 19:17:39 -07:00
tim.mccarthy 3e912b9458 Make join codes easy to copy 2026-07-10 19:12:03 -07:00
tim.mccarthy 929941b8ff Add combined development server launcher 2026-07-10 19:09:16 -07:00
tim.mccarthy 9a5a319cb9 Keep player rosters vertical 2026-07-10 14:06:01 -07:00
tim.mccarthy a5bfb7905f Promote admin join code display 2026-07-10 12:32:08 -07:00
tim.mccarthy b253a06b45 Add short game join codes 2026-07-10 12:30:43 -07:00
tim.mccarthy 8470da4aa9 Remove expired rejoin sessions 2026-07-10 12:27:32 -07:00
tim.mccarthy 2de4648288 Remember player name for new crews 2026-07-10 12:25:55 -07:00
tim.mccarthy 3fe3333768 Align admin link controls 2026-07-10 12:22:53 -07:00
tim.mccarthy feb595af16 Clarify unnamed Pi-Rats in admin panel 2026-07-10 12:21:07 -07:00
tim.mccarthy 1a4bc86139 Keep event log toggle in place 2026-07-10 11:59:30 -07:00
tim.mccarthy 2210bcd48e Widen character sheet modal 2026-07-10 11:58:34 -07:00
tim.mccarthyandClaude Opus 4.8 692c6d26c1 Cap request body size (HTTP 413)
LimitRequestBodyMiddleware (pure ASGI, registered outermost) rejects request
bodies larger than PIRATS_MAX_BODY_BYTES (default 1 MiB) before they're buffered
into memory: it checks the declared Content-Length first, then counts the bytes
actually streamed so a chunked/length-omitting client can't bypass the header
check. Exposed as services.pirats.maxBodyBytes and documented in the README.

Tested in isolation (Content-Length fast path + streamed path) and through the
real app.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 15:59:48 -07:00
tim.mccarthyandClaude Opus 4.8 122e66b817 Defensive coding: sanitize free text, constrain inputs
Player-authored free text is scrubbed at the API boundary before storage via a
new validation.py: drop control characters and unpaired surrogates, trim
whitespace, and cap length (names 120, other text 2000). Applied to crew/player
names, the character sheet, like/hate answers, techniques, recruit techniques,
the renamed Name, the Gat description, and challenge stakes. Values matched
against stored text (swap offers, face-card assignments) and identifiers/enums
are left untouched so they still compare equal.

Constrained set-role to the two real roles so it can't stash an arbitrary string
in the column. Audited the rest: queries are parameterized by SQLModel (the lone
f-string SQL in database.py is the hardcoded legacy-migration list, no user
input); objective-type and rollback writes already whitelist their keys; no
endpoint accepts a generic (field, value) write.

Tests cover the sanitizer (control chars, surrogates, emoji, caps) and the
create/join HTTP path end-to-end.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 15:54:21 -07:00
tim.mccarthyandClaude Opus 4.8 ccb32e7103 Periodic purge of old finished/inactive games
New maintenance.py runs a background asyncio loop (started from the app
lifespan) that purges games which either finished more than PIRATS_PURGE_
FINISHED_DAYS (default 14) ago or have had no activity for PIRATS_PURGE_
INACTIVE_DAYS (default 30). "Activity" is a game's most-recent GameEvent
timestamp; games with no events are undatable and left alone.

Each purge is logged with the crew name, uuid, reason, idle days and an
estimated byte footprint; every run that removes anything VACUUMs the SQLite
file and logs the disk space actually reclaimed. Child rows go via the ORM
cascade already declared on Game's relationships.

Configurable via PIRATS_PURGE_ENABLED / _INTERVAL_HOURS / _FINISHED_DAYS /
_INACTIVE_DAYS, exposed as services.pirats.purge.* in the NixOS module and
documented in the README. Unit test covers the selection logic and cascade;
smoke-tested the VACUUM/reclaim path against a file DB.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 15:47:44 -07:00
tim.mccarthyandClaude Opus 4.8 5e9f9bfb13 Backend logging: stderr + configurable rotating file
Add configure_logging() (main.py): always logs to stderr, plus a rotating
file when PIRATS_LOG_FILE is set; level from PIRATS_LOG_LEVEL (default INFO).
Called from both the CLI entrypoint and the app lifespan (idempotent), which
also logs startup/migration/shutdown.

Targeted server-side events for ops/debugging (not every game event): game
created, player joined, player removed (kick/leave), game ended.

NixOS service: new logFile (/var/log/pirats/pirats.log) and logLevel options,
wired to the env vars; LogsDirectory=pirats makes the path writable under the
sandboxed DynamicUser. README documents the env vars/options.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 15:42:06 -07:00
tim.mccarthyandClaude Opus 4.8 b1a559cf39 Polish: legible crew roster, End-Scene enforcement, decluttered Hand
- Crew roster bubbles: explicit text color + opaque distinct surface so
  they're legible and stand out from the page in both themes (the bug was
  the <button> defaulting to black-on-dark in dark mode).
- End-Scene enforcement: unless Dev Mode is on, a scene can't end until
  every living Pi-Rat has faced a Deep Challenge or the Obstacle List is
  empty. end_scene_and_transition now returns (ok, msg) and the route
  surfaces a 400; the Deep sees a ✓/○ challenge-progress badge on each
  Pi-Rat bubble. 3 new tests cover the gate.
- Hand panel: dropped the how-to-play blurb and the title in favor of a
  low-profile "Your Hand" label.
- Bump VERSION to 8 with changelog entry; check off TODO.md Polish items.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 15:34:10 -07:00
tim.mccarthyandClaude Opus 4.8 6fa7073f10 Make the inline Event Log collapsible and viewport-bounded (v7)
Two scene-layout tweaks to the inline (third-column) Event Log:

- It can now be collapsed to a fixed corner button (✕ in its header) to declutter,
  and reopened from that button. ScenePhase owns `logOpen` and reflows the grid to
  two columns while collapsed; EventLog dispatches `collapse`.
- The panel now pins at top:3.5rem (matching .dashboard-container's top padding)
  with max-height calc(100vh - 4.5rem), so its bottom stays on-screen at any scroll
  position and .log-content scrolls internally — previously the bottom sat ~24px
  below the fold at the top of the page.

Verified across Pi-Rat and Deep views, scroll extremes, and 3-col / 1-col widths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 15:16:57 -07:00
tim.mccarthy b18bf683a9 Simple tasks: Tooltips and UI Layout
Completed tasks: 'PvP challenge tooltips', 'Secret technique tooltips', and 'Character sheet layout' from TODO.md
2026-06-15 11:01:16 -07:00
tim.mccarthy e1779292e5 Simple tasks: Event log and personal objective cursor
Completed tasks: 'Event log items' and 'Personal objectives for pi-rats' from TODO.md
2026-06-15 10:57:00 -07:00