Quality-of-life: catalog sort/search, skill duplicate & clone, state persistence, editor upgrades - #2
Merged
Conversation
…editor upgrades Quality-of-life roadmap across four areas: Sorting + content search - CatalogSortOrder (name/date-modified/platform/type) with stable name tiebreak; sort menu + "Search Inside Skills" toggle in the list column header. - SkillItem.searchableBody indexed at scan time (length-capped, lowercased, no extra disk I/O); CatalogFilter gains searchBody matching. State persistence - Last selection/section/platform/sort persist via AppSettings and restore on launch. - CatalogSelection.resolve shared by refresh/reloadCatalog. - Window frame autosave via SkillzWindowChromeCleaner. Duplicate / clone-to-platform - SkillFileService.duplicateSkill / copySkill copy the whole folder (multi-file skills) with -copy collision-free naming and rewrite primary SKILL.md name frontmatter. - Context menu: Duplicate Skill, Copy to Platform. Editor niceties + toasts - NSTextView-backed MarkdownTextView (native Find bar, undo, line-wrap) replacing the plain TextEditor; updateNSView diff guards the SwiftUI<->AppKit feedback loop. - Editor footer: word/char count (EditorMetrics) + Open in Editor. - ToastCenter + SkillzToast for auto-dismissing success/info feedback; errors keep the explicit-dismiss banner. Adds 12 unit tests (sort, body search, selection resolve, duplicate/copy, editor metrics, toast center). Docs (CLAUDE.md/AGENTS.md) updated.
…atch editor inset - SkillzWindowChromeCleaner: set frameAutosaveName only once (cleanWindow runs on every updateNSView; re-applying could snap the window to the saved frame). - MarkdownTextView: re-apply line-wrap only when the mode changes instead of on every keystroke, avoiding redundant text-container relayout; track applied state in coordinator. - MarkdownTextView: use SkillzSpacing.lg/.md for textContainerInset so the NSTextView editor keeps the prior 16pt padding feel instead of a tighter inset.
…path in sort test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A comprehensive quality-of-life pass across four areas, built to match existing patterns (
@MainActorstores,@AppStoragesettings,CatalogFilteras the single filter source, theCatalogSection/SkillzAppearanceenum idioms). Two new types only:CatalogSortOrder,ToastCenter.Sorting + search-in-content
CatalogSortOrder(name / date-modified / platform / type) with a stable name tiebreak. Sort menu + "Search Inside Skills" toggle live in the list column header; the choice persists.SkillItem.searchableBodyis indexed at scan time (length-capped to 8KB, lowercased) — no extra disk I/O — andCatalogFiltermatches it only when body search is enabled.Duplicate / clone-to-platform
SkillFileService.duplicateSkill/copySkillcopy the whole folder (multi-file skills) with-copycollision-free naming and rewrite the primarySKILL.mdnamefrontmatter.State persistence
AppSettingsand restore on launch through a sharedCatalogSelection.resolvehelper.SkillzWindowChromeCleaner(set once). Split-column-width persistence was intentionally left out — no reliable macOS 14 API.Editor niceties + toasts
MarkdownTextView(NSTextView) replaces the plainTextEditor: native Find bar, undo, line-wrap toggle. TheupdateNSViewtext diff guards the SwiftUI⇄AppKit feedback loop; wrap is re-applied only when the mode changes.EditorMetrics) + "Open in Editor".ToastCenter+SkillzToastfor auto-dismissing success/info feedback; errors keep the explicit-dismiss banner.Tests
Adds 12
@Testfunctions (sort orders, body search, selection resolve, duplicate/copy-to-platform, editor metrics, toast center). Suite total: 60. Docs (CLAUDE.md/AGENTS.md) updated in sync.Validation
skillzTestsonmacos-26.Known risks to watch in review/CI:
NSTextViewbridge is the most likely source of a compile/runtime surprise (Swift 5 concurrency:MainActor.assumeIsolatedin the delegate; theCatalogSelectionfallback closure).setFrameAutosaveNamevs.defaultSize) — degrades gracefully if it doesn't restore.NavigationSplitView/HSplitView.https://claude.ai/code/session_01GoyGVatSJsyfhtpiMi8ZNy
Generated by Claude Code