Operasi Mise M4 — manifest sync + 100% feature coverage + LandingRenderer parseConfigBadge extracted
Phase 4 of 5 in Operasi Mise (kitchen prep before continuing development). Goal: clean up structural debt the audit flagged — slice manifests drift, config title shortening, scaffolding dir counted in coverage stats, duplicated tiny helpers. (1) sync-slice-manifests.mjs: ran, wrote 4 manifests (ai-agents, ai-chat, ai-studio, icon-picker — config.ts added after manifest was last regenerated). Also taught the script to silently skip slices that have config.ts but no slice.json — those are catalog-only meta-slices (admin-panel, event-tracking, pages, rbac-roles) whose actual code lives in _shared/, not as standalone distributables. (2) Aligned 8 config.ts titles with their slice.json long-form (ai-agents/chat/studio, code-block, equation, notifications, notion-blocks, notion-shell). Pre-commit warnings now silent. (3) audit-feature-manifest.mjs: skip _-prefixed dirs (consistent with sync-slice-manifests convention) so _templates scaffolding doesn't count against coverage. Result: 98.0% → 100.0% (48/48). (4) Extracted parseConfigBadge to _shared/landing/parse-config.ts — 5 templates (kreator-studio, personal-brand, research, konsultan, wirausaha) had identical 8-line inline function. Now imported. Added generic parseConfigField<T>() helper for future config-key extraction. Net: -40 LOC across 5 templates. LandingRenderer base-class extraction (originally planned) revealed shallow shared surface — each template's switch-case maps to template-specific component imports (Hero, Stats, FeaturedPosts, etc), so no extraction beyond parseConfigBadge made sense.
Manifest sync
- scripts/validation/sync-slice-manifests.mjs — skip catalog-only slices (config.ts only, no slice.json)
- 4 manifest files updated: ai-agents, ai-chat, ai-studio, icon-picker — files[] regenerated from disk
Feature manifest coverage 100% (48/48)
- scripts/audit-feature-manifest.mjs — skip _-prefixed dirs (matches sync-slice-manifests convention)
- _templates scaffolding now correctly excluded from coverage stats
Slice title alignment (config.ts ↔ slice.json)
- ai-agents/ai-chat/ai-studio — long-form titles restored
- code-block/equation/notifications/notion-blocks/notion-shell — same
Shared helper extracted
- components/templates/_shared/landing/parse-config.ts — parseConfigBadge + generic parseConfigField<T> (NEW)
- 5 LandingRenderer.tsx files migrated: removed local parseConfigBadge, import from _shared