Repository navigation
Add optimole delete: delete images by key, folder or website - #3
Merged
Merged
Conversation
"optimole delete" takes exactly one of --keys FILE|- (asset keys, sent 100 per DELETE /api/assets and stopping at the first request that fails), --folder PATH or --folder-id N (the folder's tree, emptied in the background), and --site DOMAIN (a website's images, in any folder). Safety is a full-access key plus a typed confirmation: on a terminal the command says what it deletes and asks for the folder's path, the domain or "delete"; anything else, Ctrl-C or Ctrl-D deletes nothing. --yes skips the question, and without a terminal the command refuses to run without it. A folder path is looked up in the folder list first, so an unknown folder or a path two folders share is refused before anything goes. Key deletes are retried like listing (a deleted key can be named again); folder and website deletes only when the server cannot have received them, since a repeat would start a second background deletion. After a failed request the command says how many images were deleted, and which may have been. The fake server answers DELETE /api/assets with the dashboard's rules (scope, the three body shapes, 422 messages), and knows websites, their folders and the assets they offloaded. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…eted - --site is sent as typed: the server strips one "www." as the prompt does, where sending the stripped domain had it strip a second one ("www.www.example.com" would have emptied example.com). - The answer must end with Enter: "delete" then Ctrl-D, or a line too long to read whole, deletes nothing. A folder path longer than a terminal line (1024 bytes on macOS) is confirmed by its name instead. - A keys request repeated after a lost answer may have deleted, whatever the retries answered; a 202 whose body does not read, or a 5xx, may have started a background deletion; a request that never connected did not. - Known API keys are hidden, and control characters quoted, in every message, the prompt and the JSON (folder paths, file names, server messages). - A folder path is matched only against a whole folder list; a list cut short (page limit, a cursor missing or repeated) stops the command. - Opening the --keys file gives way to Ctrl-C (a FIFO waits for a writer). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Staging answers a key that is deleted already with 422 "invalid or unauthorized", and refuses its whole request. So a keys request repeated after a lost answer would make a deletion that worked look failed, and "running again with the same keys is safe" was wrong. - Keys requests are now retried like folder and website requests: only after a 429 or a connection that failed before sending. One rule (untouched) tells what proves nothing was deleted. - After a failure the command says how many keys to leave out to finish, and that keys a failed request deleted show up as invalid next time. - The fake refuses deleted keys like unknown ones. Co-Authored-By: Claude Opus 5.5 <[email protected]>
- --site sends the host in lower case, "www." kept: the server strips one, as the prompt does, and a long URL no longer passes its 255-character limit. A non-ASCII domain is refused (give its xn-- form): the server maps it with IDNA, which the standard library lacks, so "İ.com" would have shown "i.com" and deleted "xn--i-9bb.com". - A folder whose name holds a slash ("2026 / Drafts") reads as the nested 2026/Drafts: both now match, so the command asks for --folder-id. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…te nothing Co-Authored-By: Claude Opus 5.5 <[email protected]>
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.
The dashboard API can now delete images in bulk (optimole-service#1944), but the CLI had no way to delete anything. This PR adds
optimole delete: delete images by asset key, every image of a folder, or every image of a website.What changed
optimole delete --keys FILE|-— deletes the asset keys in a file or on stdin, one per line, 100 per request. The run stops at the first request that fails. It then says how many images are deleted, which may be deleted, and which keys to leave out to finish.--folder PATHand--folder-id N— empty a folder and all its subfolders in the background; the folders stay. The CLI looks the folder up first. It refuses an unknown folder, or a path that two folders share, before anything is deleted. A folder named2026 / Draftscounts as the same path as2026/Drafts.--site DOMAIN— empties one website of the account, in any folder, in the background.https://www.example.com/blogmeansexample.com, as on the server. An internationalized domain must be given in itsxn--form.Confirmation — on a terminal, the command says what it will delete. Then it asks you to type the folder path, the domain, or
delete, then Enter. Any other answer, Ctrl-C or Ctrl-D deletes nothing.--yesskips the question. Without a terminal and without--yes, the command exits 2 and sends nothing.Retries — a delete request repeats only when the server cannot have received it (a
429, or a connection that failed before sending). After a lost answer or a5xx, the command says the images may be deleted.Fake server and docs —
internal/testserveranswersDELETE /api/assetswith the dashboard's rules: scope, the three body shapes, the422messages, websites and their folders. The README andoptimole delete -hdescribe the command.Note
Safety, by owner decision: there are no approval codes. Only full-access API keys can delete; the dashboard answers folder-scoped keys with
403, and the CLI says a full-access key is needed. The other guard is the typed confirmation, or an explicit--yesin scripts.Note
A key that is deleted already counts as invalid when named again: the server refuses the whole request with
422. This is why a key request does not repeat after a lost answer. It is also why the hint after a failure says which keys to leave out.Note
--foldertakes a path and--folder-idtakes an ID, as inoptimole upload. One flag for both is ambiguous for a folder named2024. A path longer than one terminal line (1000 bytes) is confirmed by the folder's name instead.QA
Do these steps on staging, with a test account. Build the CLI from this branch first.
go build -o optimole ./cmd/optimole export OPTIMOLE_API_URL=https://staging-dashboard.optimole.com/apiSign in to
https://staging-dashboard.optimole.comwith a test account. On theDashboardpage, copy the API Key. Run./optimole loginand paste it.Expect:
Logged in.Upload test images: two files into the root, and a folder tree.
Expect:
keys.txtholds two keys, and./optimole folderslistsQA/Delete.Run
./optimole delete --keys - < keys.txt.Expect: exit code 2 and
add --yes to delete without asking. The two images stay in the library.Run
./optimole delete --keys keys.txtand typeDelete, then Enter.Expect:
the answer did not match; nothing was deleted.Run
./optimole delete --keys keys.txtagain and typedelete, then Enter.Expect:
Deleted 2 images.In the dashboard, the two images are gone from the media library.Run
./optimole delete --keys keys.txt --yesa third time.Expect: exit code 1, the
422names both keys as invalid, andNothing was deleted.Run
./optimole delete --folder qa/deleteand type the path that the prompt shows (QA/Delete).Expect:
Deleting N images in the background.Within a few minutes the images leave the library../optimole foldersstill listsQA/Deleteand its subfolders.Go to
Settings → API Keysand click Create a new key. This key is folder-scoped (it starts withoptml-s). RunOPTIMOLE_API_KEY=<that key> ./optimole delete --folder QA/Delete --yes.Expect: exit code 1 and
Deleting images needs a full-access API key.Run
./optimole delete --site https://www.<a website of the account>/ --yes, then./optimole delete --site no-such-site.example --yes.Expect: first
Deleting N images in the background.(orNothing to delete: the website … has no images.), thenThe account has no website with this domain.🤖 Generated with Claude Code