feat(w4): ship v1.5.0 timeline, character arc, and compliance

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 17:40:42 +08:00
parent c5c0b7329b
commit cb6b4c3731
51 changed files with 1528 additions and 42 deletions
@@ -234,6 +234,39 @@ export function SettingsPage(): React.JSX.Element {
{t('settings.goalNotifications')}
</label>
</div>
<div className="setting-item">
<label style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<input
type="checkbox"
data-testid="settings-compliance-check"
checked={settings.enableComplianceCheck === true}
onChange={(e) =>
void settings.update({ enableComplianceCheck: e.target.checked })
}
/>
{t('settings.complianceCheck')}
</label>
</div>
{settings.enableComplianceCheck && (
<div className="setting-item" style={{ flexDirection: 'column', alignItems: 'flex-start' }}>
<span>{t('settings.complianceWords')}</span>
<textarea
className="form-control form-control--wide"
data-testid="settings-compliance-words"
rows={3}
value={(settings.complianceWords ?? []).join('\n')}
onChange={(e) =>
void settings.update({
complianceWords: e.target.value
.split('\n')
.map((s) => s.trim())
.filter(Boolean)
})
}
placeholder={t('settings.complianceWordsHint')}
/>
</div>
)}
<div className="setting-item">
<label style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<input
@@ -276,7 +309,7 @@ export function SettingsPage(): React.JSX.Element {
{section === 'shortcuts' && <ShortcutEditor />}
{section === 'about' && (
<p style={{ color: 'var(--text-secondary)', lineHeight: 1.8 }}>
{t('app.name')} v1.4.0
{t('app.name')} v1.5.0
<br />
{t('app.tagline')}
</p>