v0.8.0 — Gated curation, English-default UI, refactor
Added — Gated Skill Curator (I1 completion, §8)
curation_auto (default False) was defined in config but never read — the curator always merged immediately once judge confidence passed the threshold, breaking the "propose first, human applies" philosophy already used for router calibration. Default now only proposes merges (curation_log.status='pending') and waits for a Terapkan (Apply) click on /skills; curation_auto=True still allows direct auto-merge.
memory/curator.py: new_propose()/apply_pending_merge(),_merge()refactored into shared_apply_merge();revert_last_merge()only looks atstatus='applied'rows.- New endpoint
POST /skills/apply-merge+ Apply button in the UI.
Added — UI locale (English default, switchable to Indonesian)
All static text across the 9 web pages (nav, buttons, titles, status messages — previously a mix of hardcoded Indonesian) now goes through infra/i18n.py (t()/translator(), ~180 keys). Default English; switch to Indonesian via a dropdown on /settings, stored server-side (ui_locale). Agent response language is untouched — the agent still always replies in whatever language the user writes in; this only affects UI chrome.
Changed — Web UI technical-debt cleanup (from a UI/UX audit)
- Sidebar DRY: markup previously duplicated across 9 templates now lives in
web/templates/_sidebar.html, included via apagecontext var — bonusaria-current="page"on the active nav item. - CSS split by concern: the 1082-line monolithic
style.cssis now organized underweb/static/css/*.css(base/layout/chat/pages/activity/autopilots/skills/conversations/toast);style.cssis a thin@importentry point. - JS extracted: ~700 lines of inline JS in
index.htmlmoved to a cacheableweb/static/chat.js, with server-rendered data passed viawindow.OPENCLAWN_DATA. - Accessibility/security polish: real SRI
integrityhashes (computed from the actual pinned CDN files) formarked/DOMPurify,prefers-reduced-motionsupport, improved--text-faintcontrast (#6f6690→#7d73a0),aria-live="polite"on SSE-updated regions.
Fixed — Column migration for existing installs
CREATE TABLE IF NOT EXISTS is a no-op on tables that already exist, so columns added after initial release (curation_log.status/merged_content, skills.merged_into/version) never reached older databases — causing a 500 on /skills (no such column: status). DatabaseManager now patches missing columns on existing tables at every startup (PRAGMA table_info + ALTER TABLE ADD COLUMN, idempotent, no data loss).
Fixed — Activity timeline label overlap
A regression from the earlier "evidence" framing: kind labels got longer ("Routing" → "Routing evidence" etc.) but the grid column width wasn't adjusted, so the longest labels overflowed into the title column. Column widened, label allowed to wrap.
Tests: 513 passing, ruff clean.