<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Roie Ambulo</title>
    <description>The latest articles on DEV Community by Roie Ambulo (@roie).</description>
    <link>https://dev.to/roie</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F82119%2Fea5cd6b1-615a-456f-a514-dd252e529a1a.png</url>
      <title>DEV Community: Roie Ambulo</title>
      <link>https://dev.to/roie</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/roie"/>
    <language>en</language>
    <item>
      <title>I Built a Terminal Dashboard to Keep Track of All My Local Projects</title>
      <dc:creator>Roie Ambulo</dc:creator>
      <pubDate>Wed, 03 Jun 2026 23:12:02 +0000</pubDate>
      <link>https://dev.to/roie/i-built-a-terminal-dashboard-to-keep-track-of-all-my-local-projects-19k3</link>
      <guid>https://dev.to/roie/i-built-a-terminal-dashboard-to-keep-track-of-all-my-local-projects-19k3</guid>
      <description>&lt;h2&gt;
  
  
  ovw • a terminal overview for your local projects
&lt;/h2&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fscgh0ujqnnnu3i9jizj8.jpg" alt="ovw screenshot" width="799" height="349"&gt;
&lt;/h2&gt;

&lt;p&gt;If you code a lot, you know how this goes. You have an idea, you spin up a project, ship it or park it, move on to the next one. Before long you've got a growing pile of repos spread across &lt;code&gt;~/dev&lt;/code&gt;, &lt;code&gt;~/Code&lt;/code&gt;, &lt;code&gt;~/Projects&lt;/code&gt;: each one a snapshot of a different idea. Some shipped, some abandoned after the first &lt;code&gt;git commit&lt;/code&gt;, some you don't even remember writing.&lt;/p&gt;

&lt;p&gt;Even with zoxide or aliases, you still have no idea what state a project is in until you're inside it. And I didn't want a separate app just to track that.&lt;/p&gt;

&lt;p&gt;That's why I built &lt;strong&gt;ovw&lt;/strong&gt; (short for "overview").&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ovw?
&lt;/h2&gt;

&lt;p&gt;ovw is a terminal dashboard for your local projects. Point it at a few directories and it scans everything: tech stacks, Git activity, running ports, scripts, and more. Shows it all in one table.&lt;/p&gt;

&lt;p&gt;Your filesystem and Git history stay the source of truth. ovw just reads them and organizes the view.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Shows You
&lt;/h2&gt;

&lt;p&gt;The default columns are &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;stack&lt;/code&gt;, &lt;code&gt;activity&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, and &lt;code&gt;note&lt;/code&gt;. You can show, hide, and reorder any of these with &lt;code&gt;c&lt;/code&gt; in the TUI, or set them in config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;columns&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"stack"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"manager"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"branch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"activity"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"note"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what each one gives you:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Auto-detected from files: React, Go, Python, SvelteKit, Astro, and 18+ more&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Manager&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;pnpm, cargo, uv, poetry, npm, bun, and more&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scripts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Available scripts without opening package.json&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Version&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;From package.json, Cargo.toml, or pyproject.toml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Branch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Current Git branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Activity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Last commit + unpushed count&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Updated&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Last file modification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Auto-tags (dirty, stale, active) plus your own labels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ports&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Which local ports the project is running on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your notes, or falls back to last commit message&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every column is sortable, filterable, and searchable.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Place for Your Whole Dev Workflow
&lt;/h2&gt;

&lt;p&gt;The goal was never just visibility: it's cutting down the friction of context-switching. From the TUI you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;r&lt;/code&gt; opens the Runner and run any project script directly&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;o&lt;/code&gt; opens the project in your editor&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;t&lt;/code&gt; launches a terminal at the project root&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ctrl+p&lt;/code&gt; for the command palette&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No more &lt;code&gt;cd project &amp;amp;&amp;amp; npm run dev&lt;/code&gt;. Just select and go.&lt;/p&gt;

