Docs/Desktop app

Desktop app

Copies screen

Every second full checkout under the roots you name, and the one verb that deletes them. The engine is the sealed CLI's copies group (cli/copies), run as tama request copies/list and tama request copies/remove, so the screen and the terminal cannot disagree about what a pass would do.

Every second full checkout under the roots you name, and the one verb that deletes them. The engine is the sealed CLI's copies group (cli/copies), run as tama request copies/list and tama request copies/remove, so the screen and the terminal cannot disagree about what a pass would do.

The inventory includes dependency checkouts under package-manager and build directories, submodule checkouts, and bare Git caches. All stored Git history is checked, including dangling commits and annotated tags. Roots contribute their canonical repositories together, so their order does not change ownership. Linked worktrees appear only once, under their primary repository.

#Scope, header, refusals

The roots are scope, not a destination: Add root… opens a directory chooser, because the walk refuses a relative path and a directory that does not exist, and both are avoidable before a request leaves. With no root the screen states the command's own refusal rather than sending anything: tama copies needs at least one --root; a machine-wide default would walk directories Tama does not own.

Title Copies; scope is the number of roots; freshness reads no root selected, not scanned, scanning now, scan refused, or the copy count with the apparent size the pass found. Actions, in the order the decision is made: Add root…, Scan, Preview removal, Remove copies.

#What a row says

One row per copy: its path, the checkout it duplicates (OF), its apparent size, its state, and what this pass would do with it. The state chip carries the same facts the refusals are made of — uncommitted changes, history not retained, no origin, only checkout here, owns worktrees — and a clean row reads Clean. The inspector adds the origin, size and command's refusal sentence. Git history retained by names the canonical checkout whose independent, referenced objects preserve that history. This proof removes the history and missing-origin refusals, but does not override dirty files or replace an explicit claim when the owner is unknown.

A failed Git observation shows Unreadable Git state, never Clean. The inspector's Git inspection error field shows the actual failed command and error. Normal removal refuses this row; the explicit force override may remove it without a history or working-tree proof. Repository identification and filesystem errors remain failures.

#Keeping and claiming

Keep marks a copy to leave alone and travels as --except: it is neither removed nor refused. Claim appears only on a row whose owner is absent — the one refusal an operator can answer — and travels as --only, narrowing the pass to exactly the claimed paths. The two cannot travel together, so claiming clears every kept mark, and the screen says so in both lists. Changing a mark, a root, or the override drops the preview: an apply must never run against a plan that no longer describes it.

A claimed pass reads canonical repository headers and any object storage needed for its retention proof, then walks only the claimed subtrees. Unrelated working trees are not traversed. The ordinary scan and an unclaimed removal still walk all roots; a successful claimed removal is not evidence that no other copies remain.

Remove past every refusal (--force) is off until it is turned on, because it is the difference between a safety refusal and deleted history. It does not override an unreadable directory in the required walk, an unknown selection or a deletion error.

#What the screen never removes

Linked worktrees are counted and named, not removed: git tracks those and the Worktrees surface owns them. Two checkouts of one repository that both sit directly under a root are reported as a twin pair and neither is removable, because which one to keep is the operator's call. A candidate git will not answer for is reported as skipped.

A directory the walk could not read at all is reported too, as a danger panel naming the count and a warning panel per directory carrying the operating system's own reason. That is the difference between "one checkout per repository here" and "none where this pass could look", and the screen states it beside the count for the same reason the CLI exits non-zero: a pass over a tree it could not list would otherwise answer that the machine holds no second checkouts, and that answer would be quoted as proof.

#The decision

Remove copies is enabled only after a preview with no refusal outstanding. It opens a confirmation that lists exactly the paths the preview reported, states how much apparent size comes back, and names the override and every mark in force. Refusals and unreadable directories are checked before any deletion starts. Each deletion checks the current Git state and retention proof again. Nested selections are removed before their parents, and shared checkouts before selected Git object stores. Cyclic dependencies refuse the pass before deletion. An operational error is not a rollback guarantee. A clean pass re-reads the tree afterwards and keeps the removed list on screen.

Control is required for this destination: a signed-out operator does not see it, rather than seeing a dead row.

Return to the desktop application or the copies command group.