Merge origin/main: reconcile briefing checklist and brief visuals

Both branches added a case-briefing checklist independently. Reconcile onto
the upstream {id,text} BriefChecklistItem model and keep the upstream brief /
luggage-tag visual refinements (boxed CHECKLIST section, assignment/heading
split), while retaining this branch's full-stack backing (checklist table,
board read/write/clone, importer/exporter) and the player-tickable interaction
(persisted locally per level). Keep the brief-goals list alongside the new
checklist. Align the server wire shape, importer, and exporter to {id,text}.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 23:06:20 +02:00
co-authored by Claude Opus 4.8
11 changed files with 225 additions and 74 deletions
+1 -1
View File
@@ -76,7 +76,7 @@ function serializeLevel(board: TemplateBoardExport, assetFilenames: Map<string,
subtitle: state.subtitle || undefined,
timelineRange: timeline?.range,
brief: state.brief.body || state.brief.concepts.length || state.brief.checklist?.length
? prune({ body: state.brief.body, concepts: state.brief.concepts.map(concept => ({ label: concept.label, context: concept.context, expectedPartyKind: concept.expectedPartyKind || 'person' })), checklist: state.brief.checklist })
? prune({ body: state.brief.body, concepts: state.brief.concepts.map(concept => ({ label: concept.label, context: concept.context, expectedPartyKind: concept.expectedPartyKind || 'person' })), checklist: state.brief.checklist?.map(item => item.text) })
: undefined,
documents: documents.map(document => prune({
key: documentKeyById.get(document.id)!, title: document.title, fileType: document.fileType, captureKind: document.captureKind,