&lt;p&gt;You can also use it without the TUI. Jump straight to a single project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ovw my-project              &lt;span class="c"&gt;# TUI filtered to that project&lt;/span&gt;
ovw my-project &lt;span class="nt"&gt;--json&lt;/span&gt;       &lt;span class="c"&gt;# JSON output for that project&lt;/span&gt;
ovw my-project &lt;span class="nt"&gt;--open&lt;/span&gt;       &lt;span class="c"&gt;# open it directly in your editor&lt;/span&gt;
ovw &lt;span class="nb"&gt;.&lt;/span&gt;                     &lt;span class="c"&gt;# quick view of the current folder&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use plain and JSON output for scripting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ovw &lt;span class="nt"&gt;--plain&lt;/span&gt;      &lt;span class="c"&gt;# plain text table&lt;/span&gt;
ovw &lt;span class="nt"&gt;--json&lt;/span&gt;       &lt;span class="c"&gt;# JSON output for piping&lt;/span&gt;
ovw &lt;span class="nt"&gt;--dirty&lt;/span&gt;      &lt;span class="c"&gt;# only dirty projects&lt;/span&gt;
ovw &lt;span class="nt"&gt;--stale&lt;/span&gt;      &lt;span class="c"&gt;# only stale projects&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Status and Notes
&lt;/h2&gt;

&lt;p&gt;ovw automatically tags projects: &lt;strong&gt;dirty&lt;/strong&gt; (uncommitted changes), &lt;strong&gt;stale&lt;/strong&gt; (no activity in 30 days), &lt;strong&gt;active&lt;/strong&gt; (committed today). You can also set your own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ovw &lt;span class="nb"&gt;set &lt;/span&gt;my-project &lt;span class="nt"&gt;--status&lt;/span&gt; parked
ovw &lt;span class="nb"&gt;set &lt;/span&gt;my-project &lt;span class="nt"&gt;--note&lt;/span&gt; &lt;span class="s2"&gt;"fix check-in flow"&lt;/span&gt;
ovw &lt;span class="nb"&gt;set &lt;/span&gt;my-project &lt;span class="nt"&gt;--pin&lt;/span&gt;
ovw &lt;span class="nb"&gt;set &lt;/span&gt;my-project &lt;span class="nt"&gt;--script&lt;/span&gt; &lt;span class="nv"&gt;run&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"go run ."&lt;/span&gt;   &lt;span class="c"&gt;# add a custom script&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes never stay empty. If you haven't written one, the detail view falls back to the last commit message or the project description from its manifest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Fields
&lt;/h2&gt;

&lt;p&gt;Want to track client, owner, or priority? Define custom fields in config and they become columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ovw &lt;span class="nb"&gt;set &lt;/span&gt;my-project &lt;span class="nt"&gt;--field&lt;/span&gt; &lt;span class="nv"&gt;owner&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;roie
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Keyboard Shortcuts
&lt;/h2&gt;

&lt;p&gt;All action shortcuts are customizable. In Settings &amp;gt; Keyboard shortcuts, or directly in config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[keys.actions]&lt;/span&gt;
&lt;span class="py"&gt;details&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"d"&lt;/span&gt;
&lt;span class="py"&gt;terminal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"enter"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# macOS / Linux&lt;/span&gt;
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; roie/tap/ovw

&lt;span class="c"&gt;# or via curl&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/roie/ovw/main/install.sh | sh

&lt;span class="c"&gt;# Windows&lt;/span&gt;
powershell &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"irm https://raw.githubusercontent.com/roie/ovw/main/install.ps1 | iex"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First launch walks you through choosing which folders to scan. After that you get the full table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Under the Hood
&lt;/h2&gt;

&lt;p&gt;Your filesystem is the source of truth. ovw stores only user metadata (notes, statuses, pins) in a local config file. Everything else is read live from disk on every scan. No database, no daemon, no cloud. Fast even with dozens of projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;Even with zoxide getting me into projects fast, I still had no idea what state anything was in. And I didn't want to maintain a separate Notion or Obsidian doc just for that. ovw started as a quick script and grew into a proper tool as I kept using it. Every feature in v1.3 exists because I personally needed it.&lt;/p&gt;

&lt;p&gt;It's MIT-licensed and open for ideas, issues, and contributions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/roie/ovw" rel="noopener noreferrer"&gt;github.com/roie/ovw&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install&lt;/strong&gt;: &lt;code&gt;brew install --cask roie/tap/ovw&lt;/code&gt; or the one-liner above&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your project folders have gotten out of hand, give it a try. And if it helps, a star on GitHub goes a long way.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with way too many weekend projects.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>tui</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
