@git.zone/tsdisk
tsdisk is a disk usage diagnostic CLI for finding large files, caches, logs, Docker storage, and deleted-but-open files on Linux hosts.
Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.
Install
pnpm add --global @git.zone/tsdisk
For one-off usage:
pnpm dlx @git.zone/tsdisk
Usage
tsdisk
The tool prints a structured report covering filesystem usage, large files and directories on mounted workspaces such as /mnt/data, known user and system cache paths, project-local tool caches, systemd journal usage, deleted open files, and Docker context storage. Both the default human report and scan print live progress every five seconds, including the current stage, discovered cache count, measured workspace bytes, potential cleanup bytes, and the largest paths found so far.
Potential cleanup is an estimate of measured cache candidates requiring owner review, not guaranteed free space. Explicitly protected caches and overlapping parent/child candidates are excluded from that estimate. Unknown sizes are counted separately. Hardlinks or shared filesystem extents can reduce actual savings. Backups, checkpoints, and worktrees appear as large disk consumers but are never automatically classified as removable. Confirmed reclaimable bytes remain unknown until the owning tool verifies cleanup eligibility.
It asks for sudo because root-owned filesystem paths and deleted open files require elevated permissions. The default diagnostic command does not delete caches or prune Docker data. The explicit cleanup command previews owning-tool cleanup and requires --apply to execute it.
Project Tool Cache Diagnostics
tsdisk reports common build/cache buildup from git.zone tooling without deleting anything:
- Deno self-extracting staging such as
dist/binaries/.*/.deno_compile_node_modules - Release binary staging under
.nogit/release-binaries/.*/.deno_compile_node_modules - tsbundle temp workspaces under
.nogit/tsbundle-tempand.nogit/tsbundle-temp-* - Retained Rust matrix directories and renamed legacy Docker registries (report-only)
- tsdocker local registry caches under
.nogit/docker-registry - Rust target caches under
rust/target,ts_rust/target, and marked.nogit/tsrust-target - Stopped
tsdocker-registry-*containers and their bind mounts - Docker buildx state volumes with zero container links, as report-only findings
Markers identify ownership, never prove inactivity. Marked caches require review; safeToPrune: false remains explicitly protected. No cache finding receives a raw rm -rf command. Unmarked legacy paths, bundle intermediates, and retained matrix runs remain report-only. Bundle cleanup belongs to tsbundle’s own stale-workspace lifecycle.
Environment
| Variable | Description | Default |
|---|---|---|
DOCKER_TIMEOUT |
Docker command timeout in seconds | 60 |
DU_TIMEOUT |
du command timeout in seconds |
300 |
NCDU_TIMEOUT |
ncdu export timeout in seconds |
900 |
TSDISK_NCDU_EXPORT |
Path for the temporary ncdu export |
/tmp/tsdisk-ncdu-root-*.json |
TSDISK_KEEP_NCDU_EXPORT |
Keep the ncdu export for later browsing |
unset |
TSDISK_INSTALL_NCDU |
Install ncdu with apt-get if missing |
prompt |
Structured Diagnostics
tsdisk scan --root /mnt/data/foss.global --json
tsdisk scan --root /mnt/data/project-a --root /mnt/data/project-b
tsdisk --json
tsdisk --help
tsdisk --version
scan and --json run bounded, noninteractive diagnostics without requesting sudo or installing tools. --root selects project-cache discovery and workspace size roots; host filesystem, home/cache, journal, deleted-open-file, and Docker diagnostics are still included. Without roots, discovery uses /mnt/data when present and the current directory. The original tsdisk human report remains available.
The JSON object includes schemaVersion, generatedAt, roots, toolCaches, issues, issueCounts, usage, reclaim, sections, and complete. Sections with kind: "command" record the executed command, arguments, exit code, stdout, stderr, and completeness. Workspace sections have kind: "derived", derivedFrom: "usage.entries", and command: "usage-summary"; their text is a compatibility summary of at most 100 retained paths, not native command output. Capped summaries set result.truncated: true and complete: false. Use usage.entries for structured paths and partial-size flags. Missing tools, command warnings, and insufficient permissions remain visible. JSON stdout contains exactly one document; five-second progress updates go to stderr.
usage records measured bytes, processed record count, the largest paths, cache paths, and completeness. It streams one native du -a -0 -x -B1 pass over the selected roots, retaining partial ancestor totals even when a large directory exceeds the time budget. Discovered .nogit directories are measured first, so retained checkpoints and worktrees become visible before broad dependency trees. GNU du counts overlapping operands and hardlinks once; the report reconstructs inclusive ancestor totals without adding those bytes twice. complete: false sizes are lower bounds; human output marks them with +. Inclusive parent/child sizes must not be added together. File records are consumed as they arrive rather than retained in memory or exported to disk. The native pass includes dependencies, backups, and arbitrary large files. Overlapping roots on the same device are scanned once; explicitly selected nested mounts are retained.
reclaim.candidateBytes counts measured cache candidates without parent/child overlap; unknownSizeCount counts unsized candidates. confirmedReclaimableBytes is null and status is owner-review-required: discovery does not run project-installed cleanup tools or establish inactivity.
Cache discovery records read failures, invalid markers, symlinks, filesystem boundaries, and exhausted depth, entry, or time budgets. Unknown sizes stay absent rather than becoming zero. Symlink roots and roots with symlink ancestors are rejected. Standard dependency and generated-code directories are intentionally excluded. Cache byte sizes are allocated disk usage, not a promise of reclaimable space: parent/child findings and hardlinks may overlap.
Cache discovery visits directories breadth first, so nearby projects precede deep worktrees. It is bounded to depth 8, 50,000 directory/symlink inspections, and 45 seconds per root. Ordinary source files do not consume the directory budget; each directory listing is capped at 4,096 entries so a huge flat directory cannot starve its siblings. issueCounts retains totals by reason; issues contains at most 200 discovery examples per root, plus sizing issues. Sizing has a 45-second budget and a 500-cache limit. Workspace usage has one DU_TIMEOUT budget (default 300 seconds, plus five seconds for termination). Additional command diagnostics have a 120-second total budget, with at most 15 seconds per command. Discovery limits are cooperative between filesystem operations. scan exits 0 for a complete report, 2 for an incomplete report, or 1 for invalid input/failure. Consumers of the earlier --json shape can still read toolCaches and workspace command sections.
Cleanup
# Project paths are explicit; cleanup never recurses across a workspace.
tsdisk cleanup --root /mnt/data/project --only=docker
# pnpm has no prune dry-run: preview identifies its configured store.
tsdisk cleanup --root /mnt/data/project --only=pnpm --json
# Execute only after reviewing the command and its scope.
tsdisk cleanup --root /mnt/data/project --only=pnpm --apply --yes
Cleanup defaults to a preview of rust,docker for the current project. --dry-run explicitly selects preview mode. Repeat --root to select multiple projects, and use --only=rust,docker,pnpm to choose categories. pnpm is opt-in because the configured store may be shared. Tsdisk never deletes a pnpm store directory.
Rust requires @git.zone/tsrust 1.13.2 or later; Docker requires @git.zone/tsdocker 3.6.0 or later. Rust and Docker use their project-installed node_modules/.bin/tsrust and tsdocker; missing tools block the batch without downloading anything. Rust previews pass --days 14 by default; --days N changes only Rust retention. Docker cleanup uses the owning tool’s identity, mount, and build checks; its abandoned-container scope can span projects in the current Docker context. Registry directories are project-local. Bundle, matrix, and legacy registry findings do not become execution targets.
Rust rechecks retention, markers, cache identity, and active use at execution time. Active Rust tools or inaccessible process state (including protected same-user processes) block removal. Linux tsrust builds and pruning share a cache guard.
All owner previews must succeed without truncated output before any execution. --apply prints the plan and asks for confirmation; noninteractive or JSON execution additionally requires --yes. Each apply invokes the owning tool again so its safety checks run at execution time. A failed command stops subsequent actions and returns a nonzero exit code; completed actions are not rolled back. Commands time out after 120 seconds for preview or 240 seconds for apply, with a five-second termination grace period. Review owning-tool state before retrying an interrupted operation.
Cleanup runs as the project owner and refuses filesystem roots and symlink project paths.
With project-local @git.zone/tsdocker 3.7.0 or later, Docker previews report whether
cache permissions require sudo. After successful previews and cleanup confirmation,
tsdisk invokes sudo's native password prompt in the terminal. The password never
enters tsdisk, arguments, environment variables, JSON, or log files. The owning tool
then elevates only approved cache file removal; project code and Docker commands
continue as your user. Rust and pnpm cleanup are never elevated.
Use --no-sudo to refuse elevated cleanup. Without a terminal, caches requiring sudo
block the batch unless --sudo is explicit and sudo can authenticate without a prompt.
--yes accepts the cleanup plan but does not supply or bypass sudo authentication.
JSON stdout remains one document; sudo prompts and notices go to the terminal/stderr.
Authentication failure or cancellation prevents all apply commands. Older Docker
tools retain their ordinary cleanup behavior and must be upgraded for sudo support;
tsdisk never reruns an old project binary as root. No plans or application state are
persisted. This Linux CLI uses du, df, findmnt, and GNU timeout from the host.
Library API
scanWorkspace(root, { maxDepth, maxEntries, timeoutMs, onProgress? }) returns findings, issues, issue counts, usage-priority paths, completion status, and the directory/symlink inspection count. collectProjectToolCacheReport(context, roots?) adds sizing. collectDiskReport(context, roots?) adds streaming workspace usage and host command diagnostics; context.onProgress receives live state updates. measureDiskUsage(roots, { timeoutSeconds, trackedPaths?, priorityPaths?, onProgress? }) performs the standalone native usage pass. Priority paths only reorder descendants on the selected filesystem; they cannot expand scan scope. estimateReclaimableSpace(findings) returns the conservative candidate summary. The existing classification and byte-formatting exports remain available. parseCliOptions(args) and createCleanupPlan(options) expose validated CLI options and cleanup command plans; creating a plan does not execute cleanup.
License and Legal Information
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the repository license file.
Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
Company Information
Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany
For any legal inquiries or further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.