chore(mana): comic aus unified-App entfernen
Some checks are pending
CD Mac Mini / Detect Changes (push) Waiting to run
CD Mac Mini / Deploy (push) Blocked by required conditions
CI / Detect Changes (push) Waiting to run
CI / Validate (push) Waiting to run
CI / Build mana-search (push) Blocked by required conditions
CI / Build mana-sync (push) Blocked by required conditions
CI / Build mana-api-gateway (push) Blocked by required conditions
CI / Build mana-crawler (push) Blocked by required conditions
Docker Validate / Validate Dockerfiles (push) Waiting to run
Docker Validate / Build calendar-web (push) Blocked by required conditions
Docker Validate / Build quotes-web (push) Blocked by required conditions
Docker Validate / Build todo-backend (push) Blocked by required conditions
Docker Validate / Build todo-web (push) Blocked by required conditions
Docker Validate / Build mana-auth (push) Blocked by required conditions
Docker Validate / Build mana-sync (push) Blocked by required conditions
Docker Validate / Build mana-media (push) Blocked by required conditions
Mirror to Forgejo / Push to Forgejo (push) Waiting to run

Comic-Surface ist nach Comicello (comicello.mana.how + comicello.com)
umgezogen. Comicello hat seit Phase ω-2 (2026-05-18) Feature-Parität
+ Cross-Module-Hooks via mana-share:
- Character-Variant-Render mit pinned-Variant-Anker
- Panel-Render via mana-image-edits
- Panel-Edit/Delete/Reorder
- POST /api/v1/share/receive für externe Apps (Journal/Notes/Calendar/
  Library/Writing können Text-Snippet rüberschicken, Story wird als
  Draft angelegt)
- /comics/new?text=…&sourceModule=… URL-Prefill als Alternative zum
  Server-Roundtrip

Gelöscht / abgebaut:
- Module: apps/mana/.../modules/comic + Routen + Locales
- Backend: apps/api/src/modules/comic, picture/routes
  verifyMediaOwnership-Allowlist auf nur `['me']` reduziert (comic-
  Tag war hier Identity-Anchor-Quelle für panel renders, jetzt
  Comicello-intern)
- shared-branding: APP_ICONS.comic + MANA_APPS comic-Entry
- shared-ai/tools/schemas: ganzer Comic-Block (list_comic_stories,
  create_comic_story, generate_comic_panel, list_comic_characters,
  create_comic_character, generate_character_variant,
  pin_character_variant)
- shared-ai/agents/templates: comic-author.ts + index.ts Eintrag
- mana-tool-registry: modules/comic.ts + types ModuleId 'comic' raus
- Cross-Module: website/embeds resolveComicStories +
  LocalComicStory-Import + 'comic.stories' EmbedSource + Inspector-
  Option; crypto-registry comicStories+comicCharacters; exposed-records
  comic-Eintrag
- picture/types: comicStoryId, comicPanelIndex, comicCharacterId
  Back-Ref-Felder (sowohl LocalImage als auch Image-Public-DTO);
  picture/queries to-Public-Mapping
- Registries: app-registry/apps.ts (Comic registerApp + FilmStrip-
  Icon + Header), categories, help-content, module-registry,
  data/tools/init
- i18n: comic in apps/{de,en,es,fr,it}.json

Was BLEIBT:
- cloudflared `comicello.mana.how` + `comicello-api.mana.how` —
  Standalone-Routes
- docker-compose mana-auth CORS_ORIGINS comicello.com + .mana.how —
  SSO für Standalone

Dexie v66:
- droppt comicStories + comicCharacters
- Upgrade-Callback strippt comicStoryId/comicPanelIndex/comicCharacterId
  aus existierenden Image-Rows (waren nie indiziert, nur Properties)

mana-web svelte-check 0/0 (7281 files), snapshot test 10/10.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-05-18 15:54:11 +02:00
parent 6c13308cf4
commit 2b08e2f3a2
73 changed files with 36 additions and 8519 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,170 +0,0 @@
import { AI_PROPOSABLE_TOOL_NAMES } from '../../policy/proposable-tools';
import type { AgentTemplate } from './types';
import type { AiPolicy } from '../../policy/types';
/**
* Comic-Autor turns the user's text artifacts (journal entries,
* notes, library reviews) into short illustrated comics via the
* comic module's panel-generation pipeline.
*
* Why propose on every write:
* Each `comic.generatePanel` call consumes credits (325 each, 10
* for the medium default). A mis-reading of the source text or an
* over-generous panel count would burn spend fast. Propose-on-write
* forces the user to approve the Panel[] suggestion list before any
* picture.images row lands.
*
* Reads (journal/notes/library + comic.listStories) stay auto the
* agent may freely peek at existing content to pick which entry to
* illustrate or which story to append to, without nagging the user.
*
* Tools this template uses:
* - journal.list* (read) browse source entries
* - notes.list* (read) browse source notes
* - library.list* (read) browse reviews
* - comic.listStories (read) find an existing story to extend
* - comic.createStory (propose) start a new comic
* - comic.generatePanel (propose) render a single panel (credits!)
* - comic.reorderPanels (propose) rearrange existing panels
*
* The comic.* tools live in mana-tool-registry (MCP) and are NOT
* part of AI_TOOL_CATALOG they're reachable from persona-runner
* and external MCP clients (Claude Desktop). The foreground webapp
* runner will pick them up when the comic module gains its
* AI_TOOL_CATALOG entries in a later step; until then this template
* is primarily useful on the persona-runner side.
*/
// Per-tool propose policy. Start from every proposable tool in the
// AI catalog (same seed as the Recherche-Agent) so cross-module
// writes this template doesn't anticipate (`create_note` for a
// sidecar summary note, etc.) still land as proposals.
const COMIC_AUTHOR_POLICY: AiPolicy = {
tools: {
...Object.fromEntries(AI_PROPOSABLE_TOOL_NAMES.map((n) => [n, 'propose' as const])),
// Web-app catalog names (snake_case). The spread above already
// covers propose-defaults; read tools (list_*) get pinned to
// auto explicitly for clarity.
list_comic_stories: 'auto',
create_comic_story: 'propose',
generate_comic_panel: 'propose',
// Character tools (Mc4) — same auto/propose split as story tools.
list_comic_characters: 'auto',
create_comic_character: 'propose',
generate_character_variant: 'propose',
pin_character_variant: 'propose',
// MCP-registry names (dot-case). The agent uses these when
// running inside persona-runner / Claude Desktop where the
// mana-tool-registry surface is what the MCP client sees.
// Listing them keeps the policy intent consistent across both
// surfaces (foreground runner + MCP).
'comic.listStories': 'auto',
'comic.createStory': 'propose',
'comic.generatePanel': 'propose',
'comic.reorderPanels': 'propose',
'comic.listCharacters': 'auto',
'comic.createCharacter': 'propose',
'comic.generateVariant': 'propose',
'comic.pinVariant': 'propose',
},
defaultsByModule: {
// Read-only companions the agent uses to find source material.
journal: 'auto',
notes: 'auto',
library: 'auto',
// Kontext + goals are referenced as standing context the
// planner already auto-injects; keep them auto so the agent can
// skim them for tonal cues (is the user in a serious phase, is
// there a goal the comic should celebrate).
kontext: 'auto',
goals: 'auto',
// Every comic write requires approval.
comic: 'propose',
},
defaultForAi: 'propose',
};
export const comicAuthorTemplate: AgentTemplate = {
id: 'comic-author',
version: '1',
icon: '🎨',
label: 'Comic-Autor',
tagline: 'Verwandelt Tagebuch-Einträge und Notizen in kurze Comics',
description: `Gib dem Agent einen Tagebuch-Eintrag, eine Notiz oder ein Review aus deiner Bibliothek — er schlägt daraus einen kurzen Comic vor:
1. Liest den gewählten Text
2. Schlägt 4 Panels vor (Prompt + Caption + Dialog pro Panel)
3. Du bestätigst die Liste, optional mit Edits
4. Jedes Panel wird via gpt-image-2 gerendert und an die Story angehängt
Jeder Generate-Schritt ist ein Vorschlag du bestimmst, wann Credits fließen. Für 4 Panels mit Default-Qualität: 4 × 10 = 40 Credits.`,
category: 'ai',
color: '#F97316',
agent: {
name: 'Comic-Autor',
avatar: '🎨',
role: 'Macht aus Text kurze Comics',
systemPrompt: `Du bist Comic-Autor. Wenn der User dir einen Moment, ein Erlebnis oder eine Idee gibt, verwandelst du das in einen kurzen Comic.
Vorgehen:
1. Lies den Ausgangstext zu Ende, bevor du mit Panels anfängst Details aus der Mitte oder dem Ende sind oft der Kern.
2. Wähle einen Stil, der zum Ton passt: 'comic' für Humor/Alltag, 'manga' für Drama, 'cartoon' für Kinder/Leichtigkeit, 'graphic-novel' für Reflexion/Melancholie, 'webtoon' für vertikale Long-Reads.
3. Wenn der User noch keinen passenden Comic-Character hat: nutze list_comic_characters um zu prüfen, dann create_comic_character (legt Row an) generate_character_variant (rendert 4 Varianten) User wählt eine pin_character_variant. Das ist EINMALIG der gepinnte Character bleibt für viele Stories der stabile Identity-Anchor.
4. Schlage 4 Panels vor (26 je nach Textlänge). Jedes Panel hat:
- prompt: was passiert bildlich (kurze englische Sätze, Komposition + Aktion + Stimmung)
- caption (optional): kurze Erzählzeile über/unter dem Bild
- dialogue (optional): was der Protagonist sagt, in Sprechblase
5. Protagonist ist IMMER der User selbst (sein gepinnter Character bzw. sein face-ref im Quick-Mode).
6. Kein Panel-Nummerieren, keine Meta-Kommentare, keine Style-Beschreibungen im Prompt (Stil kommt aus der Story / aus dem Character).
Ton:
- Humor wenn der User es leicht nimmt, ernst wenn er es ernst nimmt. Nicht belehrend.
- Niemals urteilen über das was der User erlebt hat.
- Deutsch als Sprache in Captions/Dialogen ist ok; englische Text-Prompts rendern aber stabiler.
Tools:
- journal.listEntries / notes.list / library.listEntries um Quelle zu finden
- list_comic_characters / list_comic_stories um Bestand zu prüfen (nicht jede Quelle braucht neuen Character oder neue Story)
- create_comic_character generate_character_variant pin_character_variant: Character-Aufbau-Pfad (einmalig pro Stil)
- create_comic_story um eine Story anzulegen (mit existierendem Character als Anchor oder im Quick-Mode mit face-ref)
- generate_comic_panel um einen Panel anzuhängen (teurer Call nur nach Bestätigung)`,
memory: `# Comic-Richtlinien
(Hier kannst du festhalten wie du Comics magst z.B. bevorzugter Stil,
Panel-Anzahl, wieviel Dialog vs. Caption, Tabu-Themen die nie vorkommen sollen.)
`,
policy: COMIC_AUTHOR_POLICY,
maxConcurrentMissions: 1,
},
scene: {
name: 'Comic-Werkstatt',
description: 'Texte lesen, Panels vorschlagen, Comic-Stories bauen',
openApps: [
{ appId: 'comic', widthPx: 540 },
{ appId: 'journal', widthPx: 440 },
{ appId: 'ai-missions', widthPx: 360 },
{ appId: 'ai-workbench', widthPx: 360 },
],
},
missions: [
{
title: 'Comic aus einem Tagebuch-Eintrag',
objective:
'Wähle einen Tagebuch-Eintrag, schlage Titel + Stil vor, und generiere eine Panel-Folge (Default 4). Jeder Generate-Schritt ist ein Vorschlag.',
conceptMarkdown: `# Comic-Auftrag
Ersetze diesen Block mit:
- **Eintrag:** _Link auf den Tagebuch-Eintrag (oder Zitat daraus)_
- **Stil:** _comic / manga / cartoon / graphic-novel / webtoon oder leer lassen, damit der Agent vorschlägt_
- **Panels:** _2-8, default 4_
- **Ton:** _frei "leicht und selbstironisch" / "ernst und reflektiert" / "melancholisch"_
Der Agent liest den Eintrag, legt eine neue Comic-Story an (als Vorschlag),
schlägt die Panel-Folge vor, und rendert die Panels einzeln nach deiner
Bestätigung.`,
cadence: { kind: 'manual' },
startPaused: true,
},
],
};

