Two unrelated bugs in scripts/mac-mini/ensure-containers-running.sh,
both caught while debugging a mana-auth crash loop on 2026-04-08:
1. The recovery path passed --env-file "$PROJECT_ROOT/.env.macmini" to
docker compose, but that file has never existed on the server — only
.env does, and compose auto-loads it from the working directory. The
explicit --env-file silently caused recovered containers to start with
empty secrets (e.g. blank MANA_AUTH_KEK), which made mana-auth crash
the moment it came back up. The auto-recovery loop was therefore
self-defeating: it kept "fixing" auth into the same broken state
every 5 minutes for hours, with no notification because compose
exited 0. Drop --env-file entirely and cd into PROJECT_ROOT so
compose's standard .env discovery applies.
2. mana-infra-minio-init is a one-shot job container that legitimately
sits in "exited" state after running once. The script flagged it as
"stuck" every cycle, tried to "recover" it, and spammed the log with
ERROR lines. Add an explicit ONESHOT_INIT_CONTAINERS allowlist and
skip those names in both the initial scan and the post-recovery
verification.
Also tee compose output into the log so future failures actually leave
a breadcrumb instead of disappearing into the void.
Also: bump @mlc-ai/web-llm from a transitive dep (via @mana/local-llm)
to a direct dep of @mana/web. SvelteKit's adapter-node post-build
Rollup pass uses the web app's direct deps as its externals heuristic;
without this entry it warns "@mlc-ai/web-llm ... could not be resolved
- treating it as an external dependency" on every build. Functionally
harmless (the dynamic import in LocalLLMEngine only fires in the
browser), but the warning hid a real adapter-node misconfiguration
that would have bitten us if we'd ever tried to SSR /llm-test.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reflects the removal of apps/matrix and services/mana-matrix-bot from
the workspace plus the dropped @matrix-org/matrix-sdk-crypto-nodejs
override in package.json. Net -365 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
mana-auth has been crash-looping in production with:
error: Cannot find package 'nanoid' from
'/app/src/services/encryption-vault/index.ts'
The encryption-vault service imports nanoid for audit row IDs (line 27,
used at line 547 in the audit log writer), but nanoid was never added
to services/mana-auth/package.json. The import was introduced in commit
e9915428c (phase 2 — server-side master key custody) and slipped past
because nanoid happens to exist transitively in the workspace via
postcss → nanoid@3.3.11. Local pnpm store lookups would resolve it just
fine; a strict isolated container build can't.
Fix:
- Add "nanoid": "^5.0.0" to services/mana-auth/package.json deps
- pnpm install pulled nanoid@5.1.7 into services/mana-auth/node_modules
Verified the import resolves locally:
bun -e 'import { nanoid } from "nanoid"; console.log(nanoid())'
→ ok: 6TLuTWlenhC0KnSESn5Ex
The Mac Mini still needs to redeploy mana-auth (rebuild image with the
new lockfile, restart container) to pick this up — production is
currently 502ing on auth.mana.how.
The lockfile had drifted out of sync with two package.json files:
- services/mana-events/package.json declared drizzle-orm, hono, jose,
postgres, zod, drizzle-kit, typescript — but mana-events was never
registered as an importer in pnpm-lock.yaml at all. A frozen-lockfile
install would fail.
- apps/mana/apps/web/package.json had "postgres": "^3.4.9" as a
devDependency that the lockfile hadn't picked up.
Both are already declared in their package.json — this commit just
locks them in. No new top-level dependencies are introduced.
The rest of the diff is non-substantive churn from running pnpm install
(jiti peer-version flips between 1.21.7 ↔ 2.6.1, expo-font peer
specifier format becoming more explicit). Net diff is −102 lines
despite registering two new importers, because the peer-format
verbose-ification deduplicates a few entries.
The lockfile had grown five (!) different vitest versions over time:
1.6.1, 2.1.9, 3.2.4, 4.1.2 and 4.1.3 — pulled in by various
packages that pinned outdated majors. The mismatch produced the
classic "createDOMElementFilter not found" startup crash because
hoisted @vitest/utils@3.x was loaded by the nested @vitest/runner@4.x.
Bumped every package.json that pinned an old vitest:
- apps/manavoxel/apps/web (^4.1.0 → ^4.1.2)
- apps/matrix/apps/web (^4.1.0 → ^4.1.2)
- apps/memoro/apps/server (^3.0.0 → ^4.1.2)
- apps/nutriphi/packages/shared (^2.1.8 → ^4.1.2)
- packages/qr-export (^3.0.5 → ^4.1.2)
- packages/shared-llm (^2.0.0 → ^4.1.2)
- packages/shared-storage (^4.1.0 → ^4.1.2)
- packages/spiral-db (^1.6.1 → ^4.1.2)
- packages/test-config (^3.0.0 → ^4.1.2)
- packages/wallpaper-generator (^3.0.5 → ^4.1.2)
After a clean pnpm-lock.yaml regenerate, every @vitest/* sub-package
resolves to a single version (4.1.3, picked by semver) — no more
duplicates between hoisted and nested node_modules.
Verified by running:
pnpm --filter @mana/web vitest run src/lib/data/sync.test.ts
→ 20/20 tests passing in 217ms
pnpm --filter @mana/web vitest run src/lib/data/time-blocks/recurrence.test.ts
→ 19/19 tests passing in 198ms
Pre-existing test failures in base-client.test.ts (German error
strings vs english assertions), dashboard.test.ts (widget count
drift), and content/help/index.test.ts (svelte-i18n locale not
initialised in test env) are unrelated and tracked separately.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New SyncChange / FieldChange / SyncOp types replace `any[]` in
applyServerChanges. The wire format is now self-documenting and
TypeScript catches malformed callsites at compile time.
- isValidSyncChange() validates incoming server payloads at the boundary:
malformed entries are dropped with a single warn log, valid ones are
applied. A bad row from the server can no longer corrupt IndexedDB.
Hand-rolled type guards keep us free of a runtime-validation dep.
- applyServerChanges() and readFieldTimestamps() are now top-level
exports (extracted out of createUnifiedSync's closure) so they can be
imported directly by tests. Behaviour is unchanged — the closure
variant inside the sync manager just resolves the module-level
symbol now.
- New sync.test.ts covers:
* pure isValidSyncChange and readFieldTimestamps cases
* field-level LWW: server-newer wins, split outcome when local-newer
on one field and server-newer on another
* insert with __fieldTimestamps stamping
* soft-delete LWW guard
* malformed-entry drop with valid entries surviving
* sync-loop guard: server-applied writes don't generate _pendingChanges
- fake-indexeddb added as devDependency for the integration tests.
Note: the monorepo's vitest install is currently tangled across mixed
@vitest/* package versions in the lockfile, so `pnpm test` fails before
reaching this file. The tests are written to pass on any vitest 4.x once
that's untangled — needs its own dedicated cleanup pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Picture, Contacts, Planta, Storage, and NutriPhi image uploads now go
through mana-media instead of directly to S3. This enables SHA-256
deduplication, automatic thumbnail generation, EXIF extraction, and
makes all images visible in the Photos gallery. Non-image files (PDFs,
audio, docs) continue to use shared-storage directly. SVG avatars in
Contacts also stay on shared-storage since Sharp can't process SVGs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add curated icon registry (73 Phosphor icons, 8 categories) in shared-icons
- Add DynamicIcon atom and IconPicker molecule in shared-ui
- Migrate habits module from emoji strings to Phosphor icon names
- Add Dexie version(2) migration for emoji→icon field rename
- Replace inline SVGs in habits with Phosphor components
- Add drag-and-drop photo upload to Photos workbench ListView
- Add blob: to CSP img-src for upload previews
- Add dev:media script and include mana-media in dev:manacore:servers
- Add ./toast export to shared-ui package.json
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All app compute servers have been consolidated into apps/api/ (unified
Hono/Bun server). Old servers moved to apps/*/apps/server-archived/.
Archived: cards, chat, contacts, context, calendar, guides, moodlit,
mukke, news, nutriphi, picture, planta, presi, questions, storage, todo, traces
Still active: uload (separate domain), memoro (Supabase-based)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All standalone SvelteKit web apps have been superseded by the unified
ManaCore app (apps/manacore/apps/web). Moved to web-archived/ within
each project to preserve history while removing from active workspace.
Archived: calc, cards, chat, citycorners, contacts, context, guides,
inventar, moodlit, mukke, news, nutriphi, photos, picture, planta,
presi, questions, skilltree, storage, times, zitare, todo, calendar,
uload, memoro
Moved to apps-archived/: wisekeep (not integrated, inactive)
Kept active: manacore (unified), matrix, manavoxel, arcade (separate containers)
Server, landing, and package directories remain active for each project.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Upgrade shared-logger to dual-mode: JSON lines in production, console
in dev. Adds configureLogger() for service name + request ID.
- Add requestLogger middleware to shared-hono with request ID generation
and structured request/response logging.
- Align Promtail config with new JSON field names (requestId, ts, service).
- Add PUBLIC_GLITCHTIP_DSN + PUBLIC_UMAMI_WEBSITE_ID to mana-web docker config.
- Add /status page that polls all backend /health endpoints server-side.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add web-vitals package with LCP/CLS/INP/FCP/TTFB → Umami tracking
- Set GlitchTip user context on login, clear on logout
- Add funnel events: first_content_created, user_return_visit,
second_module_used, guest_converted
- Track first content via Dexie creating hook (fires once per user)
- Track module usage via route navigation effect
- Track guest→registered conversion on signup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add compact inline TagChip for list items/cards (smaller than TagBadge).
Set up vitest with jsdom for shared-ui package and add 44 tests covering
TagChip, TagBadge, TagColorPicker, TagSelector, and constants.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove leaflet, leaflet.markercluster, and @types/leaflet from
citycorners. Replace interactive Leaflet maps with zero-dependency
OpenStreetMap iframe embeds on both map and location detail pages
(standalone citycorners + manacore integrated). Add filtered location
list below map as replacement for interactive markers.
Also removes remaining bauntown files missed in previous commit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These apps were either stubs (voxelava, worldream), planning-stage
(reader), dev-tools (playground), or inactive (bauntown). Removing
to reduce monorepo surface area. All recoverable from git history.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add spiral module (stores, components, data collection) and /spiral route
to ManaCore web. Wire up navigation entry and command palette shortcut.
Add spiral-db workspace dependency.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dexie is imported in 62 files but was only available as transitive dependency
via @manacore/local-store. In Docker builds with isolated node_modules it
wasn't being resolved — add it explicitly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add missing toast.svelte.ts store for zitare module, fix onclick|stopPropagation
to Svelte 5 syntax in calendar, replace non-existent StarFill with Star weight="fill"
in contacts, fix calc skins import path, add app-specific shared packages to vite config,
and improve login error handling for invalid credentials.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Zod schemas for all 30+ API endpoints with proper input validation
- Consistent `{ success: true/false, ... }` response wrapper on every endpoint
- Pagination (limit/offset) on spaces, space memos, bots, and recordings list endpoints
- Validation helper (validateBody/validateQuery) for clean route handlers
- Fix rate-limiter return type in both memoro and shared-hono
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
mana-stt: add WhisperX service with CUDA GPU support, speaker diarization, and auto-fallback chain.
mana-notify: add locale fallback and default templates for task reminders.
CD: update deployment pipeline and docker-compose configuration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Set accurate status levels (beta/planning) instead of blanket 'development',
mark Cards/Picture/Zitare/Wisekeep as no longer coming soon.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Delete apps/memoro/apps/backend/ (NestJS) and apps/memoro/apps/audio-backend/
(NestJS) — all functionality has been ported to the new Hono/Bun servers
(apps/server/ and apps/audio-server/).
Also clean up root and memoro package.json scripts to remove references
to the old @memoro/backend and @memoro/audio-backend packages.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace @arcade/backend (NestJS) with @arcade/server (Hono/Bun).
Same two endpoints, no auth required (public game generator):
- POST /api/games/generate — AI game generation (Gemini, Claude, GPT)
- POST /api/games/submit — Community game submission via GitHub PR
- GET /health — Health check
This removes the last remaining NestJS backend from the monorepo.
NestJS is now completely gone — all servers use Hono + Bun.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
adapter-auto does not produce a build/ directory for node deployments,
causing Docker builds to fail. Switch to adapter-node like all other apps.
Co-Authored-By: Claude Sonnet 4.6 <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>
- 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>
- 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>
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>
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>
- Add auth store using createManaAuthStore
- Wrap app layout with AuthGate (allowGuest=true)
- Add GuestWelcomeModal and SessionExpiredBanner
- Start sync on login, stop on logout
- Rewrite login/register/forgot-password to use shared auth UI
- Remove all PocketBase auth references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move from apps-archived/ to apps/
- Delete NestJS backend, PocketBase, old scripts and docs
- Create Hono/Bun redirect server (click tracking, analytics API)
- Create @manacore/uload-database shared Drizzle schema package
- Add local-first store (Dexie.js) for links, tags, folders
- Rewrite Links and Tags pages to use IndexedDB
- Simplify hooks, layouts, remove all server-side data loading
- Add dev scripts: dev:uload:web, dev:uload:server, dev:uload:local
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New calculator app with standard, scientific, programmer, unit converter,
currency, finance, date, and percentage modes. Includes 5 visual skins:
Modern, HP-35 (1972), Casio fx (1985), TI-84 (2004), and Minimal.
Local-first with IndexedDB history, keyboard support, safe math parser.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New app for professional time tracking with timer, projects, clients,
and reports. Local-first architecture with IndexedDB + mana-sync.
- Timer store with start/stop/resume, auto-save every 10s
- 6 local-store collections: clients, projects, timeEntries, tags, templates, settings
- TimerCard with live counter, project selector, billable toggle
- EntryItem with inline-expand editing, EntryList with day grouping
- EntryForm modal with quick-duration buttons (15m-4h)
- QuickStart pills from recent entries
- Projects page: card grid, color coding, budget progress, inline CRUD
- Clients page: billing rates, project rollup, inline CRUD
- Reports page: stats grid, billable breakdown, project/daily charts
- i18n: German + English
- Registered in shared-branding with icon, URLs, dev scripts
- Guest seed: 2 clients, 3 projects, 5 time entries, 4 tags
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add @iconify-json/ph for Phosphor icons via astro-icon. Each app tile
now shows a clean Phosphor icon instead of an emoji.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>