mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-20 07:43:37 +02:00
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
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:
parent
6c13308cf4
commit
2b08e2f3a2
73 changed files with 36 additions and 8519 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -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 (3–25 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 (2–6 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,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ export const EmbedSourceSchema = z.enum([
|
|||
'goals.goals',
|
||||
'places.places',
|
||||
'recipes.recipes',
|
||||
'comic.stories',
|
||||
'habits.habits',
|
||||
'quiz.quizzes',
|
||||
'events.socialEvents',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue