Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

62 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

fstop logo

๐Ÿ”ฅ fstop

A mesmerizing terminal visualization that brings your file system to life. Watch files heat decay as they change, see git status at a glance, and experience your codebase breathing in real-time.

watching: /Users/dev/myproject  โ†‘3

+ myproject/
โ”œโ”€โ”€ + src/
โ”‚   โ”œโ”€โ”€ โœš App.tsx                               MODIFIED 2s โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘
โ”‚   โ”œโ”€โ”€ โœš components/
โ”‚   โ”‚   โ””โ”€โ”€ โ— Button.tsx                        CREATED 8s โ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘
โ”‚   โ”‚       โ‹ฎ +2 more
โ”‚   โ”œโ”€โ”€ utils/...
โ”‚   โ””โ”€โ”€ index.ts
โ”œโ”€โ”€ โ€ฆ package.json
โ””โ”€โ”€ README.md

โ—2 โœš3 โ€ฆ1

โœจ Features

  • ๐ŸŒก๏ธ Heat Visualization โ€” 7-color thermal gradient (redโ†’blue) shows recency at a glance
  • ๐ŸŽจ Git Status Integration โ€” Instantly see staged, unstaged, untracked, and conflicted files with colored symbols
  • ๐ŸŒฌ๏ธ Breathing Mode โ€” The tree auto-refreshes, showing heat decay in real-time like a living organism
  • ๐Ÿ“ Space-Aware Layout โ€” Adapts to terminal size, collapsing cold branches when space is limited
  • ๐Ÿ” Priority Bubbling โ€” Hot files and git-status items bubble to the top, always visible
  • ๐Ÿ“Š Git-First Sorting โ€” Files with git status appear first within directories
  • ๐Ÿ‘ป Smart Ghosts โ€” Tracked deleted files stay visible until committed; untracked fade naturally
  • โ‹ฎ Partial Collapse โ€” Shows โ‹ฎ +N more when some directory contents are hidden
  • ๐ŸŽš๏ธ Additive Weights โ€” Granular, composable priority system for fine-tuned control
  • ๐Ÿ“‚ Directory Folding โ€” Ctrl+Up/Down or click [โ–ผ]/[โ–ถ] to fold/unfold directories; Shift+click to hide
  • โŒจ๏ธ Cursor Navigation โ€” Use arrow keys or j/k to navigate, Enter to open files
  • ๐Ÿ” Filter Mode โ€” Press / to search (vim-style), matches highlighted with yellow background
  • ๐Ÿ”— Clickable Links โ€” Filenames are clickable in iTerm and compatible terminals (OSC 8)
  • โšก Debounced Updates โ€” Smooth rendering even during rapid file changes
  • ๐Ÿ”— Symlink Support โ€” Follows symlinked directories, showing their contents live; detects and prevents loops

๐Ÿ“ฆ Installation

# Clone the repository
git clone https://github.com/yourusername/fstop.git
cd fstop

# Install dependencies
npm install

Global Installation

# Link globally to use from anywhere
npm link

# Now you can use it in any directory
cd ~/any-project
fstop .

To unlink: npm unlink -g fstop

๐Ÿš€ Usage

# Watch current directory
node bin/watch.mjs .

# Watch a specific directory
node bin/watch.mjs ./src

# Watch with more history slots
node bin/watch.mjs . --history 8

# Faster breathing (500ms refresh)
node bin/watch.mjs . --breathe 500

โš™๏ธ Options

Option Short Default Description
--history -n 4 Number of recent changes to keep hot
--breathe -b 2000 Auto-refresh interval in ms
--interval 100 Debounce interval for file changes
--ignore -i Add glob patterns to ignore
--ghost-steps 3 Fade steps for deleted items
--no-git Disable git status indicators
--quick -q Render once and exit (no watching)
--markdown-preview Preview .md files with a command (e.g. markserv)
--loopcheck Enable symlink loop detection (slower startup, safer)

๐Ÿ“ Config Files

fstop loads defaults from config files so you don't have to repeat CLI flags:

File Scope
~/.config/fstop/config.json Global defaults
.fstop.json Per-project overrides (in project root)

CLI flags override config. Config keys use camelCase versions of flag names: history, ignore, interval, breathe, ghostSteps, git, loopcheck, markdownPreview.

Markdown Preview Config

The markdownPreview key accepts either a plain command string or a structured object with extra flags. Works great with markserv:

{
  "markdownPreview": {
    "command": "markserv",
    "flags": ["--theme", "solarized"]
  }
}

The flags array is passed to the command before fstop's own arguments.

โŒจ๏ธ Keyboard Controls

fstop is fully interactive:

Key Action
โ†‘ / k Move cursor up
โ†“ / j Move cursor down
Enter Open selected file/directory
Ctrl+โ†‘ Fold directory at cursor
Ctrl+โ†“ Unfold directory at cursor
Any character Start/continue filtering
Backspace Remove last filter character
Esc Clear filter, folds, and hidden dirs
Ctrl+C Quit

Mouse Controls

Action Effect
Click filename Open file/directory
Click [โ–ผ]/[โ–ถ] Toggle fold on directory
Shift+click directory Hide directory from tree

