Commit graph

16 commits

Author SHA1 Message Date
Till JS
11f768b8e5 docs(invoices): ClubDesk vs. Mana comparison + invoices module plan
Competitive analysis of ClubDesk (reeweb ag, ~20'000 DACH clubs) with a
dual-use roadmap identifying features that benefit both clubs and general
users (freelancers/creators). First chosen step: invoices module with
Swiss QR-Bill as the CH-differentiator.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 15:27:57 +02:00
Till JS
da47f534bc docs(plans): function-calling migration + removal of propose/approve gate
Plan for ripping out the fragile text-JSON parser and the propose-approve
flow in one atomic PR. Key shifts:

- LLM uses native function calling — SDK-guaranteed structure, no parser
- Tool policy becomes auto | deny (no propose, no confirm for now)
- Timeline + per-iteration revert replace the proposal inbox as the
  review surface; missions run end-to-end without human approval
- Safety via mission-budget, manual-cadence, agent-policy, revert
- No _rationale meta-param (tool name + params are self-explanatory)

Applies to webapp runner, mana-ai server runner, and companion chat —
all three share one runPlannerLoop from @mana/shared-ai after migration.
Net: ~1000 LoC deleted, ~600 added.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 15:10:23 +02:00
Till JS
5d67179842 docs(workbench): plan for scene-scope empty state
Captures the UX gap — a scoped scene that filters out everything shows
the generic "Keine Treffer" with no hint that the scope is the reason
or how to clear it. Plan lays out a minimal Phase 1 (shared
ScopeEmptyState component + clearSceneScope helper, ~10 LOC per
ListView) with optional Phase 2/3 extensions. No code yet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 16:23:13 +02:00
Till JS
b5d55fdb21 feat(events): add Event Discovery — Phase 1 + 2
Phase 1: Manual iCal feeds + Discovery tab
- 5 new DB tables in event_discovery schema (regions, interests,
  sources, discovered_events, user_actions)
- iCal parser (node-ical) with deduplication (SHA-256 hash)
- Crawl scheduler (15-min interval, auto-deactivate after 5 errors)
- CRUD routes for regions, interests, sources + paginated feed endpoint
- Frontend: "Meine Events" / "Entdecken" tab navigation in ListView
- Discovery setup wizard (regions via mana-geocoding + interests)
- DiscoveredEventCard with save/dismiss, SourceManager for iCal feeds
- "Merken" creates a local socialEvent from discovered event

Phase 2: Auto source discovery + LLM extraction + relevance scoring
- Source discoverer: web search via mana-research to auto-find iCal
  feeds and venue websites for a region
- Website extractor: crawl via mana-research /extract, then LLM-based
  event extraction via mana-llm with structured JSON output
- Flexible date parsing (ISO, DD.MM.YYYY), markdown fence stripping
- Relevance scorer: category match, freetext match, haversine distance,
  time proximity, weekend bonus (0-100 clamped)
- Routes: POST regions/:id/discover-sources, PUT/DELETE sources/:id/activate|reject
- Frontend: "Automatisch finden" button, suggested vs active sources UI

107 tests (all passing), no regressions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 15:30:46 +02:00
Till JS
49f315f6be feat(research): Phase 3a — 4 sync research agents
Adds Perplexity Sonar, Claude web_search, OpenAI Responses, and Gemini
Grounding as ResearchAgents behind the same comparison interface as the
search and extract providers.

New endpoints:
  POST /v1/research          — single-agent (or auto-routed to the first
                               provider with a configured key)
  POST /v1/research/compare  — fan-out across N agents, persist all
                               answers + citations in research.eval_*

Each agent normalizes its native response into a common AgentAnswer shape
(answer text + citations[] + tokenUsage), storing the provider's raw
response alongside for later inspection. Implementations use direct HTTP
against each vendor's public API — no SDK deps added.

Auto-routing preference: perplexity-sonar → gemini-grounding →
openai-responses → claude-web-search → (openai-deep-research stubbed for
Phase 3b). Credits orchestration reuses the search/extract executor
pattern (reserve → call → commit/refund).

Deferred to Phase 3b: openai-deep-research (async job queue), migration
of mana-ai + mana-api news-research to call this service directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 15:06:12 +02:00
Till JS
2bdb48bdd1 feat(research): add mana-research service — Phase 1 + 2
New Bun/Hono service on port 3068 that bundles many web-research providers
behind a unified interface for side-by-side comparison. All eval runs
persist in research.* (mana_platform) so quality can be reviewed later.

Providers (Phase 1+2):
  search:  searxng, duckduckgo, brave, tavily, exa, serper
  extract: readability (via mana-search), jina-reader, firecrawl

Endpoints:
  POST /v1/search, /v1/search/compare       — single + fan-out
  POST /v1/extract, /v1/extract/compare     — single + fan-out
  GET  /v1/runs, /v1/runs/:id               — history
  POST /v1/runs/:run/results/:id/rate       — manual eval
  GET  /v1/providers, /v1/providers/health  — catalog + readiness

Auto-routing: when `provider` is omitted, queries are classified via regex
(fast path, 0ms) with optional mana-llm fallback, then routed to the first
available provider for that query type (news → tavily, academic → exa,
semantic → exa, etc.).

Credits: server-key calls go through mana-credits reserve → commit/refund
so failed provider calls don't charge the user. BYO-keys supported via
research.provider_configs (UI arrives in Phase 4).

Cache: Redis with graceful degradation (1h TTL for search, 24h for
extract). Pay-per-use APIs only — no subscription-gated providers.

Docs: docs/plans/mana-research-service.md + docs/reports/web-research-capabilities.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:42:25 +02:00
Till JS
a252160585 feat(library): M3 — progress tracking (pages, episodes, issues) + restart
ProgressControls.svelte renders typ-spezifische Fortschritts-UI:
  - book   → range slider + page input + "Fertig"-Button; auto-completes
             the entry (status=completed, times++) when current == total
  - series → collapsible season/episode grid; each episode is a toggleable
             pill that writes into details.watched with a watchedAt stamp;
             auto-completes once watched.length == totalEpisodes
  - comic  → ±1 issue bumper; auto-completes on issueCount reach
  - movie  → atomic, no progress widget

libraryEntriesStore.restartEntry: flips a completed entry back to active,
stamps startedAt=today, clears completedAt. Preserves the per-episode
watched list so users keep the history of the previous run-through; they
can reset individual episodes via the tracker if they want a fresh pass.

DetailView embeds <ProgressControls {entry}> below the status row and
renders a "↻ Nochmal lesen/sehen" button whenever status === 'completed'.

docs/plans/library-module.md: M1 + M2 + M3 marked DONE with commit IDs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 13:17:22 +02:00
Till JS
8c6502d0ff feat(library): add Bibliothek module — books/movies/series/comics log
M1 skeleton for a new media-consumption module. Single-table design with
a `kind: 'book' | 'movie' | 'series' | 'comic'` discriminator and a
discriminated `details` union for kind-specific fields (pages / runtime /
episode tracker / issue count). Shared kern: status, rating, review,
favourites, times counter, completedAt — which enables cross-media
queries like a year-in-review.

Dexie migration v26 was already registered in module-registry.ts /
database.ts via the preceding wetter commit (62aac6dfd); this commit
adds the actual module code, encryption registry entry, app-icon,
MANA_APPS entry, Kreativität & Medien category row, and the module
plan at docs/plans/library-module.md.

Encrypted fields (via ENCRYPTION_REGISTRY):
  title, originalTitle, creators, review, tags
Plaintext (intentional):
  kind, status, year, rating, genres, completedAt, isFavorite, times,
  externalIds, details — all needed for the tab filter, status chips,
  Jahresrückblick range-scan, and progress UIs.

Product decisions (frozen in the plan):
  - audiobooks = kind='book' with details.format='audio'
  - manga     = kind='comic' (no sub-discriminator)
  - metadata lookup (M7) lands as an endpoint in apps/api, not a
    standalone service

Guest seed ships one example per kind (Dune, Arrival, Severance, Saga)
so first-run users immediately see what the module does.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 03:49:01 +02:00
Till JS
d83fc370a0 docs: update tool coverage table + server-side research + templates
Catches up all docs with the current state of the AI tool system.

services/mana-ai/CLAUDE.md:
- New v0.6 status section documenting NewsResearchClient,
  pre-planning research injection, config.manaApiUrl, and the full
  28-tool / 11-module inventory (17 propose + 11 auto).

apps/mana/CLAUDE.md:
- New "Tool Coverage" table in the AI Workbench section listing all
  tools per module with their policy (propose vs auto).
- New "Templates" subsection documenting the two-section gallery
  (agent vs workbench templates), the seed-handler registry, and
  the current handlers (meditate, habits, goals).
- Architecture cross-reference updated to include §23.

docs/architecture/COMPANION_BRAIN_ARCHITECTURE.md:
- §23.2 gains a "Server-Side Research (mana-ai, ab v0.6)" subsection
  explaining how NewsResearchClient mirrors the client-side research
  pre-step: same endpoints, same trigger regex, but HTTP-direct from
  the Docker network instead of SvelteKit-internal.

docs/plans/README.md:
- workbench-templates.md added to the roadmap table (T1 shipped).
- Multi-agent description updated to mention 28 tools + server-side
  web-research.
- Architecture cross-reference includes §23.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 12:35:40 +02:00
Till JS
a08e45ca16 feat(templates): generalise to WorkbenchTemplate + ship Calmness pilot (T1)
First pass of the workbench-templates plan (docs/plans/workbench-
templates.md) — templates are no longer agent-centric but a general
"starter kit" bundle: optional agent + optional scene + optional
missions + optional per-module seeds. Pilot non-AI template "Calmness"
ships alongside.

Shape generalisation (packages/shared-ai/src/agents/templates/types.ts):
- AgentTemplate renamed to WorkbenchTemplate; all fields now optional
  (agent, scene, missions, seeds). Back-compat AgentTemplate alias
  kept so research/context/today keep compiling.
- Added `category: 'ai'|'wellness'|'work'|'lifeEvent'|'delight'` +
  `icon` (for non-agent templates that have no avatar) + `version`
  field (for future update-detection).
- New WorkbenchTemplateSeedItem shape: `{stableId?, data: unknown}`.
  Module-specific seed payloads are typed at the handler side.
- Existing three AI templates nachgezogen: category='ai' (or
  'delight' for today-agent), icon, version='1'.

Seed infrastructure:
- apps/mana/apps/web/src/lib/data/ai/agents/seed-registry.ts — in-
  memory handler map keyed by module name; module-local seed.ts files
  register themselves at import time.
- apps/mana/apps/web/src/lib/modules/meditate/seed.ts — first handler:
  createPreset-based, idempotent via stableId embedded as HTML
  comment in the preset description (T1 pragmatism; T2 adds a proper
  column on the preset schema).
- data/ai/missions/setup.ts pulls `import '$lib/modules/meditate/seed'`
  so the handler is registered before any template is applied.

Applicator upgrades (data/ai/agents/apply-template.ts):
- Agent step now optional — skipped cleanly when template has no
  agent part.
- New step 4: seeds. Walks template.seeds, looks up the handler for
  each module, aggregates per-item outcomes (created/skipped-exists/
  failed) into result.seedOutcomes. Missing handler = warning, not
  fatal. Crypto/encryption unchanged — seeds go through the same
  module stores that module code already uses.
- Result shape gains `seedOutcomes: Record<string, SeedOutcome[]>`
  so the gallery can show "3 new, 1 already there".

Calmness pilot (packages/shared-ai/src/agents/templates/calmness.ts):
- category='wellness', NO agent, scene with meditate/mood/journal/
  sleep apps, two meditate preset seeds:
  * 4-7-8 Atmung (breathing preset)
  * Body-Scan 10min (bodyscan preset with 9 scan steps)
- Each seed has a stableId so re-apply is idempotent.

Gallery updates (routes/(app)/agents/templates/+page.svelte):
- Card avatar falls back to t.icon when no agent. "Agent" chip shows
  only for agent-templates; "N Seeds" chip shows for templates with
  seeds.
- Detail header shows "Workbench-Setup ohne AI-Agent" when no agent.
- New "Seeds" preview section: lists per-module counts + item names.
- Options section gains a "Seed-Daten in Module einpflegen" checkbox.
- Success panel shows seed summary: "3 Seeds neu, 1 bereits
  vorhanden".

Tests: shared-ai 26/26, webapp svelte-check 0 errors, 0 warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 01:07:41 +02:00
Till JS
e8077a44b4 docs: flesh out Multi-Agent plan shipping log + Team Workbench forward plan
The Multi-Agent Workbench shipped end-to-end (commits 1771063df through
7c89eb625). This commit turns the plan doc into a proper history + post-
mortem and captures the deferred Team-Workbench as its own forward plan
so the architectural breadcrumbs don't rot.

docs/plans/multi-agent-workbench.md:
- Status bumped to  Shipped; every phase checkbox flipped.
- Open-questions section rewritten with the decisions that were
  actually made (name-unique via store write-time check, per-source
  system principalIds, policy fully migrated, scene binding default-
  empty with smart suggestion).
- New "Shipping-Historie" table mapping each phase to its commit, the
  number of files touched, and the test outcome.
- New "Lessons Learnt + Follow-Up Ideen" with:
  * What went better than expected (L3 Actor cutover, getOrCreate
    instead of unique index, displayName caching)
  * Thin spots worth revisiting (avatar not on Actor, missing token
    counter for budget, no missions list on agent detail, no
    drag-reassign, scene binding doesn't drive filters yet)
  * Five deferred follow-up projects (team features, agent memory
    self-update, agent-to-agent messaging, meta-planner, per-agent
    encryption domains)

docs/plans/team-workbench.md (NEW):
- Full forward-looking plan for the deferred Team-Workbench.
- Two use-cases (human multi-user vs multi-agent sharing team
  context) with the observation that they share the same infra.
- Decision candidates table (still open — meant as T0 RFC fodder,
  not baked in).
- Architecture sketch with data-model deltas over the current
  single-user shape.
- Encryption subsection dedicated to the hardest problems: team-key
  wrapping per member (reuses Mission-Grant pattern), member-removal
  rotation (lazy vs eager), Zero-Knowledge-mode incompatibility.
- T0..T6 phasing (~7 weeks for a clean first-pass).
- Section "Wie Multi-Agent dafür den Weg geebnet hat" enumerating
  the four invariants the shipped Phase 0-7 deliberately preserved
  to make this plan cheap when it lands.

docs/plans/README.md (NEW):
- Index doc with the AI/Workbench roadmap as an ASCII flow so future
  contributors can locate themselves in the sequence without reading
  three 400-line plans first.

docs/future/AI_AGENTS_IDEAS.md:
- Header marks Point 1 (encrypted tables) as shipped via the Mission
  Grant plan; points 2-8 stay relevant. Cross-link to all three plan
  docs so this stays the go-to backlog.

services/mana-ai/CLAUDE.md:
- Design-context header expanded to link to all four related docs
  (arch §20-22, both shipped plans, forward team plan, ideas backlog).

No code changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:17:04 +02:00
Till JS
bc77b36234 feat(agents): Agent CRUD + default bootstrap + Mission.agentId (Phase 2)
Second phase of the Multi-Agent Workbench rollout (docs/plans/
multi-agent-workbench.md). Builds on Phase 1's identity-aware Actor.

Adds the Agent primitive — a named AI persona that owns Missions,
carries its own policy + memory, and (from Phase 3 on) drives the
Workbench lens. Everything is wired; a single user currently has one
"Mana" default agent until the UI (Phase 5) lets them create more.

Shared types (@mana/shared-ai):
- agents/types.ts: Agent, AgentState, DEFAULT_AGENT_ID/NAME constants
- policy/types.ts: AiPolicy + PolicyDecision (moved from webapp so
  Agent.policy can reference it without a runtime dep on the web app)
- missions/types.ts: new optional Mission.agentId field

Webapp data layer:
- data/ai/agents/{types,store,queries,bootstrap}.ts
- Dexie schema v19 adds `agents` table (indexes on state, name,
  [state+name]); sync registered under the existing ai app-id
- Encryption registry: agents.systemPrompt + agents.memory encrypted;
  name/role/avatar/policy stay plaintext for search + UI rendering
- DuplicateAgentNameError thrown at write time (not a Dexie unique
  index — bootstrap races between tabs would otherwise hit
  ConstraintError; store now resolves via getOrCreateAgent)
- bootstrap.ts: ensureDefaultAgent + backfillMissionsAgentId. The
  backfill runs once per device (localStorage sentinel) so missions
  that pre-date the rollout get stamped with the default agent's id.
  Called fire-and-forget from startMissionTick() during layout init.

Runner threading (already merged into d5c351d63 via Till's debug-log
commit that picked up my uncommitted edits):
- runner.ts + server-iteration-staging.ts now resolve mission.agentId
  to the real Agent and build makeAgentActor with agent.name as
  displayName. Missing-agent fallback keeps using LEGACY_AI_PRINCIPAL
  so historical writes still attribute cleanly.

Tests: shared-ai 26/26, mana-ai 35/35, svelte-check 0 errors.
Agent store vitest suite is present but blocked by a pre-existing
\$lib alias resolution issue in the webapp vitest config that
predates this phase (proposals/store.test.ts is broken the same way
on HEAD). Will address separately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:35:49 +02:00
Till JS
bb3da78d5c feat(ai): Mission Grant rollout gating — flag, alerts, runbook, user docs
Phase 4 — everything needed to flip the Mission Key-Grant feature on
safely per deployment. No new behaviour; purely operational plumbing.

- PUBLIC_AI_MISSION_GRANTS feature flag (default off). hooks.server.ts
  injects window.__PUBLIC_AI_MISSION_GRANTS__, api/config.ts exposes
  isMissionGrantsEnabled(). Grant UI (dialog + status box) and the
  Workbench "Datenzugriff" tab both hide when the flag is off.
- PUBLIC_MANA_AI_URL added to the injection set so the webapp can reach
  the new audit endpoint from production.
- Prometheus alerts (new mana_ai_alerts group):
  - ManaAIServiceDown (warning, 2m)
  - ManaAIGrantScopeViolation (critical, 0m) — MUST stay at 0; any
    increment pages immediately
  - ManaAIGrantSkipsHigh (warning, 15m) — flags keypair drift
  - ManaAIPlannerParseFailures (warning, 10m) — prompt/LLM drift
- Runbook in docs/plans/ai-mission-key-grant.md: initial keypair gen,
  leak-response procedure (rotate + invalidate all grants + audit),
  scope-violation triage.
- User-facing doc in apps/docs security.mdx: new "AI Mission Grants"
  section with the three hard constraints (ZK users blocked, scope
  changes invalidate cryptographically, revocation is one click) plus
  an honest threat-model comparison column showing where grants shift
  the tradeoff.

Rollout remaining (not code): generate keypair on Mac Mini, provision
MANA_AI_PRIVATE_KEY_PEM + MANA_AI_PUBLIC_KEY_PEM via Docker secrets,
flip PUBLIC_AI_MISSION_GRANTS=true starting with till-only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:02:47 +02:00
Till JS
6882ffb626 feat(shared-ai): Mission Key-Grant contract + plan for encrypted server-side runs
Foundation for Phase 2+ of the Mission Key-Grant flow: lets mana-ai
execute missions that depend on encrypted inputs (notes/tasks/events/
journal/kontext) without needing an open browser tab. Opt-in per
mission, Zero-Knowledge users excluded.

- Canonical HKDF-SHA256 derivation (scope-bound via tables + recordIds
  in the HKDF info string → scope changes invalidate the grant
  cryptographically, not just via a runtime check)
- Mission.grant field on the shared Mission type
- Golden snapshot + drift-guard test so webapp wrap path and mana-auth
  wrap endpoint can't silently diverge
- Ideas backlog at docs/future/AI_AGENTS_IDEAS.md
- Full rollout plan at docs/plans/ai-mission-key-grant.md
- COMPANION_BRAIN_ARCHITECTURE.md §21 captures the flow + privacy
  guarantees + non-goals

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 13:41:35 +02:00
Till JS
777810d0d2 docs(mail): add TODO checklist for remaining Phase 1-4 work
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 20:46:00 +02:00
Till JS
a3de6b3d81 feat(mail): add mana-mail service and frontend module (Phase 1 MVP)
Backend: Hono/Bun service on port 3042 with JMAP client for Stalwart,
account provisioning (@mana.how addresses on user registration),
thread/message/send/label API endpoints, and JWT + service-key auth.

Frontend: Mail module with 3-column inbox UI (mailboxes, thread list,
detail/compose), local-first encrypted drafts in Dexie, and API-driven
thread fetching. Scoped CSS with theme tokens.

Integration: Dexie v11 schema, mail pgSchema in mana_platform,
mana-auth fire-and-forget hook for account provisioning,
getManaMailUrl() in API config, app registry + branding update.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 20:35:54 +02:00