Repository navigation
feat(web): restore a deleted artifact when it is opened - #1369
Merged
Merged
Conversation
danyaberezun
requested review from
Andrey Markin (Mark-Life),
Olga Lavrichenko (OLavrik),
artyomxx and
Rinat S (rsolmano)
as code owners
November 14, 2026 00:40
danyaberezun
force-pushed
the
artifacts-open-restores
branch
from
November 14, 2026 16:59
813b0c8 to
93d50be
Compare
Merged
3 of 5 tasks
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.
Problem
The Artifacts tool (#1358) keeps every file the agent deleted as a "Deleted, not by you" row, but that row could not be opened. Its name was disabled, so seeing what the agent removed took two steps: Restore, then open. #1358 listed "open a deleted artifact without restoring it" as deferred.
Approach
Opening a deleted artifact restores it. Opening a file means asking for its contents, so a single click (preview) or a double click (kept tab) on a deleted row's name now restores the file from its kept copy, then opens it. Enter on the focused name does the same, and
Mod+Enter(from #1370's keyboard trees) restores it into a kept tab.ENTRY_EXISTS): it is not opened in place of the artifact the user clicked.changedAtis when it saw the file gone, so a list refresh keeps it and a new deletion changes it; the contracts spec now states this. A double click, a click in the gap before the live snapshot, or a list refresh in between therefore never asks again; the host would refuse a row that is already live withARTIFACT_UNKNOWN. A row the agent deletes again right after its restore gets a fresh one instead of getting stuck. A click,Mod+Enter, the Restore button and the menu's Restore all share it, keyed per workspace and path.reviewSendfollows). Opening another file while a slow restore runs is therefore never undone by the restored preview.artifacts.restoreandopenFileInTab. A host method "restore and open" was rejected: no difference for the user, and it would need a protocol bump.The Restore button and menu item stay. A deleted row still looks deleted until it is opened. Mention in chat and Reveal in Files remain hidden for deleted rows (deferred).
Changes
apps/web/src/panels/artifactActions.ts:restoreArtifactnow reports success;openArtifact(workspaceId, artifact, intent), which restores a deleted artifact first;restoreDeletedArtifact(workspaceId, artifact), which holds the one-restore-per-deletion rule per workspace and path without React.ArtifactsPanel:aria-disabled) and opens throughopenArtifact;Mod+Enter, and the Artifacts section's kept-open goes throughopenArtifact;EntryMenutakesonRestore(present only for a deleted row) instead of adeletedflag plus its own restore call.apps/web/src/panels/SPEC.md,packages/contracts/SPEC.md(a deleted row'schangedAt) andREADME.mddescribe the new behaviour.Screenshots
Same scenario and viewport:
report.mdwas deleted outside ThinkRail, and its struck-through name is clicked.Before: nothing opens and the row stays deleted.
After: the file is restored and opens in a tab, and the row is a normal one again.
Related issues
Follow-up to #1358.
Checklist
bun run lint,bun run typecheck(26/26),bun run test(25/25 packages), pluscheck:deps,check:boundaries,check:seams,check:spec-surface,check:i18n,check:compiler@thinkrail/server's backpressure test inhost/snapshotConflation.test.tstimed out once while the machine was loaded. It fails the same way onmainwhen run alone with-t, and this PR touches no server code. The whole server package then passed (2839).bun run e2e, orbun run e2e:fullwhen touching agent behavior):bun run e2e→ every Chromium test passes, including the newe2e/artifacts.spec.tstest "opening a deleted artifact restores it, once on a double click or Mod+Enter, and a failed restore opens nothing". Rerun after rebasing onto feat(web): run the workbench and the sidebar trees from the keyboard #1370. 25 WebKit tests could not start on the author's Linux machine ("Host system is missing dependencies"), so WebKit is unverified locally.apps/web/src/panels/artifactActions.test.ts(5) covers the cases e2e can't reach: a taken path opens nothing, a click made during the restore keeps its place, plus each one-restore-per-deletion rule (reuse in flight or done across list refreshes, a fresh restore for a newer deletion, retry after a failure). Each test fails with its rule removed; the e2e test fails without the reuse or withMod+Enterleft disabled on deleted rows.SPEC.md/ top-level specs updated to reflect any boundary, contract, or behavior change