Filter Mode

Just start typing to filter and highlight matching files:

โ”œโ”€โ”€ โœš [lay]out.mjs        <- "lay" highlighted
โ”œโ”€โ”€ renderer.mjs
โ””โ”€โ”€ terminal.mjs

/lay_
  • Matching files get a weight boost (bubble to top)
  • Matched substring shown with yellow background
  • Cursor navigation works during filter
  • Enter opens selected
  • Backspace removes last filter character
  • Esc clears filter, folds, and hidden dirs

๐ŸŽฏ Git Status Symbols

Symbol Color Meaning
โœ– ๐Ÿ”ด Red Merge conflicts
โœš ๐ŸŸก Yellow Unstaged changes
โ— ๐ŸŸข Green Staged for commit
โ€ฆ โšช Gray Untracked (new to project)
โ‡… ๐ŸŸฃ Magenta Ahead and behind remote
โ†‘ ๐Ÿ”ต Cyan Ahead of remote
โ†“ ๐Ÿ”ด Red Behind remote

๐ŸŒก๏ธ Heat System

Files pulse with a 7-segment thermal gradient from hot to cold:

โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  brightRed     โ€” Just changed (< 1s)
โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘  red           โ€” Hot
โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘  magenta       โ€” Warm  
โ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘  brightMagenta โ€” Cooling
โ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘  cyan          โ€” Cool
โ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘  brightCyan    โ€” Cold
โ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘  blue          โ€” Coldest

Heat decays exponentially with a ~10 second half-life. The breathing timer keeps the visualization alive, smoothly transitioning colors as files cool down.

Note: The heat bar color is always based on temperature, independent of git status. Filenames use git colors, bars use thermal colors.

๐Ÿ“ Project Structure

fstop/
โ”œโ”€โ”€ bin/
โ”‚   โ””โ”€โ”€ watch.mjs          # CLI entry point
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ file-watcher.mjs   # Chokidar wrapper
โ”‚   โ”œโ”€โ”€ git-status.mjs     # Git status parsing
โ”‚   โ”œโ”€โ”€ heat.mjs           # Heat scoring system
โ”‚   โ”œโ”€โ”€ layout.mjs         # Space-aware tree layout
โ”‚   โ”œโ”€โ”€ renderer.mjs       # ANSI terminal rendering
โ”‚   โ”œโ”€โ”€ terminal.mjs       # Terminal utilities
โ”‚   โ”œโ”€โ”€ tree-state.mjs     # File tree state management
โ”‚   โ””โ”€โ”€ config.mjs         # Config file loading
โ””โ”€โ”€ package.json

๐ŸŽจ How It Works

  1. File Watcher โ€” Chokidar monitors the directory for changes (follows symlinked directories)
  2. Symlink Loop Detection โ€” Preflight check detects and prevents directory symlink cycles
  3. Tree State โ€” Maintains a virtual file tree with event history
  4. Heat Scoring โ€” Calculates priority based on recency and event type
  5. Git Integration โ€” Fetches status via git status --porcelain
  6. Layout Engine โ€” Weight-based priority system adapts tree to terminal height
  7. Renderer โ€” Outputs ANSI-styled tree with in-place updates

๐ŸŽš๏ธ Priority Weight System

When space is limited, fstop uses an additive weight system to decide what to show. Each line gets a score from multiple categories:

Category Options Weights
Git conflict, unstaged, staged, untracked 800, 700, 600, 500
Heat hot, cold 350, 0
Type dir, file 100, 50
Event deleted, created, modified 150, 75, 50
Context hasChildren, inHistory, ghost 200, 100, 50

Example: A hot unstaged file that was just modified:

  • type.file (50) + git.unstaged (700) + heat.hot (350) + event.change (50) = 1150

Customizing Weights

Edit lib/layout.mjs to tune priorities:

// Prioritize deletions above everything
WEIGHT.event.unlink = 900

// Heat-first workflow (over git)
WEIGHT.heat.hot = 800
WEIGHT.git.unstaged = 300

๐Ÿ’ก Tips

  • Resize your terminal to see the adaptive layout in action
  • Use --breathe 500 for faster, more responsive heat decay
  • Use --history 8 to track more simultaneous changes
  • Press Ctrl+C to exit cleanly
  • Symlinked directories are followed automatically; if you have symlink loops, fstop will exit with an error before starting

๐Ÿ“ What Gets Watched

By default, fstop ignores:

  • **/node_modules/**
  • **/.git/**
  • **/localdata/**, **/.postgres/**, **/.mysql/** (database data)
  • **/.cache/**

Note: dist/ directories are not ignored by default. Use --ignore "**/dist/**" if you want to exclude them.

Symlinked directories are followed, including those pointing outside the watched root. If a symlink loop is detected, fstop will fail with a clear error message before starting the watcher.

๐Ÿ› ๏ธ Requirements

  • Node.js 18+
  • A terminal with ANSI color support
  • Git (optional, for git status features)

๐Ÿ“„ License

MIT


Watch your code breathe.

About

Live file tree view with heat decay, git status, and adaptive priority weighted display.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages