Commit graph

68 commits

Author SHA1 Message Date
Till-JS
c843531595 feat(analytics): update Umami tracking IDs for all web apps
Update all 15 web apps with correct Umami website IDs:
- calendar, chat, clock, contacts, manacore, manadeck, picture, planta, todo: updated IDs
- zitare, storage, nutriphi, skilltree, photos, presi: added tracking

All IDs now match the websites configured in Umami.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 11:14:16 +01:00
Till-JS
ceebb5dda6 feat(zitare): add settings store and i18n updates 2026-02-13 23:29:50 +01:00
Till-JS
23a1c5e539 feat(calendar): add larger resize handles, live time preview, and drag-to-create
- Increase resize handle height from 8px to 20px with visual grip indicator
- Show live time preview during resize operations
- Add drag-to-create functionality: click and hold on empty cell to drag and create events with custom duration
- Fix zitare TypeScript errors (SearchResultItem -> QuickInputItem, createUserSettingsStore API)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 23:03:23 +01:00
Till-JS
ad8d5c3bc0 🔧 chore(zitare): change zitare-web port from 5012 to 5018
Port 5012 is used by calendar-web

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 19:40:50 +01:00
Till-JS
e62782f627 🐛 fix(zitare): correct health check endpoint path in Dockerfile
Changed /api/health to /health to match actual endpoint

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 19:35:08 +01:00
Till-JS
09465fe36b 🔧 chore(zitare): add drizzle.config.ts for backend
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 19:31:25 +01:00
Till-JS
533bd90093 🚀 feat(zitare-web): add Docker deployment infrastructure
- Add Dockerfile for production build
- Add docker-entrypoint.sh for runtime config
- Add hooks.server.ts for client-side env injection
- Add zitare-web service to docker-compose.macmini.yml
  - Port 5012
  - Depends on zitare-backend
  - Health check on /health endpoint
2026-02-13 14:49:26 +01:00
Till-JS
ef9bd5656d 🔧 debug(bot-services): add logging to getToken for SSO-Link debugging
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 14:06:37 +01:00
Till-JS
c54ff859d6 🚀 feat(zitare): add Docker deployment infrastructure
- Add Dockerfile for zitare-backend (multi-stage build, port 3007)
- Add docker-entrypoint.sh for database setup
- Add zitare-backend service to docker-compose.macmini.yml
- Update matrix-zitare-bot to depend on zitare-backend
- Add zitare-backend to CI workflow (change detection + build job)
2026-02-13 13:49:15 +01:00
Till-JS
431957ca05 📝 chore(zitare): complete metadata for all quotes
- Add missing year, source, and authorBio fields to all quotes
- Fix incorrect weis-1 quote (was Konfuzius, now Laozi with Tao Te King)
- Add new quotes: weis-9 (Konfuzius), liebe-6 (Saint-Exupéry), leben-7 (Horaz),
  erfolg-5/6 (Goethe, Sassoon), glueck-6 (Aristoteles), freund-5 (Cicero),
  mut-6 (Vergil), hoff-4/5 (Tutu, Cicero), natur-5/6 (Muir, Heraklit)
- Total: 60 quotes with complete multilingual metadata
- All author bios now include birth/death years
2026-02-13 13:40:36 +01:00
Till-JS
742aa0e046 feat(zitare): add multilingual support and expanded quote metadata
- Add 6-language support: original, de, en, it, fr, es
- Add quote metadata: source, year, tags, imageUrl, authorBio, verified
- Add originalLanguage field to preserve original quote language (la, el, zh, sa, etc.)
- Update all 50 quotes with full translations and metadata
- Add new utility functions: getQuoteText, getQuotesByTag, getAllTags,
  getQuotesByAuthor, getVerifiedQuotes, getQuotesByYearRange,
  getQuotesByOriginalLanguage
- Update matrix-zitare-bot to use new multilingual schema
2026-02-13 12:42:50 +01:00
Till-JS
d961508a81 🩹 fix(zitare): use proper German umlauts in quotes
Replace ASCII representations with actual umlauts:
- ae → ä, oe → ö, ue → ü, ss → ß
- Also fix author names (Saint-Exupéry, Kierkegaard, Linné)
2026-02-13 12:35:41 +01:00
Till-JS
74c1cfed4f feat(zitare): add @zitare/content package for shared quotes
- Create new @zitare/content package with 50 German quotes
- Include 10 categories: motivation, weisheit, liebe, leben, erfolg,
  glueck, freundschaft, mut, hoffnung, natur
- Add utility functions: getRandomQuote, getDailyQuote, searchQuotes,
  getQuotesByCategory, formatQuote, etc.
- Migrate matrix-zitare-bot to use the shared package
- Remove hardcoded quotes from bot configuration
2026-02-13 12:30:41 +01:00
Till-JS
7a2acd4bbe 🐛 fix(admin): remove api/v1 prefix from admin controllers
All backends with setGlobalPrefix('api/v1') were registering routes
as /api/v1/api/v1/admin instead of /api/v1/admin. Changed all admin
controllers to use @Controller('admin') instead of @Controller('api/v1/admin').

Affected backends:
- calendar
- contacts
- picture
- presi
- todo
- zitare
- chat

Note: storage backend still uses @Controller('api/v1/admin') as it has
no global prefix.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 14:03:00 +01:00
Till-JS
03c9267a69 🐛 fix(admin): use PostgresJsDatabase instead of NodePgDatabase
All backends use postgres-js driver, not node-postgres. The admin
services incorrectly imported from drizzle-orm/node-postgres which
caused runtime errors: "Cannot find module 'pg'"

Fixed in: chat, todo, calendar, contacts, picture, zitare
2026-02-12 02:34:00 +01:00
Till-JS
a2e2a5b73c feat(admin): add user data dashboard for cross-project data visualization
Add comprehensive admin dashboard to view and manage user data across all projects:

Backend:
- Add admin endpoints to Chat, Todo, Contacts, Calendar, Picture, Zitare, Presi
- Each backend exposes GET/DELETE /api/v1/admin/user-data/:userId
- Service-to-service auth via X-Service-Key header

Aggregation (mana-core-auth):
- GET /api/v1/admin/users - Paginated user list with search
- GET /api/v1/admin/users/:userId/data - Aggregated data from all backends
- DELETE /api/v1/admin/users/:userId/data - GDPR deletion across all projects

Frontend (ManaCore web):
- New User Data tab in admin navigation
- User search page at /admin/user-data
- User detail page with ProjectDataCard components
- GDPR deletion dialog with email confirmation

Presi:
- Migrate user_id from UUID to TEXT for Better Auth compatibility
- Add SQL migration script
2026-02-11 14:59:18 +01:00
Till-JS
feaf27dd14 feat(auth): implement cross-subdomain SSO for all web apps
Add Single Sign-On (SSO) support across all mana.how subdomains:

- Add trySSO() method to @manacore/shared-auth that exchanges session
  cookies for JWT tokens
- Add /api/v1/auth/session-to-token endpoint to mana-core-auth service
- Update all 15 web apps to try SSO during auth initialization

SSO Flow:
1. User logs in on any app (e.g., calendar.mana.how)
2. Session cookie is set with Domain=.mana.how
3. When visiting another app (e.g., todo.mana.how), it checks for
   local tokens first
4. If no local tokens, tries SSO via session cookie
5. Session cookie is exchanged for JWT tokens via new endpoint
6. User is automatically authenticated

Apps updated: calendar, chat, clock, contacts, manacore, manadeck,
nutriphi, picture, planta, presi, questions, skilltree, storage,
todo, zitare

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 13:17:04 +01:00
Till-JS
df2c518a5c feat(auth): add missing auth pages for zitare and planta
- Add zitare login page with standard pattern
- Add zitare forgot-password page
- Add planta forgot-password page
- Refactor planta register to use shared RegisterPage component

All apps now have consistent login, register, and forgot-password pages
using the shared auth-ui components and i18n translations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 13:09:42 +01:00
Till-JS
d703ccfd80 feat(auth): add resend verification email to registration screen
- Add prominent email verification success UI with resend button
- Show resend verification option when registration fails with "not verified" error
- Improve form spacing with space-y-4 for better visual consistency
- Add translations for resend verification in all languages (de, en, fr, it, es)
- Update all 13 app register pages to pass onResendVerification prop

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 12:44:28 +01:00
Till-JS
a23430f210 feat: add KeywordCommandDetector to all 19 Matrix bots
All bots now support natural language commands via KeywordCommandDetector:
- matrix-chat-bot (gespraeche, modelle, verlauf, etc.)
- matrix-mana-bot (todo, timer, kalender, summary, etc.)
- matrix-manadeck-bot (decks, karten, lernen, mana, etc.)
- matrix-planta-bot (pflanzen, giessen, faellig, etc.)
- matrix-presi-bot (presis, folien, themes, teilen, etc.)
- matrix-project-doc-bot (projekte, generate, export, etc.)
- matrix-questions-bot (fragen, recherche, antwort, etc.)
- matrix-skilltree-bot (skills, xp, stats, aktivitaeten, etc.)
- matrix-stats-bot (stats, heute, woche, realtime, etc.)
- matrix-storage-bot (dateien, ordner, teilen, suche, etc.)
- matrix-tts-bot (voice, voices, speed, etc.)

All bots include COMMON_KEYWORDS (hilfe, help, status).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:26:25 +01:00
Till-JS
271496b0fd 🚀 ci: add mana-search and api-gateway to Docker builds
- Add mana-search + SearXNG to docker-compose.macmini.yml
- Add api-gateway dependency on mana-search
- Add CI workflow for building mana-search Docker image
- Add CI workflow for building api-gateway Docker image
2026-01-29 18:34:18 +01:00
Till-JS
fbd315eac0 🔧 chore: create @manacore/shared-nestjs-setup and migrate 8 backends
- Create shared package with bootstrapApp(), configureCors(), configureValidation()
- Migrate: chat, calendar, contacts, zitare, clock, planta, presi, nutriphi
- Skip complex backends: manadeck, picture, todo, skilltree, questions, storage

Savings: ~280 LOC (8 backends × 35 LOC each)
2026-01-29 17:25:51 +01:00
Till-JS
d0d2855adb 🔧 chore: create @manacore/shared-tsconfig and migrate 13 backends
- Create shared TypeScript config package with:
  - base.json: Common options (ES2021, skipLibCheck, etc.)
  - nestjs.json: NestJS backend config (decorators, commonjs)
  - sveltekit.json: SvelteKit web config
  - expo.json: Expo mobile config
  - astro.json: Astro landing config

- Migrate 13 NestJS backends to use shared config:
  calendar, chat, clock, contacts, nutriphi, picture, planta,
  presi, questions, skilltree, storage, todo, zitare

- Skip manadeck (uses nodenext module system)

Savings: ~280 LOC (13 backends × ~22 LOC each)
2026-01-29 16:38:57 +01:00
Till-JS
2ccd063628 feat(auth): redirect users to source app after email verification
Add sourceAppUrl tracking during registration to redirect users back
to the app they registered from after email verification. Includes
URL validation for security (only *.mana.how, mana.how, localhost).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 01:31:31 +01:00
Till-JS
2480d92699 🔧 chore(watchtower): try list format for telegram notification URL
Use list format for environment variables as suggested in shoutrrr
issue #45 to avoid YAML parsing issues with colon in bot token.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 10:14:30 +01:00
Till-JS
49a8c652da 🔀 merge: integrate till-dev into main
Merge till-dev branch containing:
- Planta plant care tracking application
- Clock backend with alarms, timers, world clocks
- Zitare backend with favorites and lists
- Various app improvements and fixes
- Auth system updates
- Infrastructure improvements

Note: Some type-check issues may need resolution after merge.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 15:40:43 +01:00
Wuesteon
079b55a796 delete old apps due to context pollution 2025-12-25 17:23:14 +01:00
Wuesteon
4c44764838 1. Brevo email integration (API key, sender settings)
2. URL configuration fix (BASE_URL, FRONTEND_URL)
  3. Password reset URL pointing to frontend instead of API
2025-12-17 18:11:13 +01:00
Wuesteon
d3e11b320a 🐛 fix(auth): require name field in registration forms
Add required name field (min 2 chars) to all registration forms to fix
Better Auth validation error. Updates backend DTO, shared-auth service,
shared-auth-ui RegisterPage component, i18n translations, and all app
auth stores and register pages.
2025-12-16 20:28:28 +01:00
Wuesteon
42e5e97390 ️ fix: resolve all svelte-check a11y warnings across web apps
- Fix 121 accessibility warnings across 9 web apps (manacore, clock, chat,
  manadeck, calendar, zitare, contacts, picture, todo)
- Add proper ARIA attributes (role, tabindex, aria-label) to interactive elements
- Add onkeydown handlers alongside onclick for keyboard accessibility
- Add svelte-ignore comments for intentional patterns (modals, dropdowns)
- Update svelte-check threshold from error to warning in pre-commit hook
- Fix script compatibility for bash 3.x (remove associative arrays)
- Add comprehensive documentation for svelte-check patterns and fixes

All web apps now pass svelte-check with 0 errors and 0 warnings.
Pre-commit hooks will block any future commits with warnings.
2025-12-15 19:09:01 +01:00
Wuesteon
3011d77caf ♻️ refactor(contacts,zitare): use dynamic runtime URLs in auth stores
Replace hardcoded localhost URLs with dynamic getAuthUrl() and
getBackendUrl() functions that:
- Read from injected window variables in client-side code
- Fall back to process.env for SSR
- Default to localhost for local development

This ensures proper URL resolution in Docker/production environments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-15 14:13:00 +01:00
Wuesteon
0fa154c7d6 🐛 fix(shared-auth): add automatic token refresh on 401 responses
- Add backendUrl parameter to initializeWebAuth() for interceptor config
- Expand isTokenExpiredResponse() to match more error patterns:
  - "invalid token", "token validation failed", "claim" (jose errors)
  - ERR_JWT_EXPIRED error code
- Update all web apps to pass backendUrl for automatic refresh:
  - picture (3006), chat (3002), zitare (3007), contacts (3015)
  - calendar (3014), clock (3017), todo (3018)
- Fix API client default port in picture web app

This prevents users from being randomly signed out when JWT expires.
The interceptor now catches 401 responses and automatically refreshes
the token before retrying the request.
2025-12-12 20:47:43 +01:00
Till-JS
a898160423 refactor(todo): rename Labels to Tags for consistency across apps
- Rename route /labels to /tags and /label/[id] to /tag/[id]
- Rename LabelSelector component to TagSelector
- Update all UI texts from "Labels" to "Tags"
- Update navigation items and references
- Align terminology with Calendar and Contacts apps

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 21:12:08 +01:00
Wuesteon
39b04e4b34 🐛 fix(auth): enable automatic token refresh across all web apps
Users were getting signed out after ~15 minutes because API clients were
reading tokens directly from localStorage without triggering the refresh
logic. The tokenManager exists with proper refresh capability but was
never being used.

Changes:
- Add getValidToken() method to auth stores in 9 web apps
- Update API clients to use authStore.getValidToken() instead of localStorage
- Token refresh now happens proactively before requests fail

Apps updated: chat, calendar, picture, zitare, contacts, todo, clock, manacore, manadeck

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-10 20:52:29 +01:00
Till-JS
ee42b6cc76 feat: major update with network graphs, themes, todo extensions, and more
## New Features

### Network Graph Visualization (Contacts, Calendar, Todo)
- D3.js force simulation for physics-based layout
- Zoom & pan with mouse/touchpad
- Keyboard shortcuts: +/- zoom, 0 reset, Esc deselect, / search, F focus
- Filtering by tags, company/location/project, connection strength
- Shared components in @manacore/shared-ui

### Central Tags API (mana-core-auth)
- CRUD endpoints for tags
- Schema: tags table with userId, name, color, app
- Shared tag components in @manacore/shared-ui

### Custom Themes System
- Theme editor with live preview and color picker
- Community theme gallery
- Theme sharing (public, unlisted, private)
- Backend API in mana-core-auth

### Todo App Extensions
- Glass-pill design for task input and items
- Settings page with 20+ preferences
- Task edit modal with inline editing
- Statistics page with visualizations
- PWA support with offline capabilities
- Multiple kanban boards

### Contacts App Features
- Duplicate detection
- Photo upload
- Batch operations
- Enhanced favorites page with multiple view modes
- Alphabet view improvements
- Search modal

### Help System
- @manacore/shared-help-content
- @manacore/shared-help-ui
- @manacore/shared-help-types

### Other Features
- Themes page for all apps
- Referral system frontend
- CommandBar (global search)
- Skeleton loaders
- Settings page improvements

## Bug Fixes
- Network graph simulation initialization
- Database schema TEXT for user_id columns (Better Auth compatibility)
- Various styling fixes

## Documentation
- Daily report for 2025-12-10
- CI/CD deployment guide

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 02:37:46 +01:00
Wuesteon
f440ca2a8d fix(db): use TEXT for user_id columns across entire codebase
Better Auth generates non-UUID user IDs (32-char base62 format like
'otUe1YrfENPdHnrF3g1vSBfpkQfambCZ'). Changed all `uuid('user_id')` to
`text('user_id')` in Drizzle schemas for consistency with auth system.

Affected packages/apps:
- apps/calendar, clock, picture, zitare
- games/figgos, voxelava
- packages/manadeck-database, news-database, uload-database
- services/mana-core-auth (feedback schema)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 16:30:51 +01:00
Till-JS
7b8335a3fb fix(settings): unify global settings across web apps
- Add desktopPosition prop to Clock layout for nav sync
- Remove duplicate local theme/locale controls from Clock, Calendar, Todo, Zitare
- Move GlobalSettingsSection to proper position in settings pages
- Remove weekStartsOn from Calendar (now handled by GlobalSettingsSection)

All web apps now consistently use GlobalSettingsSection for:
- Navigation (desktopPosition, sidebarCollapsed)
- Theme (mode, colorScheme)
- Language (locale)
- General (startPage, weekStartsOn, soundsEnabled)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 16:28:00 +01:00
Wuesteon
d41d060bb3 Merge branch 'dev-1' into dev 2025-12-05 17:57:26 +01:00
Till-JS
fd3341ff4d refactor(zitare): reorganize routes into (app) layout group
Move all authenticated routes into (app) layout group for better
code organization and layout management.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 04:20:21 +01:00
Wuesteon
9c47119535 Fix wrong type
import, make auth and chat work
2025-12-04 23:25:25 +01:00
Till-JS
bbe540c3f1 feat: add global start page setting across all apps
- Add GeneralSettings types (startPages, weekStartsOn, soundsEnabled)
- Create app-routes.ts with available routes for 12 apps
- Extend UserSettingsStore with general settings support
- Update GlobalSettingsSection with start page selector UI
- Add start page redirect logic to all app layouts:
  - Clock, Calendar, Todo, Zitare, Picture
  - Manadeck, Presi, Chat, Manacore
- Create user-settings stores for Clock and Todo apps

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:31:04 +01:00
Wuesteon
e32e4b1b3a 🐛 fix(build): remove recursive build scripts from parent packages
Parent workspace packages (apps/*/package.json, games/*/package.json) had
build scripts that called 'turbo run build' or 'pnpm run --recursive build',
creating infinite recursion when root turbo orchestrates builds.

When root turbo runs 'build', it finds packages with build scripts and
executes them. If those scripts also call 'turbo run build', it spawns
another turbo process → infinite loop.

Changes:
- Removed 'build' script from 7 parent packages (calendar, contacts, zitare, picture, presi, mana-games, voxel-lava)
- Also removed redundant 'clean', 'lint', 'type-check' scripts where they had recursive calls
- Root turbo.json already handles orchestration of these tasks

This follows the guideline in CLAUDE.md:
> Parent workspace packages must NEVER have scripts that call turbo run
> for tasks that turbo orchestrates from the root.

Fixes CI build timeout (was running for 10+ minutes with infinite task spawning).
2025-12-04 01:59:53 +01:00
Wuesteon
843cf1e678 fixes 2025-12-04 00:51:40 +01:00
Wuesteon
e9caa4a217 fix lint 2025-12-04 00:32:13 +01:00
Wuesteon
16cb8e753b improve code quality 2025-12-03 23:42:37 +01:00
Till-JS
ba746fce04 Merge branch 'main' of https://github.com/Memo-2023/manacore-monorepo 2025-12-03 11:57:30 +01:00
Wuesteon
ea3582d487 💄 style: apply prettier formatting across codebase
Run prettier --write to fix formatting inconsistencies in 80 files
across calendar, contacts, picture, presi, storage, zitare apps
and shared packages/documentation.
2025-12-03 02:02:09 +01:00
Till-JS
482509a574 🐛 fix(theme): add ShadCN-style CSS variable aliases for shared components
- Add aliases without color- prefix (--background, --foreground, --primary, etc.)
- Fix Mana/Subscription page styling across all apps
- Remove conflicting legacy aliases from contacts app.css
- Update contacts mana page to use toast instead of alert

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 00:20:49 +01:00
Till-JS
0e5d923faf feat(auth): add centralized user settings synced across all apps
- Add settings module to mana-core-auth with REST API endpoints
- Create user_settings table with globalSettings and appOverrides (JSONB)
- Add createUserSettingsStore() factory in shared-theme package
- Integrate user settings in all app layouts (calendar, chat, contacts, etc.)
- Support for nav position, theme, locale settings with per-app overrides
- Optimistic updates with localStorage caching for offline support
- Add comprehensive documentation in docs/USER_SETTINGS.md

API Endpoints:
- GET /api/v1/settings - Get all user settings
- PATCH /api/v1/settings/global - Update global settings
- PATCH /api/v1/settings/app/:appId - Set app override
- DELETE /api/v1/settings/app/:appId - Remove app override

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 00:09:47 +01:00
Till-JS
623b1a21b1 feat(landing): add Presi landing page and improve Zitare landing
- Create complete Presi landing page with Astro + Tailwind
- Orange theme (#f97316) matching Presi branding
- Use shared-landing-ui components (HeroSection, FeatureSection, FAQSection, CTASection)
- Add "How it works" section with 4-step guide
- Fix Zitare landing styling with proper Tailwind config
- Add CSS custom properties for consistent theming
- Add deploy:landing:presi script and update deploy:landing:all
- Add dev:presi:landing script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 13:06:38 +01:00