feat(templates): two more non-AI templates + split gallery into two sections

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>
This commit is contained in:
Till JS 2026-04-16 11:45:40 +02:00
parent 4f76d3926e
commit 9161c0b3ab
7 changed files with 390 additions and 34 deletions

View file

@ -0,0 +1,83 @@
import type { WorkbenchTemplate } from './types';
/**
* Deep Work work-category Workbench-Template.
*
* Ein Starter-Kit für konzentrierte Arbeitsphasen. Scene mit Todo /
* Calendar / Notes / Times + zwei Habits (Deep-Work-Zeit tracken, 1
* "wichtigste Aufgabe" pro Tag definieren) + ein Wochenziel für
* Fokus-Stunden.
*
* Kein AI-Agent. Das Template gibt die Struktur vor, der User bringt
* die Arbeit.
*/
export const deepWorkTemplate: WorkbenchTemplate = {
id: 'deep-work',
version: '1',
label: 'Deep Work',
icon: '💻',
tagline: 'Konzentrierter Arbeitsplatz mit Fokus-Tracking',
description: `Ein Starter-Kit für konzentrierte Arbeit. Legt dir eine Scene mit Todo, Kalender, Notes und Time-Tracking an und seed-et zwei Habits plus ein Wochenziel für Deep-Work-Stunden.
Was drin ist:
- **Scene**: Todo · Kalender · Notes · Times alles für fokussierte Sessions nebeneinander.
- **2 Habits**:
- 🎯 1 wichtigste Aufgabe pro Tag
- 4h Deep Work pro Tag
- **1 Wochenziel**: "20h Deep Work pro Woche" zählt abgeschlossene Time-Tracking-Sessions.
Kein Agent. Das Setup ist da; der Rest ist deine Disziplin.`,
category: 'work',
color: '#1F2937',
scene: {
name: 'Deep Work',
description: 'Fokus, Kalender, Notes, Zeit',
openApps: [
{ appId: 'todo', widthPx: 540 },
{ appId: 'calendar', widthPx: 540 },
{ appId: 'notes', widthPx: 440 },
{ appId: 'times', widthPx: 340 },
],
},
seeds: {
habits: [
{
stableId: 'template-deepwork:habit:top-task',
data: {
title: '1 wichtigste Aufgabe pro Tag',
icon: '🎯',
color: '#1F2937',
targetPerDay: 1,
defaultDuration: null,
},
},
{
stableId: 'template-deepwork:habit:deep-work-hours',
data: {
title: '4h Deep Work pro Tag',
icon: '⏱',
color: '#374151',
targetPerDay: 4,
defaultDuration: 60,
},
},
],
goals: [
{
stableId: 'template-deepwork:goal:weekly-focus',
data: {
title: '20h Deep Work pro Woche',
description: 'Summiert Time-Tracking-Sessions im Times-Modul.',
moduleId: 'times',
metric: {
source: 'event_count',
eventType: 'TimeSessionCompleted',
},
target: { value: 20, period: 'week', comparison: 'gte' },
},
},
],
},
};

View file

@ -0,0 +1,93 @@
import type { WorkbenchTemplate } from './types';
/**
* Fitness wellness-category Workbench-Template.
*
* Scene für Körper-Arbeit + drei Grund-Habits + ein Wochenziel. Keine
* AI. Der User trackt selbst; das Template nimmt ihm nur die initiale
* Einrichtung ab.
*
* Zielgruppe: jemand der "ich will regelmäßig trainieren" sagt und
* nicht erst 15 Minuten Setup-Zeit investieren will. 1-Klick-Setup.
*/
export const fitnessTemplate: WorkbenchTemplate = {
id: 'fitness',
version: '1',
label: 'Fitness',
icon: '🏋️',
tagline: 'Workout-Workspace mit Basis-Habits und Wochenziel',
description: `Ein Starter-Kit für regelmäßige Bewegung. Legt dir eine Scene mit Body, Habits, Stretch und Sleep an und seed-et drei Habits und ein Wochenziel — dann kannst du direkt loslegen.
Was drin ist:
- **Scene**: Body · Habits · Stretch · Sleep alles was du zum Tracken brauchst, nebeneinander.
- **3 Habits** mit sinnvollen Default-Icons:
- 🏃 Täglich 30min Bewegung
- 🏋 3× Woche Training
- 💧 2L Wasser täglich
- **1 Wochenziel**: "3 Workouts pro Woche" der Goal-Tracker zählt TaskCompleted-Events aus dem Body-Modul.
Kein Agent. Keine Automation. Du trainierst, die Workbench zählt.`,
category: 'wellness',
color: '#EF4444',
scene: {
name: 'Fitness',
description: 'Bewegung, Kraft, Schlaf',
openApps: [
{ appId: 'body', widthPx: 540 },
{ appId: 'habits', widthPx: 440 },
{ appId: 'stretch', widthPx: 340 },
{ appId: 'sleep', widthPx: 340 },
],
},
seeds: {
habits: [
{
stableId: 'template-fitness:habit:daily-movement',
data: {
title: 'Täglich 30min Bewegung',
icon: '🏃',
color: '#EF4444',
targetPerDay: 1,
defaultDuration: 30,
},
},
{
stableId: 'template-fitness:habit:weekly-training',
data: {
title: '3× Woche Training',
icon: '🏋️',
color: '#F97316',
targetPerDay: null,
defaultDuration: 60,
},
},
{
stableId: 'template-fitness:habit:hydration',
data: {
title: '2L Wasser täglich',
icon: '💧',
color: '#0EA5E9',
targetPerDay: 8,
defaultDuration: null,
},
},
],
goals: [
{
stableId: 'template-fitness:goal:weekly-workouts',
data: {
title: '3 Workouts pro Woche',
description: 'Zählt abgeschlossene Workouts im Body-Modul.',
moduleId: 'body',
metric: {
source: 'event_count',
eventType: 'TaskCompleted',
},
target: { value: 3, period: 'week', comparison: 'gte' },
},
},
],
},
};

View file

@ -11,6 +11,8 @@ import { researchTemplate } from './research';
import { contextTemplate } from './context';
import { todayTemplate } from './today';
import { calmnessTemplate } from './calmness';
import { fitnessTemplate } from './fitness';
import { deepWorkTemplate } from './deep-work';
export type {
// Generalised names (T1 of workbench-templates plan):
@ -34,9 +36,18 @@ export const ALL_TEMPLATES = [
contextTemplate,
todayTemplate,
calmnessTemplate,
fitnessTemplate,
deepWorkTemplate,
] as const;
export { researchTemplate, contextTemplate, todayTemplate, calmnessTemplate };
export {
researchTemplate,
contextTemplate,
todayTemplate,
calmnessTemplate,
fitnessTemplate,
deepWorkTemplate,
};
/** Lookup helper returns the template matching the given id, or
* undefined. Useful for deep-links `/agents/templates?pick=research`. */