Add CLI delete with must-be-empty semantics#22
Merged
Conversation
A CLI can now be deleted from its view via a "Delete CLI" action. The rule is must-be-empty: if the CLI still has visible (non-trashed) snips the delete is refused with an explanatory notice. Once empty it deletes after confirmation, cleaning up the CLI's icon asset and removing any leftover trashed snips (which would otherwise be orphaned). Adds IShellInteractions.NotifyAsync (single-button notice) for the "can't delete" message, implemented as a ContentDialog in the App head. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addresses a codex review finding: deleting the icon asset before SaveAsync meant a failed save would leave the persisted store still referencing the CLI while its icon was already gone. Persist the removal first, then clean up the icon as a best-effort post-save side effect. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addresses a codex review finding: IconAssetStorage.ResolveAbsolutePath combined an untrusted IconRef from the store directly with the base directory. An absolute path (Path.Combine silently drops the base) or a `..` traversal could therefore escape icon storage — and since the path feeds DeleteIconAsync -> File.Delete, a malformed/hand-edited store could delete arbitrary user files. Resolution now canonicalises the path and returns null unless it stays under <data>/icons/, so both display and deletion are confined to app-managed assets. Adds IconAssetStorageTests covering traversal and absolute-path rejection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
What
Adds the ability to delete a CLI, settling the cascade question flagged in CLAUDE.md / TODO with must-be-empty semantics.
Behaviour
Notable bits
IShellInteractions.NotifyAsync(single-button notice) for the "can't delete" message; implemented as aContentDialogin the App head.IconAssetStoragepath resolution to stay within<data>/icons/: an untrusted/hand-edited store could previously carry an absolute or../IconRefthat, viaFile.Delete, deleted files outside the data directory. Resolution now canonicalises and rejects escaping paths (protects both display and deletion).Tests
ShellViewModelCommandsTests: blocked-when-active, requires-confirmation, removes-CLI-and-trashed-snips + falls-back-to-Home, deletes-icon, no-op-on-Home.IconAssetStorageTests: save/delete round-trip,..traversal rejected, absolute path rejected,ResolveAbsolutePathcontainment.Review
Independent
codex exec reviewacross three passes: two findings raised and fixed (icon-delete ordering; icon path traversal), final pass clean.Verification still owed (Windows)
WinUI head: confirm the "Delete CLI" button shows on the CLI view, the "can't delete — N snips" notice appears when snips exist, and confirmation deletes an empty CLI and returns to Home.
🤖 Generated with Claude Code