Persona-Runner / Claude Desktop / Web-App-Mission-Runner können jetzt
Comic-Characters bauen, iterieren und pinnen — same Auto/Propose-
Pattern wie die Story-Tools.
MCP (packages/mana-tool-registry/src/modules/comic.ts):
- comic.listCharacters (read/auto): Pull, decrypt, filter (style?,
favoriteOnly?), liefert {id, name, style, addPrompt, source-Refs,
variantMediaIds, pinnedVariantId, variantCount, tags, isFavorite}.
- comic.createCharacter (write/propose): legt nur die Row an —
trennt Anlegen von Generierung damit der Agent reviewen kann
bevor Credits fließen. Liefert characterId zurück.
- comic.generateVariant (write/propose, kostet Credits): pullt
Character-Row, dekodiert, ruft /picture/generate-with-reference
mit n=count (default 4) + Stil-Prefix + Identity-Anchor-Prompt,
schreibt N picture.images mit comicCharacterId-Back-Ref, pusht
field-level Update auf variantMediaIds + pinnedVariantId
(auto-pin auf erste neue Variant wenn vorher null).
- comic.pinVariant (write/propose): Set-Equality-Check (variantMediaId
muss in variantMediaIds sein), field-level Update auf
pinnedVariantId. Snapshot-Pattern: bestehende Stories bleiben
unverändert, nur neue Stories nutzen den neuen Pin.
AI_TOOL_CATALOG (packages/shared-ai/src/tools/schemas.ts):
- list_comic_characters (auto)
- create_comic_character (propose) — auto-resolvt face/body-refs aus
meImages-primaries, Agent muss keine mediaIds kennen
- generate_character_variant (propose, count 1-4)
- pin_character_variant (propose)
Web-App-Executors (apps/mana/apps/web/src/lib/modules/comic/tools.ts):
- 4 ModuleTool-Einträge, die an comicCharactersStore +
runCharacterGenerate delegieren — gleicher Code-Pfad wie die UI,
also keine Divergenz zwischen Klick und Agent-Call.
Comic-Autor-Template (packages/shared-ai/src/agents/templates/
comic-author.ts):
- Policy bi-lingual erweitert: snake_case + dot-case Namen für
alle 4 neuen Character-Tools.
- System-Prompt Schritt 3 ergänzt: "Wenn der User noch keinen
passenden Comic-Character hat → list_comic_characters →
create_comic_character → generate_character_variant → pin.
Das ist EINMALIG — der gepinnte Character bleibt für viele
Stories der stabile Identity-Anchor."
- Tool-Liste am Ende vom System-Prompt um den Character-Pfad
ergänzt.
apps/mana/CLAUDE.md Tool-Coverage-Zeile für comic erweitert:
+ create_comic_character / generate_character_variant /
+ pin_character_variant (propose)
+ list_comic_characters (auto)
Tool-Count: comic 3→7. Module 23 unverändert.
107 shared-ai-Tests weiter grün. check für comic-Files clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Macht den Comic-Autor-Template (M6) auch im Web-App-Mission-Runner
nutzbar. Bisher war der Template nur über persona-runner/Claude
Desktop sinnvoll, weil die comic.*-Tools nur im mana-tool-registry
(MCP) lagen. Jetzt kennt die AI Workbench drei neue Tools und der
Template-Policy-Map trägt beide Naming-Konventionen.
AI_TOOL_CATALOG-Einträge (packages/shared-ai/src/tools/schemas.ts):
- list_comic_stories (auto) — filter style?/favoriteOnly?/limit?
- create_comic_story (propose) — title + style + optional
description/storyContext/tags. Character-Refs werden vom Executor
automatisch aus meImages primary face-ref + body-ref gezogen,
also muss der Planner keine mediaIds kennen.
- generate_comic_panel (propose) — storyId + panelPrompt + optional
caption/dialogue + quality. Kostet Credits.
Executors (apps/mana/apps/web/src/lib/modules/comic/tools.ts):
- list: scopedForModule pull + decrypt + filter + sort newest.
- create: resolveCharacterMediaIds() scannt meImagesTable für das
aktive Space, nimmt face-ref+body-ref. Fehler wenn kein Face
hinterlegt ("Lade eines in /profile/me-images hoch"). Delegiert
an comicStoriesStore.createStory — gleiche encryption/event-
pipeline wie StoryForm.
- generate: lädt Story decrypted, delegiert an runPanelGenerate
(identischer Pfad wie PanelEditor in der UI), liefert
panelIndex + imageUrl zurück.
Registrierung in data/tools/init.ts (registerTools(comicTools)).
Template-Policy (comic-author.ts) jetzt bi-lingual: snake_case
(AI_TOOL_CATALOG) UND dot-case (MCP) nebeneinander in tools-Map.
So gilt die Intent-Policy konsistent egal welche Runner-Oberfläche
das Tool nennt — auto für list_comic_stories / comic.listStories,
propose für create_comic_story / comic.createStory /
generate_comic_panel / comic.generatePanel / comic.reorderPanels.
apps/mana/CLAUDE.md Tool-Coverage-Tabelle bekommt eine Comic-Zeile.
Tool-Count jetzt 75→78, Module 22→23. 107 shared-ai tests
weiter grün. check + validate:all clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Agents can now pin a default writing style. When an AI-actor runs
`create_draft` without an explicit styleId, the tool resolves to the
agent's `defaultWritingStyleId` so e.g. a "Marketing-Agent" always
drafts in the Corporate-Tone style and a "Memoir-Agent" in Memoir.
- @mana/shared-ai: optional `defaultWritingStyleId?: string` added to
the Agent interface (plaintext FK, format `preset:<id>` or a custom
WritingStyle uuid). No migration — existing rows stay undefined and
the fallback path no-ops for them.
- ai-agents store: field threaded through CreateAgentInput + AgentPatch
+ the create function's copy-list. `updateAgent` already deep-clones
the patch so nothing else to change there.
- ai-agents ListView: new "Writing" section in the agent detail panel
with a StylePicker (reuses the writing module's component — Vorlagen
+ Meine Stile optgroups). Empty = kein Default.
- writing/tools.ts: `resolveAgentDefaultStyle()` reads the current
actor, guards `isAiActor`, loads the agent row, and returns its
defaultWritingStyleId. Wired into `create_draft` as a fallback when
`params.styleId` is missing. User-invoked calls skip the lookup — a
human omitting styleId means "ad-hoc, no style", not "my default".
`generate_draft_content` needs no change because the draft's styleId
is already set at create time.
107 shared-ai tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Neuer Eintrag in der Template-Galerie unter /agents/templates:
Comic-Autor nimmt einen Tagebuch-Eintrag, eine Notiz oder ein
Library-Review und verwandelt ihn in eine kurze Panel-Folge —
4 Panels Default, Sprechblasen + Captions direkt im Bild durch
gpt-image-2.
Policy-Layout:
- comic.listStories / journal.* / notes.* / library.* / kontext /
goals → auto. Der Agent darf frei stöbern, ohne den User für
jeden Read anzunerven.
- comic.createStory / comic.generatePanel / comic.reorderPanels →
propose. Jedes Write muss der User bestätigen; besonders
generatePanel, das pro Call 3-25 Credits kostet.
- Baseline: alle propose-fähigen Tools aus AI_TOOL_CATALOG kriegen
propose (seed wie im Recherche-Agent) — Cross-Module-Schreibungen
die der Agent eventuell vornimmt (z.B. create_note für eine
Sidecar-Zusammenfassung) landen so als Vorschlag, nicht als
Blitz-Ausführung.
- defaultForAi: propose — sicher per Default.
System-Prompt gibt dem Agent eine klare Rolle: Text lesen, Stil
wählen nach Ton (comic/manga/cartoon/graphic-novel/webtoon), 4
Panels mit prompt+caption?+dialogue? vorschlagen, Protagonist ist
immer der User. "Humor wenn der User es leicht nimmt, ernst wenn
er es ernst nimmt. Nie urteilen." Ton-Hinweis zu englischen vs.
deutschen Dialog-Texten (Englisch rendert stabiler).
Szene öffnet Comic + Journal + ai-missions + ai-workbench nebeneinander.
Eine paused Starter-Mission "Comic aus einem Tagebuch-Eintrag" mit
Concept-Markdown-Vorlage (Eintrag / Stil / Panel-Anzahl / Ton).
Die comic.*-Tools leben in mana-tool-registry (MCP) und sind noch
NICHT im AI_TOOL_CATALOG — dieser Template ist primär für
persona-runner/Claude-Desktop-Seite nutzbar, bis die Workbench-
Integration separat folgt.
107 shared-ai tests weiter grün.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- `app-registry/types.ts` now includes `tips` in the inline help shape,
matching `ModuleHelp` and what `AppPage.svelte` actually renders.
Drops 3 recurring type errors.
- `event-scout` template's `{ kind: 'daily' }` cadence now carries the
required `atHour` / `atMinute` fields (daily 08:00). Drops the 4th
type error — svelte-check is clean.
- `apps/mana/CLAUDE.md` gains a "Scene Scope" section documenting the
pattern: wire `filterBySceneScopeBatch` in the query AND render
`<ScopeEmptyState>` from the empty branch, so users always see why
the list is empty.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add discover_events (auto) and suggest_event (propose) to shared-ai
tool catalog. discover_events reads the discovery feed, suggest_event
creates a proposal to save a discovered event to the user's calendar.
- Add Event-Scout agent template with daily "Events der Woche" mission.
Policy: discover_events=auto, suggest_event=propose, all else denied.
- Add frontend tool implementations in events/tools.ts — discover_events
calls the feed API, suggest_event delegates to discoveryStore.saveEvent.
- Add feedback.ts — computes implicit user profile from save/dismiss
history (category affinity + source quality as 0–2x weight multipliers).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Connects the existing global tag system (@mana/shared-tags, 15+ module
junctions, TagSelector UI) to the AI agent model so different agents
can operate on different slices of the user's data.
Core additions:
1. Agent.scopeTagIds — optional array of global tag IDs. When set,
the agent sees only records tagged with at least one of those tags
(plus untagged records, which stay globally visible). Empty/undefined
= General-Agent, sees everything. Agent-editor grows a <TagSelector>
under "Bereiche (Tag-Scope)".
2. Per-agent kontext documents — new Dexie table `agentKontextDocs`
(v22, encrypted, synced). Each agent can have its own markdown
context doc, replacing the global singleton auto-inject. Runner
tries agent kontext first, falls back to global singleton when
the agent has no dedicated doc.
3. Ambient scope context — `withAgentScope(tagIds, fn)` sets a
module-level scope during the reasoning loop. Auto-tools read it
via `getAgentScopeTagIds()` and filter their result sets.
`filterByScope(records, getTagIds)` is the reusable filter
primitive (keeps untagged records, drops mismatched tagged ones).
4. Notes tag junction — `noteTags` table (v22) + `noteTagOps` via
`createTagLinkOps`. Notes was the only major module without
structured tag support. `list_notes` now calls `filterByScope`
so a scoped agent only sees notes tagged with its scope.
Flow: mission starts → runner resolves owning agent → reads
agent.scopeTagIds → wraps entire reasoning loop in withAgentScope →
list_notes (and future list_tasks etc.) auto-filter → planner sees
only scope-relevant records → proposes scoped edits.
Runner tests: 8/8. shared-ai type-check: clean.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Closes out T1 with three templates per category as discussed. The
gallery now renders agent-templates and workbench-templates as two
distinct labeled sections — the earlier implicit "everything's a
template for an agent" framing is gone.
Seed handlers (new):
- apps/mana/apps/web/src/lib/modules/habits/seed.ts — title-based
idempotency (there's no description column on LocalHabit). If a
non-deleted habit with the same title exists, the seed is skipped.
- apps/mana/apps/web/src/lib/companion/goals/seed.ts — title-based
idempotency on companionGoals where status !== 'abandoned'.
- Both pulled in via side-effect imports in missions/setup.ts so the
handler registry is populated before any apply.
New templates:
- 🏋️ Fitness (wellness) — scene body/habits/stretch/sleep + 3 habit
seeds (Täglich 30min Bewegung, 3× Woche Training, 2L Wasser) + 1
goal seed (3 Workouts pro Woche). No agent.
- 💻 Deep Work (work) — scene todo/calendar/notes/times + 2 habit
seeds (1 wichtigste Aufgabe pro Tag, 4h Deep Work pro Tag) + 1
goal seed (20h Deep Work pro Woche). No agent.
Gallery two-section layout:
- Title "Templates" (not "Agent-Templates") — broader framing.
- Section 1: "🤖 Agent-Templates" — filters ALL_TEMPLATES where
category ∈ {'ai','delight'}: Recherche-Agent, Kontext-Agent,
Today-Agent.
- Section 2: "🎨 Workbench-Templates" — filters to the rest:
Calmness, Fitness, Deep Work.
- Each section gets a short intro paragraph so users understand the
distinction before scanning the cards.
- Cards themselves unchanged; rendering extracted into a
{#snippet templateCard(t)} shared between both sections.
- Per-category arrays computed once at module-load time (const in
<script>); no per-render filter cost.
Result: each section has 3 templates, categorised by "does this
create an AI agent" rather than by use-case. Keeps the separation
honest — Agent-Templates set up autonomous work; Workbench-Templates
set up the user's own workspace.
Tests: shared-ai 26/26, webapp svelte-check 0 errors, 0 warnings.
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>
First pass of the Multi-Agent discoverability UX. A new /agents/
templates route showcases pre-configured agents; clicking one creates
agent + scene + starter mission(s) as a single bundle. Addresses the
"blank form anxiety" + "user doesn't know what agents are for"
observations from the UX brainstorm.
Three templates for v1 (shared-ai/src/agents/templates/):
- 🔍 Recherche-Agent — reads sources one by one, writes a note per
source, summarizes into a report. Manual-cadence mission; all
writes propose so user curates.
- 🧭 Kontext-Agent — learns about the user via a weekly check-in.
Reads kontext/notes/goals, asks 2-3 questions, proposes a diff-
style context update. Weekly Sunday cadence.
- 🌅 Today-Agent — researches "on this day" history each morning,
writes a 4-8 line German poem, proposes a journal note. Daily 7am
cadence. A "delight" agent, not a productive one.
Each template packs (agent config, scene layout, starter mission):
- AgentTemplate type lives in @mana/shared-ai — pure data, no runtime
imports. Adding a new template = drop a file in templates/ and
extend ALL_TEMPLATES.
- Template-specific policies derive from the proposable-tool list so
drift-guard catches divergence from the canonical set.
- Starter missions default to startPaused=true — user sees the
mission ready-to-go and hits Play when ready. Prevents surprise
autonomous work on first apply.
Applicator (data/ai/agents/apply-template.ts):
- Creates agent → scene (if template defines one) → missions in
order. Agent failure = abort; scene/mission failures surface as
warnings in the result without blocking.
- Duplicate-name handling: falls through to findByName, returns
existing agent with wasExisting=true; scene is skipped in that
case to avoid clone-proliferation.
Gallery page /(app)/agents/templates/+page.svelte:
- Three large cards side-by-side (stacks on mobile) with avatar /
label / tagline / meta chips (Scene, N Missionen).
- Click opens detail panel with full description, scene preview
(app-ids + widths), mission preview (title / objective / cadence),
and override checkboxes (create scene, create missions, start
active vs paused).
- Success panel shows what landed with warnings inline; CTA back to
workbench.
Discoverability in /ai-agents module:
- Bar now has two buttons: "Aus Template" (primary, goto templates
route) + "Eigener Agent" (secondary, opens the existing blank-form
create mode).
- When only the default "Mana" agent exists, render a dashed promo
banner at the top linking to the template gallery. Disappears as
soon as the user has a second agent.
Tests: webapp svelte-check 0 errors, 0 warnings. shared-ai 26/26.
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>