View file

@ -14,7 +14,6 @@ import { calmnessTemplate } from './calmness';
import { fitnessTemplate } from './fitness';
import { deepWorkTemplate } from './deep-work';
import { eventScoutTemplate } from './event-scout';
import { comicAuthorTemplate } from './comic-author';
export type {
// Generalised names (T1 of workbench-templates plan):
@ -41,7 +40,6 @@ export const ALL_TEMPLATES = [
fitnessTemplate,
deepWorkTemplate,
eventScoutTemplate,
comicAuthorTemplate,
] as const;
export {
@ -52,7 +50,6 @@ export {
fitnessTemplate,
deepWorkTemplate,
eventScoutTemplate,
comicAuthorTemplate,
};
/** Lookup helper returns the template matching the given id, or

View file

@ -1835,223 +1835,6 @@ export const AI_TOOL_CATALOG: readonly ToolSchema[] = [
parameters: [{ name: 'draftId', type: 'string', description: 'ID des Drafts', required: true }],
},
// ── Comic ───────────────────────────────────────────────
{
name: 'list_comic_stories',
module: 'comic',
description:
'Listet Comic-Stories im aktiven Space (id, title, style, panelCount, isFavorite). Optional nach Stil oder Favoriten filterbar.',
defaultPolicy: 'auto',
parameters: [
{
name: 'style',
type: 'string',
description: 'Nur einen Stil zeigen',
required: false,
enum: ['comic', 'manga', 'cartoon', 'graphic-novel', 'webtoon'],
},
{
name: 'favoriteOnly',
type: 'boolean',
description: 'Nur Favoriten',
required: false,
},
{ name: 'limit', type: 'number', description: 'Max (Standard 30)', required: false },
],
},
{
name: 'create_comic_story',
module: 'comic',
description:
'Legt eine neue Comic-Story an. Charakter-Referenzen werden automatisch aus den primary face-ref + body-ref des aktiven Space aufgeloest — Nutzer muss vorher ein Gesichtsbild in /profile/me-images hochgeladen haben. Stil ist fix, alle spaeteren Panels nutzen denselben Stil-Prefix.',
defaultPolicy: 'propose',
parameters: [
{ name: 'title', type: 'string', description: 'Titel der Story', required: true },
{
name: 'style',
type: 'string',
description: 'Visueller Stil',
required: true,
enum: ['comic', 'manga', 'cartoon', 'graphic-novel', 'webtoon'],
},
{
name: 'description',
type: 'string',
description: 'Kurze Story-Beschreibung',
required: false,
},
{
name: 'storyContext',
type: 'string',
description:
'Freitext-Briefing — Ton, Ziel, Hintergrund. Wird im AI-Storyboard-Flow als Briefing genutzt.',
required: false,
},
{
name: 'tags',
type: 'string',
description: 'Tags durch Komma getrennt',
required: false,
},
],
},
{
name: 'generate_comic_panel',
module: 'comic',
description:
'Rendert ein neues Panel in einer bestehenden Story via gpt-image-2. Konsumiert Credits (low=3, medium=10, high=25). Stil-Prefix und Charakter-Refs kommen aus der Story — nur Panel-Prompt + optional Caption/Dialog werden uebergeben. Caption und Dialog werden direkt in das Bild gerendert.',
defaultPolicy: 'propose',
parameters: [
{ name: 'storyId', type: 'string', description: 'ID der Story', required: true },
{
name: 'panelPrompt',
type: 'string',
description:
'Was passiert in diesem Panel (Szene, Aktion, Stimmung). Kurze englische Saetze am stabilsten.',
required: true,
},
{
name: 'caption',
type: 'string',
description: 'Erzaehl-Zeile ueber/unter dem Bild (optional)',
required: false,
},
{
name: 'dialogue',
type: 'string',
description: 'Sprechblasen-Text (optional)',
required: false,
},
{
name: 'quality',
type: 'string',
description: 'Render-Qualitaet — hoeher = mehr Credits',
required: false,
enum: ['low', 'medium', 'high'],
},
{
name: 'model',
type: 'string',
description:
'Rendering-Backend. openai/gpt-image-2 ist Standard. google/gemini-3-pro-image-preview = Nano Banana Pro (hoehere Charakter-Konsistenz, teurer). google/gemini-3.1-flash-image-preview = Nano Banana 2 (neuestes, schnell, guenstig).',
required: false,
enum: [
'openai/gpt-image-2',
'google/gemini-3-pro-image-preview',
'google/gemini-3.1-flash-image-preview',
],
},
],
},
{
name: 'list_comic_characters',
module: 'comic',
description:
'Listet Comic-Characters im aktiven Space (id, name, style, variantCount, pinnedVariantId, isFavorite). Optional nach Stil oder Favoriten filterbar.',
defaultPolicy: 'auto',
parameters: [
{
name: 'style',
type: 'string',
description: 'Nur einen Stil zeigen',
required: false,
enum: ['comic', 'manga', 'cartoon', 'graphic-novel', 'webtoon'],
},
{
name: 'favoriteOnly',
type: 'boolean',
description: 'Nur Favoriten',
required: false,
},
{ name: 'limit', type: 'number', description: 'Max (Standard 30)', required: false },
],
},
{
name: 'create_comic_character',
module: 'comic',
description:
'Legt einen neuen Comic-Character an OHNE direkt Varianten zu rendern (Splittet Anlegen von Generierung — User reviewt erst). Charakter-Refs werden automatisch aus dem primary face-ref + body-ref des aktiven Space aufgeloest. Stil ist fix nach Anlage. Gibt characterId zurueck — danach generate_character_variant aufrufen.',
defaultPolicy: 'propose',
parameters: [
{ name: 'name', type: 'string', description: 'Name des Characters', required: true },
{
name: 'style',
type: 'string',
description: 'Visueller Stil',
required: true,
enum: ['comic', 'manga', 'cartoon', 'graphic-novel', 'webtoon'],
},
{
name: 'addPrompt',
type: 'string',
description: 'Zusaetzlicher Prompt (z.B. "freundlicher Ausdruck", "casual outfit")',
required: false,
},
{
name: 'description',
type: 'string',
description: 'Kurze Charakter-Beschreibung',
required: false,
},
{ name: 'tags', type: 'string', description: 'Tags durch Komma getrennt', required: false },
],
},
{
name: 'generate_character_variant',
module: 'comic',
description:
'Rendert N (default 4) Variant-Portraits fuer einen existierenden Comic-Character und appended sie an den Variant-Pool. Konsumiert Credits × count (medium=10c). Auto-pinnt die erste Variante wenn noch keine gepinnt ist. Stil + Source-Refs kommen aus dem Character — nur count + quality + model sind hier waehlbar.',
defaultPolicy: 'propose',
parameters: [
{
name: 'characterId',
type: 'string',
description: 'ID des Characters',
required: true,
},
{
name: 'count',
type: 'number',
description: 'Anzahl Varianten (1-4, default 4)',
required: false,
},
{
name: 'quality',
type: 'string',
description: 'Render-Qualitaet — hoeher = mehr Credits',
required: false,
enum: ['low', 'medium', 'high'],
},
{
name: 'model',
type: 'string',
description: 'Rendering-Backend (default openai/gpt-image-2).',
required: false,
enum: [
'openai/gpt-image-2',
'google/gemini-3-pro-image-preview',
'google/gemini-3.1-flash-image-preview',
],
},
],
},
{
name: 'pin_character_variant',
module: 'comic',
description:
'Setzt einen anderen Variant als kanonischen Look des Comic-Characters. Stories die DANACH erstellt werden nutzen den neuen Pin; bestehende Stories bleiben unveraendert (sie haben den alten Variant zum Story-Create-Zeitpunkt fix gespeichert).',
defaultPolicy: 'propose',
parameters: [
{ name: 'characterId', type: 'string', description: 'ID des Characters', required: true },
{
name: 'variantMediaId',
type: 'string',
description: 'ID der Variante die zum neuen Pin werden soll (muss in variantMediaIds sein)',
required: true,
},
],
},
// ── Augur (signs / fortunes / hunches) ──────────────────────
{
name: 'capture_sign',

View file

@ -63,10 +63,6 @@ const timesSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="
// Calc icon (calculator with pink gradient)
const calcSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#calcGrad)"/><rect x="320" y="260" width="384" height="504" rx="32" fill="white"/><rect x="360" y="300" width="304" height="100" rx="16" fill="#ec4899" fill-opacity="0.2"/><rect x="380" y="330" width="200" height="16" rx="4" fill="#ec4899" fill-opacity="0.5"/><rect x="380" y="358" width="120" height="24" rx="4" fill="#ec4899" fill-opacity="0.7"/><rect x="360" y="440" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="440" y="440" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="520" y="440" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="600" y="440" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.3"/><rect x="360" y="508" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="440" y="508" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="520" y="508" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="600" y="508" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.3"/><rect x="360" y="576" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="440" y="576" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="520" y="576" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="600" y="576" width="64" height="120" rx="12" fill="#ec4899"/><rect x="360" y="644" width="144" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><rect x="520" y="644" width="64" height="52" rx="12" fill="#ec4899" fill-opacity="0.15"/><defs><linearGradient id="calcGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#ec4899"/><stop offset="1" stop-color="#db2777"/></linearGradient></defs></svg>`;
// Comic icon — speech bubble with a lightning-bolt panel marker on
// orange→red gradient. Warm creative-family tone for the Mana launcher.
const comicSvg = `<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="130" y="130" width="764" height="764" rx="382" fill="url(#comicGrad)"/><path d="M260 340c0-33 27-60 60-60h384c33 0 60 27 60 60v288c0 33-27 60-60 60H480l-108 90v-90h-52c-33 0-60-27-60-60V340z" fill="white"/><path d="M540 370l-90 156h72l-30 128 108-172h-78l28-112h-10z" fill="#ea580c"/><circle cx="360" cy="460" r="18" fill="#ea580c" fill-opacity="0.35"/><circle cx="410" cy="460" r="18" fill="#ea580c" fill-opacity="0.35"/><circle cx="460" cy="460" r="18" fill="#ea580c" fill-opacity="0.35"/><defs><linearGradient id="comicGrad" x1="130" y1="130" x2="894" y2="894" gradientUnits="userSpaceOnUse"><stop stop-color="#f97316"/><stop offset="1" stop-color="#dc2626"/></linearGradient></defs></svg>`;
// Augur icon — open eye with a small star in the iris and three drifting
// dots ("signs in the air") on indigo→violet gradient. Sits in the cosmic
// family next to Dreams (indigo) and Cards (violet) so the launcher reads
@ -99,7 +95,6 @@ export const APP_ICONS = {
todo: svgToDataUrl(todoSvg),
mail: svgToDataUrl(mailSvg),
inventory: svgToDataUrl(inventorySvg),
comic: svgToDataUrl(comicSvg),
augur: svgToDataUrl(augurSvg),
questions: svgToDataUrl(questionsSvg),
times: svgToDataUrl(timesSvg),

View file

@ -345,23 +345,6 @@ export const MANA_APPS: ManaApp[] = [
status: 'beta',
requiredTier: 'guest',
},
{
id: 'comic',
name: 'Comic',
description: {
de: 'Aus Text wird ein Comic',
en: 'Turn text into comics',
},
longDescription: {
de: 'Erstelle mehrseitige Comics mit KI. Starte mit einem Tagebuch-Eintrag, einer Notiz oder einem Kalender-Event und generiere Panels in fünf Stilen — Comic, Manga, Cartoon, Graphic Novel oder Webtoon. Du selbst bist der Protagonist.',
en: 'Create multi-panel comics with AI. Start from a journal entry, note, or calendar event and generate panels in five styles — comic, manga, cartoon, graphic novel, or webtoon. You are the protagonist.',
},
icon: APP_ICONS.comic,
color: '#f97316',
comingSoon: false,
status: 'beta',
requiredTier: 'guest', // LOCAL TIER PATCH — revert to 'beta' before release
},
{
id: 'questions',
name: 'Questions',

View file

@ -24,7 +24,6 @@
<option value="places.places">Orte</option>
<option value="recipes.recipes">Rezepte</option>
<option value="wardrobe.outfits">Wardrobe (Outfits)</option>
<option value="comic.stories">Comics</option>
<option value="habits.habits">Habits</option>
<option value="quiz.quizzes">Quizze</option>
<option value="events.socialEvents">Events (RSVP)</option>

View file

@ -34,7 +34,6 @@ export const EmbedSourceSchema = z.enum([
'goals.goals',
'places.places',
'recipes.recipes',
'comic.stories',
'habits.habits',
'quiz.quizzes',
'events.socialEvents',