Code-review findings:
- donation-toast: restore path/secure/sameSite cookie attributes the
inlined useCookie dropped (security/scope regression).
- utils/color: restore @uiw fallback so percentage-notation rgb() still
converts (custom style-rule colors are arbitrary strings); add tests
pinning the one real difference vs the black fallback.
- knip: drop stale npm-check-updates ignoreDependencies entry.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
The 107-line useCookie hook had exactly one consumer (donation-toast) that
only read + set-with-expiry. Inline the two Cookies.* calls directly and
delete the hook + its 128-line test. Drop js-cookie and @types/js-cookie
from packages/ui/package.json (apps/web retains its own js-cookie dep).
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
Each of the 14 section-item dialog files (award→volunteer) had identical
~50-line Create/Update shells (DialogContent + header + form + footer).
Added section-item-dialog.tsx with a SectionItemDialog wrapper that takes
title, icon, onSubmit, onCancel, isSubmitting, submitLabel, singleColumn?.
cover-letter and summary-item use singleColumn=true for their one-column
layout. custom.tsx is untouched (it creates section definitions, not items).
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
Loosen useResumeExport param to ExportableResume { name, slug, data } so the
public resume page (where name may be '' for non-owner viewers) can reuse it.
getExportName() falls back to data.basics.name then slug, matching the
original inline logic.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
normalizeResumePreviewProps had exactly one production caller (preview.tsx).
Defaults now live in the ResumePreview destructuring; the normalizer and its
test cases are removed.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
defineDialogRenderer/defineDialogRendererRegistry were identity functions.
Each registry now exports a readonly AnyDialogRendererEntry[] directly;
renderer-registry.ts retains only the types. The unused 'domain' field and
its wrapping object are gone; renderers.tsx spreads the arrays directly.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
Three auth-settings components (password, two-factor, social-provider) each
duplicated an identical m.div hover/tap wrapper for both branches of
match(boolean). Extracted one ActionButton wrapper and replaced match with
a plain ternary; removed ts-pattern imports.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
Number(null) === 0 caused the old code to use a separate :initialized key as
a migration sentinel. A plain null check on localStorage.getItem() is
sufficient and removes the sentinel key entirely.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
Extract useTypographyForm helper (captures form creation + sync) and
TypographyForm type. Extract TypographyGroupFields component with
prefix "body" | "heading" to replace 2x4 duplicated form.Field blocks.
Font Weight label ("Font Weights" vs "Font Weight") is preserved per
prefix.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
useInitializeResumeStore, useMergeResumeMetadata, useSaveStatus,
useCanUndo, useCanRedo, useUndoResume, useRedoResume each had exactly
one caller. Inline useResumeStore selectors at call sites and remove
the wrappers. Skipped usePatchResume (4 callers).
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
Extract makeCustomSection factory to eliminate duplicate CustomSection
object literal. Replace hand-maintained SectionType array in
isStandardSectionId with membership check via `id in sections`.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
The uploads endpoint is public (Cache-Control: public, no auth headers),
so a plain img src suffices. Remove createPicturePreviewUrl, the useQuery
call, and the object-URL cleanup useEffect; simplify PicturePreviewControls
to use normalizedPictureUrl directly.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
Remove generic selector overload from useBuilderSidebar; callers
destructure the full return object instead of using a selector that
provides no meaningful benefit (state is rebuilt on every render).
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
agent/service.ts uses findLastIndex/Array.prototype.with (ES2023); web
type-checks api source and its ES2022 lib lacked them. lib only affects
type defs, not Vite runtime output.
Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
97 strings translated for Amharic (am-ET), 97 for Greek (el-GR),
97 for Khmer (km-KH), and 98 for Thai (th-TH). All placeholders
preserved verbatim ({0}, {label}, <0>, __APP_VERSION__, etc.).
Claude-Session: https://claude.ai/code/session_012jucCw5SQBpWMoZYwVEbeC
Fill in 96 empty msgstr entries per locale covering new UI strings
(AI assistant, version history, dashboard, account menu, connection
status, editor controls, and more).
Claude-Session: https://claude.ai/code/session_012jucCw5SQBpWMoZYwVEbeC
Fill in all empty msgstr entries (96 per file, 92 for ro-RO) covering
new UI strings: AI assistant, version history, undo/redo, dashboard,
connection status, export data, and related builder strings.
Claude-Session: https://claude.ai/code/session_012jucCw5SQBpWMoZYwVEbeC
Prevent the sponsor logo images from intercepting clicks so the
anchor reliably opens atlascloud.ai in a new tab instead of the SVG
asset.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>