- .github/workflows/mirror-to-forgejo.yml: on push to main, runner on Mac Mini
pushes to Forgejo via local SSH (localhost:2222). Keeps Forgejo in sync.
- .forgejo/workflows/cd-macmini.yml: deploy step now pulls from forgejo remote
(ssh://localhost:2222) instead of GitHub origin.
Flow: local → git push origin main → GitHub → mirror-to-forgejo runs on Mac Mini
→ pushes to Forgejo → Forgejo CD pipeline → deploys containers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- docker-compose: fix port mapping 2222:2222 → 2222:22 (sshd listens on 22)
- .forgejo/workflows/cd-macmini.yml: new CD pipeline for Forgejo Actions
(mirrors .github/workflows/cd-macmini.yml, run_url points to git.mana.how)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
colima delete wipes the entire VM disk on every power cycle, forcing
full image rebuilds. colima stop --force is sufficient to clear stale
process state after a hard shutdown.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
todo-web, calendar-web, contacts-web, mana-web all depend on
@manacore/shared-links but it was missing from the base image COPY list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The startup script runs `colima delete` on hard shutdown recovery,
wiping the colima.yaml mount config. Then `colima start` only added
/Volumes/ManaData but forgot /Users/mana — causing all file bind-mounts
to appear as empty directories (VirtioFS can't see host files).
This was the root cause of Synapse/SearXNG/Alertmanager/Loki crashing
after the power outage. Now both mounts are always passed explicitly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Now that VirtioFS is fixed (colima /Users/mana mount restored),
file bind-mounts work correctly. Replace the cp-in-entrypoint workaround
with a direct file mount to /etc/alertmanager/alertmanager.yml.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
vmalert: was copying prometheus.yml into /etc/alerts/ causing parse
failure. Now only copies alerts.yml (the actual rules file).
synapse: mana-auth (Better Auth) has no OIDC discovery endpoint,
so disable OIDC and enable password auth until OIDC is implemented.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
YAML '>' block scalar preserves newlines for over-indented lines,
causing 'exec binary' to run without its arguments. Fix: use JSON
array format for all entrypoints to avoid YAML folding entirely.
Also fixes SearXNG entrypoint path: image updated from
dockerfiles/docker-entrypoint.sh to entrypoint.sh.
Affected: victoriametrics, loki, vmalert, alertmanager, searxng, synapse
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create entry-parser.ts with duration extraction (2h, 30min, 1h30m),
time range parsing (9-12, 14:00-16:30), project (@), tags (#), billable
($), and date recognition. Multi-entry splitting via semicolons with
context inheritance. Integrate quick-input bar into EntryForm — type
"Meeting 2h @Client $; Review 1h" and press Enter to create multiple
entries at once.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the fixed CSS Grid widget layout with a recursive tiling system
using a binary tree data model. Each node is either a leaf (widget) or
a split (horizontal/vertical) with a draggable resize handle.
New components:
- TilingLayout: Recursive renderer (leaf→TilePanel, split→flex+handle)
- TilePanel: Widget wrapper with edit controls (split H/V, change, close)
- TileResizeHandle: Draggable divider, H+V, keyboard accessible, 10-90%
Architecture:
- Binary tree model (TileNode = TileLeaf | TileSplit)
- Immutable tree operations in tiling-tree.ts (splitLeaf, removeLeaf, etc.)
- Tiling store with debounced IndexedDB persistence
- Widget registry extracted from WidgetContainer for shared use
- Mobile fallback: flattened vertical stack under 768px
- Default: Clock | Tasks | Calendar (3 panels)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add quick-input bar to NewContactModal that parses natural language
contact info (name, company, email, phone, tags) and pre-fills form
fields on Enter. Add live duplicate detection that checks name/email
against IndexedDB while typing, showing warnings for fuzzy name matches
(Levenshtein) and exact email matches. Both features run offline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major systems added to ManaVoxel:
- Behavior runtime: EventBus + 10 triggers + 11 action executors
- Item persistence: save/load items, inventory, area pixels to IndexedDB
- NPC system: 4 types (hostile/passive/merchant/guard), patrol/chase/attack AI
- Lighting: darkness overlay with emissive material light sources
- Day/night cycle: time-based ambient lighting on streets
- Sound system: 8 synthesized Web Audio API presets
- Sprite animation: multi-frame support in editor with play/stop
- Dialog system: NPC interaction with text bubbles and options
- Item properties: range, speed, durability, element all functional
- Health endpoint for Docker, durability bar in inventory UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Restore from git history (was deleted in 079b55a79)
- Delete NestJS backend and mobile app
- Create Hono/Bun server with preset moods API
- Create local-first store (moods, sequences) with 8 preset moods
- Rewrite web app: Moods page with color gradient cards and activation,
Sequences page with CRUD, auth via shared-auth-ui with guest mode
- Add CLAUDE.md, dev scripts, root CLAUDE.md entry
- 0 type errors on both server and web
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ManaLinkBadge now resolves the correct URL for the linked record's
detail view (e.g. /event/{id}, /contacts/{id}, /deck/{id}) instead
of just linking to the app's root page.
Uses an anchor tag by default for standard browser navigation, with
onclick prop override for custom behavior. Supports all 12 apps with
their specific routing patterns.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New modal component that searches across app databases (calendar events,
contacts) and creates bidirectional links with cached display data.
Integrated into Todo's TaskEditModal with "+ Verknüpfen" button.
Search uses debounced text matching against IndexedDB records with
lazy-initialized cross-app readers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add @manacore/shared-links to Calendar, Contacts, and ManaCore apps.
Link store initializes alongside tag store in each app's layout, syncs
when authenticated, and is ready for cross-app linking.
Also fix broken workspace references in moodlit (shared-feedback-service
→ feedback, shared-feedback-ui removed, shared-subscription-ui →
subscriptions).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Duration estimation now auto-applies without requiring a button click.
When no explicit duration is typed, the system uses history-based
estimation (weighted by project/calendar, title, labels) with the
configurable default as fallback. Both apps get a "Smarte Dauer" toggle
and default duration picker in Settings. The learned duration improves
over time as more tasks/events are completed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migrate 9 more dashboard widgets from REST API polling to direct
IndexedDB reads: Chat, Zitare, Picture, Clock, Storage, Mukke,
Presi, Context, ManaDeck.
All 13 data widgets now use reactive liveQuery reads. Only Credits
and Transactions remain API-based (server-authoritative data).
Added cross-app stores for: chat, zitare, picture, clock, storage,
mukke, presi, context, manadeck — with typed collection accessors
and reactive query hooks for each.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wire up event-parser and event-estimator into the QuickEventOverlay
title input. Typing natural language like "Meeting morgen 14 Uhr 1h
@Arbeit" now shows a live parse preview, duration estimation from
history, and conflict warnings. On submit, parsed values auto-fill
form fields (date, time, calendar, location, recurrence, all-day).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace REST API polling with direct IndexedDB reads for 4 dashboard
widgets: TasksToday, TasksUpcoming, CalendarEvents, ContactsFavorites.
Data is now reactive via Dexie liveQuery — updates instantly when any
app writes to its IndexedDB (sync, other tabs, local edits). No more
30-60s polling intervals or retry logic needed.
New files:
- cross-app-stores.ts: Opens todo/calendar/contacts IndexedDB databases
- cross-app-queries.ts: Reactive queries (useOpenTasks, useUpcomingEvents, etc.)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend the event parser with multi-event splitting on keywords (danach,
dann, ;) with context inheritance (date/time/calendar chain and automatic
time offsets). Add event-estimator.ts with history-based duration
estimation (weighted similarity on calendar, title, tags) and conflict
detection against existing events. All features run offline against
IndexedDB.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New shared package enabling bidirectional links between records across
apps (e.g. todo→calendar, task→file). Each link creates a forward+reverse
pair sharing a pairId for efficient queries from both sides. Stored in
dedicated IndexedDB (manacore-links), synced via mana-sync.
Includes: types, store, mutations, reactive queries, cached display data
resolvers, ManaLinkBadge and ManaLinkList UI components.
Integrates into Todo app as first consumer — link store initialized in
layout, ManaLinkList rendered in TaskEditModal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move from apps-archived/ to apps/ (last archived app)
- Fix root package.json name to @manacore/bauntown
- Add to root CLAUDE.md project table
- Astro landing page with i18n (DE/EN/IT), Stripe, Netlify preserved
apps-archived/ is now empty — all 5 apps restored:
uload, news, wisekeep, reader, bauntown
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move from apps-archived/ to apps/
- Delete NestJS backend, mobile app, legacy Python, shared-types
- Create Hono/Bun server with Groq Whisper transcription via yt-dlp
- Create local-first store (transcripts, playlists) with guest seed
- Rewrite web app: Transcribe page, Library with search/expand,
Playlists CRUD, auth via shared-auth-ui, AuthGate with guest mode
- Remove broken landing page subpages (Prettier-incompatible Astro)
- Add wisekeep to root CLAUDE.md and dev scripts
- Fix duplicate wisekeep entries in shared-branding
- 0 type errors on both server and web
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend the natural language parser with duration recognition (30min, 2h,
1.5 Stunden), multi-task splitting on keywords (danach, dann, ;) with
context inheritance (date/time/project), and a history-based time estimator
that suggests durations from similar completed tasks. QuickAdd now shows
a live parse preview and duration suggestion. All features run offline
against IndexedDB — no AI/API calls needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move ManaCore from server-only data fetching to local-first architecture
using @manacore/local-store (IndexedDB + mana-sync). Dashboard config
now syncs across devices instead of being localStorage-only, and tags
use the shared local-first tag store consistent with all other apps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move from apps-archived/ to apps/
- Delete NestJS API, Docker files, old docs, browser extension
- Create Hono/Bun server with content extraction (Mozilla Readability)
and AI feed API reading from mana-sync's sync_changes
- Create local-first store (articles, categories) with guest seed data
- Rewrite web app: Feed page, Saved articles with URL extraction,
auth pages using shared-auth-ui, AuthGate with guest mode
- Add news to shared-branding (app icon, mana-apps registry)
- Add CLAUDE.md, dev scripts, root CLAUDE.md entry
- 0 type errors on both server and web
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Loki was already running but had no log shipper. Adds Promtail to collect
Docker logs from all 66 containers with automatic tier labeling (infra,
auth, core, app, matrix, games) and a Grafana Logs Explorer dashboard.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Kill Docker Desktop if it auto-started
- Clean stale Colima state from hard shutdown (delete --force)
- Start Colima with VZ, 12GB RAM, VirtioFS
- Restore named volumes from backup if missing
- Start containers with --no-build to skip broken Dockerfiles
- Create missing databases
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sync integration:
- Redirect service reads links from mana-sync's sync_changes table
- Analytics service queries clicks from sync_changes
- Click tracking writes to sync_changes (visible to all clients)
- Public profile reads from sync_changes
- Server DB points to mana_sync database (not separate uload DB)
- Removed uload-database dependency from server
Stripe:
- Real Stripe checkout session creation (monthly/yearly)
- Webhook handler with signature verification
- Webhook route bypasses JWT auth
Documentation:
- Root CLAUDE.md: added uload to project table, dev commands, local-first list
- mana-sync CLAUDE.md: added uLoad, Taktik, Calc to connected apps
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Colima's VirtioFS mounts files as directories, breaking direct
file-to-file bind mounts. Fix: mount host dir to /mnt/*-config,
then copy files to target path in entrypoint before exec'ing
the actual process.
Affected services: SearXNG, VictoriaMetrics, Loki, vmalert,
Alertmanager, Synapse
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Docker:
- Dockerfile for web (sveltekit-base, port 5029) and server (Bun, port 3041)
- docker-compose.macmini.yml entries for uload-server + uload-web
- Landing page deploy script (Cloudflare Pages)
Documentation:
- Complete CLAUDE.md rewrite reflecting local-first + Hono architecture
Features:
- Bulk select/deselect all/toggle active/delete
- Link expiry date (datetime picker)
- Password-protected links
- Max clicks limit
- Badges for password/expiry/maxClicks on link items
- Advanced options collapsible section in create & edit forms
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fill entire area with grass (top-down needs ground everywhere, no AIR gaps)
- Add cobblestone road with stone edges
- Add dirt paths, sand area, market stalls, flower patches
- 10 trees with trunk + leaf canopy scattered around
- 3 distinct buildings: brick house, wood cabin, stone tower
- Well with water in village center
- Torches along road edges
- Player spawns at center of road (200, 150) for better first impression
- Camera default zoom reduced to 1.5x (was 2x) to show more of the village
- Min zoom out to 0.3x for full overview
- New seed ID (guest-world-002) to regenerate for existing users
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mac Mini has docker at /usr/local/bin/docker, not in PATH.
Use same DOCKER_CMD pattern as build-app.sh.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
$state() is Svelte 5 runes syntax that only works in .svelte or .svelte.ts
files. The Inventory class used $state for reactive slots/heldSlot which
caused "ReferenceError: $state is not defined" in production builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
File-mount fixes (Colima mounts single files as directories):
- SearXNG: mount entire searxng/ dir instead of individual files
- VictoriaMetrics: mount prometheus/ dir instead of individual yml files
- Loki: mount loki/ dir instead of individual yaml file
- vmalert: mount prometheus/ dir for alerts
- Synapse: move config files to docker/matrix/config/ subdir
- Landings (nginx): copy configs from mounted dir via entrypoint
mana-llm port fix:
- Service hardcodes port 3025 in Dockerfile, was configured as 3020
- Update compose to use 3025 internally, fix health check and references
Web app Dockerfile fixes:
- mana-web: add missing MIDDLEWARE_URL build arg
- manadeck-web: add missing PUBLIC_API_URL build arg
- playground: add missing PUBLIC_MANA_LLM_URL build arg, add
@manacore/shared-auth-stores dependency
- mukke-web: add missing svelte-i18n dependency
Remaining build issues (not fixed, deeper code problems):
- skilltree-web, inventar-web: Svelte 5 rune in shared package
not compiled during Rollup build
- mana-web: MIDDLEWARE_URL may need additional server-side config
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
build-app.sh now checks available RAM before builds and only stops
monitoring containers when free memory is below 3 GB threshold.
New memory-baseline.sh script measures per-container and per-category
RAM usage for capacity planning.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Document mana-games and other games in root CLAUDE.md project tables.
Add mana-games-web service to docker-compose for Mac Mini deployment
on port 5210.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Features added to links page:
- QR code generation with modal and download
- Edit modal for title, URL, UTM parameters
- Collapsible UTM parameter fields (source, medium, campaign)
- Click count links to analytics page
- Confirm dialog before delete
Analytics dashboard improvements:
- Country breakdown with progress bars
- Device breakdown with percentages
- Time period switcher (7/30/90 days)
- Tooltip on timeline bars
- Back navigation
Other:
- Public profile page /u/[username] via Hono endpoint
- i18n setup with svelte-i18n (DE/EN locale files)
- PWA support via @vite-pwa/sveltekit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Production-ready Dockerfile on port 5210, security headers and analytics
injection via hooks.server.ts, GlitchTip error tracking, and feedback page
using shared feedback package.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Dockerfile: two-stage build on sveltekit-base, port 5028
- docker-compose.macmini.yml: manavoxel-web service on port 5028
- Root package.json: dev:manavoxel:web and dev:manavoxel:full scripts
- Fix Tailwind CSS import (shared-tailwind/themes.css)
- Port changed from 5195 to 5028 (consistent dev/prod)
Deploy with: ./scripts/mac-mini/build-app.sh manavoxel-web
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds login/register/forgot-password auth routes using shared-auth-ui,
settings page with theme/language/account controls, themes browser,
help page, community submit form, profile, and app onboarding modal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>