Skip to content

Replace Calendaria and Simple Calendar with Chronicle's own calendar - #166

Merged
keyxmakerx merged 8 commits into
mainfrom
claude/foundry-calendar-sync-ayr0rv
Oct 4, 2026
Merged

keyxmakerx merged 8 commits into
mainfrom
claude/foundry-calendar-sync-ayr0rv

Conversation

@keyxmakerx

@keyxmakerx keyxmakerx commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Fixes: none

Security implication: removes a path where a player's calendar-module note could reach Chronicle under the GM's key. The calendar window uses the player's own notes grant, not the GM's key. The players' strip is built only from Chronicle's players-audience reads, copied field by field, and shows nothing when Chronicle doesn't confirm it filtered for players.
Consumer-verified: Chronicle #1084: readViewer / playersAudience and the "audience" echo (internal/plugins/syncapi/calendar_api_handler.go); calendar.RegisterAppRoutes and the calendar embed mode (internal/plugins/calendar/routes.go, internal/widgets/notes/app_grants_handler.go, static/js/notes_embed.js).
Foundry compatibility: written for v12–v14 (ApplicationV2 window like the notebook; DialogV2 with the V1 fallback). Not yet run in a live world; see the test plan.
Mockup: Sign-offs card "Mockup v4: our real calendar inside Foundry", approved (Chronicle's own page; optional strip). Small differences are on the card "Calendar in Foundry: small differences", which this PR waits on.

What this changes

Before: the module synced Chronicle's date and notes with the Calendaria or Simple Calendar Foundry modules, and needed one of them installed.

After: neither module is used. A Calendar button next to the Notebook opens Chronicle's own calendar page in a Foundry window, as each person sees it on the site: the moving sky, day weather, moons, eras and events, with Chronicle's editing for the GM. The window can be moved and resized, and keeps its size and place per player. An optional thin strip (off until each person turns it on) shows the date, time and weather over a tiny sky. It can be dragged, locked in place or shrunk to a clock. Clicking its date opens the calendar window.

How

  • player-notebook.mjs: CalendarWindow (ApplicationV2) frames /embed/campaigns/:id/notes/calendar through the same FrameHost and grant as the notebook. openCalendarWindow connects first when needed. Size and place go in the client setting calendarWindowPlace.
  • _scene-controls.mjs: Calendar button for everyone when the world is connected.
  • calendar-sync.mjs keeps Chronicle's calendar, date, world state and nearby events. On the GM's client it publishes the calendarSnapshot world setting from ?audience=players reads for the strip; players hold no key.
  • calendar-bar.mjs: the strip (drag, lock, shrink, mini sky that rests after 20 s idle), plus the small month view as a fallback for a player who isn't connected.
  • _calendar-view-model.mjs (pure helpers, buildPlayerSnapshot) and _chronicle-caldate.mjs (Chronicle's day and leap maths, with a parity test).

Load-bearing lines:

  • buildPlayerSnapshot drops moons, era, events and day weather unless the answers echo "audience":"players".
  • publishPlayerSnapshot keeps the last snapshot when a read fails (404 excepted) and saves only on change.
  • pushDate returns whether Chronicle took the date.
  • isCalendarNoteJournal still skips notes the old calendar modules left in a world.

Honest deviations:

  • Foundry's own world clock still doesn't move with Chronicle's date.
  • The sync dashboard's Foundry-side date comparison and the wizard's calendar step went with the calendar modules.
  • Inside the window, game nights and availability don't show yet (Chronicle #1091).
  • Existing notebook connections reach the calendar without a new Allow (Chronicle #1090 tracks a per-grant scope).

Why

Key Maker: Chronicle brings its own notes and its own calendar into Foundry; Calendaria and Simple Calendar are both removed; the full calendar comes first and the strip is optional.

Test plan

  • node --test tools/test-*.mjs: 1174 tests, 1172 pass, 0 fail, 2 skipped (need CHRONICLE_DIR)
  • CHRONICLE_DIR=../Chronicle node --test tools/test-chronicle-caldate.mjs: 2 pass
  • node tools/check-package-descriptor.mjs: OK
  • Manual verification in Foundry: TESTING.md → "Calendar window" and "Built-in calendar (strip)" (needs Chronicle #1084 deployed first)
  • CI passes

Tenet self-check

  • T-B1 security: the window uses the player's own grant; the strip's player data comes only from players-audience reads and fails closed
  • T-B2 plugin isolation: changes stay within the module
  • T-B3 production UI: real Chronicle page in a native window; strip rests when idle; refused writes warn
  • T-B4 dual-audience docs: CLAUDE.md, .ai.md, TESTING.md, API-CONTRACT.md updated

🤖 Generated with Claude Code

https://claude.ai/code/session_01UexL55BkZcztyC1eezXKfn

The module no longer talks to third-party calendar modules; Chronicle's own
calendar inside Foundry replaces them. CalendarSync keeps Chronicle's
calendar state, the calendar.* WebSocket routing and the guarded date push
for that calendar to use. The Sync Calendar editor, its scene button and
menu, the setup wizard's calendar step and the dashboard's Foundry-date
comparison go with the integrations. Notes those modules left in a world
are still never pushed to Chronicle as entities.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UexL55BkZcztyC1eezXKfn
@keyxmakerx
keyxmakerx force-pushed the claude/foundry-calendar-sync-ayr0rv branch from d9de1c3 to 58656f0 Compare October 4, 2026 06:25
A date bar at the top centre shows Chronicle's date, time, season, weather
and moons, tinted by the hour; clicking it opens a month view with
Chronicle's events. The GM moves the date with step arrows or Set date and
adds events, all written to Chronicle. Players see the same bar without
controls, drawn from a snapshot the GM's client builds from Chronicle's
players-audience reads, so only what players may see reaches them. Day and
leap maths is a port of Chronicle's own calendar code, checked against it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UexL55BkZcztyC1eezXKfn
@keyxmakerx keyxmakerx changed the title Calendar sync: push only the GM's own Calendaria notes Replace Calendaria and Simple Calendar with Chronicle's own calendar Oct 4, 2026
claude added 6 commits October 4, 2026 06:44
… toggles

A single failed month read no longer publishes an empty event list to
players; turning sync or calendar sync off hides the bar on every client
at once; Escape no longer swallows a dialog's own Escape; a month whose
events failed to load is retried when reopened.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UexL55BkZcztyC1eezXKfn
Rebuilt to the second mockup's recommended picks. The date bar is now a
thin strip over a small live sky (stars, snow or rain from Chronicle's
weather, resting when the person steps away) that anyone can drag or shrink
to a round clock, kept per person. The month view shows each day's sky and
weather up to today, read from Chronicle's new day-weather route (players
get it through the players-audience snapshot), and lists the month's
events. The GM's arrows step an hour; Set date and Add event stay in the
month.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UexL55BkZcztyC1eezXKfn
Nothing shows on the table by default; the strip is a per-person setting.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UexL55BkZcztyC1eezXKfn
Each person can lock the strip so it can't be dragged by accident; the lock
is saved with their spot, per client.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UexL55BkZcztyC1eezXKfn
A Calendar button next to the Notebook opens Chronicle's calendar page in a
frame, over the player's notes grant; size and place are kept per player.
Clicking the strip's date opens it, falling back to the small month view
when the player isn't connected.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UexL55BkZcztyC1eezXKfn
@keyxmakerx
keyxmakerx marked this pull request as ready for review October 4, 2026 14:44
@keyxmakerx
keyxmakerx merged commit b712638 into main Oct 4, 2026
3 checks passed
@keyxmakerx
keyxmakerx deleted the claude/foundry-calendar-sync-ayr0rv branch October 4, 2026 15:42
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.

2 participants