# Changelog

## Score

- CAI 60 → 65 (+5.1)

## Lenses

- Code Health 95 → 94 (-1.3)
- Architecture 91 → 90 (-1.2)
- Maturity 48 → 59 (+11.5)
- Readiness 75 → 73 (-1.4)
- Security 60 → 60 (+0.0)

## Resolved (23)

- Dormant codebase
- Duplicated block (10 lines × 2) (Sources/Runestone/Documentation.docc/Tutorials/01-setting-up-a-textview-01-04.swift)
- Duplicated block (10 lines × 4) (Sources/Runestone/Documentation.docc/Tutorials/01-setting-up-a-textview-02-09.swift)
- Duplicated block (11 lines × 2) (Sources/Runestone/Documentation.docc/Tutorials/01-setting-up-a-textview-02-11.swift)
- Duplicated block (12 lines × 12) (Sources/Runestone/Documentation.docc/Tutorials/01-setting-up-a-textview-02-03.swift)
- Duplicated block (13 lines × 2) (Sources/Runestone/Documentation.docc/Tutorials/01-setting-up-a-textview-03-06.swift)
- Duplicated block (15 lines × 3) (Sources/Runestone/Documentation.docc/Tutorials/01-setting-up-a-textview-03-08.swift)
- Duplicated block (15 lines × 8) (Sources/Runestone/Documentation.docc/Tutorials/01-adding-a-theme-01-09.swift)
- Duplicated block (17 lines × 3) (Sources/Runestone/Documentation.docc/Tutorials/01-syntax-highlighting-the-text-01-03.swift)
- Duplicated block (27 lines × 2) (Sources/Runestone/Documentation.docc/Tutorials/01-adding-a-theme-02-06.swift)
- Duplicated block (8 lines × 31) (Sources/Runestone/Documentation.docc/Tutorials/01-adding-a-theme-01-09.swift)
- Duplicated block (9 lines × 2) (Sources/Runestone/Documentation.docc/Tutorials/01-adding-a-theme-01-09.swift)
- Duplicated block (9–10 lines × 3) (Example/Themes/Sources/RunestoneThemeCommon/HighlightName.swift)
- Inconsistent naming for replacement operations. `replace` is used for single-range replacements (both `UITextRange` and `NSRange` variants), while `replaceText` is used for batch replacements. The verb 'replace' is overloaded with different semantics (single vs. batch) and the method name changes slightly (`replace` vs `replaceText`) to distinguish them, which is confusing. Additionally, having two `replace` overloads with different range types (`UITextRange` vs `NSRange`) can be ambiguous depending on context.
- Members sharing a duplicated core (31 members, 50+ identical tokens) (Sources/Runestone/Documentation.docc/Tutorials/01-adding-a-theme-01-09.swift)
- Members sharing a duplicated core (4 members, 50+ identical tokens) (Sources/Runestone/Documentation.docc/Tutorials/01-setting-up-a-textview-02-09.swift)
- Most significant orphaned file (Sources/Runestone/RedBlackTree/RedBlackTree.swift)
- Most significant orphaned file (Sources/Runestone/TextView/Core/LayoutManager.swift)
- Outdated: tree-sitter
- PR-triggered workflow without a permissions block
- …and 3 more

## New (63)

- Dependency hygiene PARTLY measured — SwiftPM pinning read, dependency currency NOT established
- FileTooLong: Core/LayoutManager.swift (Sources/Runestone/TextView/Core/LayoutManager.swift)
- FoldingText.trim (cognitive 18) (Sources/Runestone/TextView/SyntaxHighlighting/Internal/TreeSitter/TreeSitterFoldingSnapshot.swift)
- Hotspot: Example/Example/Main/MainViewController.swift (Example/Example/Main/MainViewController.swift)
- Hotspot: Sources/Runestone/TextView/Core/LayoutManager.swift (Sources/Runestone/TextView/Core/LayoutManager.swift)
- Hotspot: Sources/Runestone/TextView/Core/TextInputView.swift (Sources/Runestone/TextView/Core/TextInputView.swift)
- LayoutManager.layoutLinesInViewport (cyclomatic 19) (Sources/Runestone/TextView/Core/LayoutManager.swift)
- LineController.updateSyntaxHighlightingIfNecessary (cognitive 17) (Sources/Runestone/TextView/LineController/LineController.swift)
- LinePrefixReuse.count (cognitive 16) (Sources/Runestone/TextView/LineController/LinePrefixReuse.swift)
- LinePrefixReuse.signature (cognitive 16) (Sources/Runestone/TextView/LineController/LinePrefixReuse.swift)
- LinePrefixReuse.signature (cyclomatic 17) (Sources/Runestone/TextView/LineController/LinePrefixReuse.swift)
- LineTypesetter.makeNextLineFragment (cognitive 18) (Sources/Runestone/TextView/LineController/LineTypesetter.swift)
- No assertions: testChangingWrappingNearDocumentEndCanRevealDestinationAndScrollUp (Tests/RunestoneTests/ViewportNavigationTests.swift)
- No assertions: testDelegateMakingEditorReadOnlyDuringApprovalRejectsSuggestion (Tests/RunestoneTests/WritingToolsInteractionTests.swift)
- No assertions: testDelegateStoppingWritingToolsDuringApprovalRejectsSuggestion (Tests/RunestoneTests/WritingToolsInteractionTests.swift)
- No assertions: testLongASCIILinesUnwrapped (Tests/RunestoneTests/LargeFileCorrectnessTests.swift)
- No assertions: testLongASCIILinesWrapped (Tests/RunestoneTests/LargeFileCorrectnessTests.swift)
- No assertions: testLongLinesUnwrapped (Tests/RunestoneTests/LargeFileCorrectnessTests.swift)
- No assertions: testLongLinesUnwrapped (Tests/RunestoneTests/LargeFileTraversalTests.swift)
- No assertions: testLongLinesWrapped (Tests/RunestoneTests/LargeFileCorrectnessTests.swift)
- …and 43 more

## Changes since last survey

- 41 commits — 40 feature/other, 1 fixes

## By area

- Sources/Runestone — 36 commits
- (root) — 3 commits
- Example/Example — 1 commit
- Tests/RunestoneTests — 1 commit

## Notable commits

- fix: Fix missing selection change notifications for cut operations (#422)
- change: Add Brazilian Portuguese editor action labels (#450)
- change: Add Nordic and Korean editor action localizations (#451)
- change: Add Simplified Chinese localization for editor actions (#449)
- change: Add five editor action languages and polish existing translations (#452)
- change: Add large-file scrolling and editing checks (#469)
- change: Add native inline Writing Tools support (#453)
- change: Add opt-in code and Markdown folding in the gutter (#467)
- change: Add spell checking with tap corrections and optional dictionary actions (#454)
- change: Avoid character pairing while updating marked text (#445)
- change: Avoid creating multiple instances of `DefaultTheme`. (#380)
- change: Batch native find interaction highlight updates (#446)
- change: Expand folding tap targets across the gutter (#475)
- change: Expose Writing Tools panel presentation lifecycle (#457)
- change: Honor soft indentation when typing a tab (#440)
- change: Keep complete characters together when wrapping (#471)
- change: Keep decorative line numbers out of VoiceOver navigation (#468)
- change: Keep large-document navigation local and anchor upward scrolling (#461)
- change: Keep the gutter below scroll view overlays (#437)
- change: Make editing long wrapped lines faster (#472)
- …and 21 more
