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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>