M5-Lee
war-room-starter
HTMLโœจ New

Self-hosted ops dashboard fed by markdown briefs in your project folders

Last updated Jun 14, 2026
21
Stars
2
Forks
0
Issues
0
Stars/day
Attention Score
26
Language breakdown
HTML 79.9%
Python 16.1%
Shell 2.1%
Batchfile 1.9%
โ–ธ Files click to expand
README

War Room Starter

A self-hosted operations dashboard that pulls from markdown briefs in your project folders. One static HTML file, one Python scanner, no server, no database, no SaaS.

What this is

You keep a markdown file inside each project folder โ€” your "canonical brief." A small Python scanner walks those folders, reads the briefs, and bakes the data into war-room.html. You open the HTML in any browser and see one tab per project: file activity, last-touched timestamps, and the brief itself rendered live.

That's the whole loop. Update a brief, scanner picks it up on the next pass, dashboard reflects it.

Why

If you run multiple side projects and care about not losing context between sessions, the brief becomes the source of truth. The dashboard is just a view over the briefs โ€” no separate state to drift.

Requirements

  • Python 3.9 or newer
  • Any modern browser
That's it.

Quick start

git clone https://github.com/YOUR_USERNAME/war-room-starter.git
cd war-room-starter
cp config.example.json config.json

Then on Windows, double-click start-watcher.bat. On macOS or Linux:

./start-watcher.sh

Open war-room.html in your browser. You'll see three example projects (Project A, B, C) populated from the briefs in example-projects/. The watcher rescans every 30 seconds; hit the REFRESH button in the dashboard to re-read the file.

Add your own project

  • Drop a brief into your project folder. Anywhere on disk. Name the file whatever you want โ€” PROJECT_BRIEF.md is the default. Use the example briefs in example-projects/ as a template.
  • Edit config.json.
- Change projects_root to the folder that contains your project folders, e.g. "~/code" or "C:\\Projects". Use \\ (double backslash) for Windows paths in JSON, or just forward slashes โ€” Python handles both. - Add an entry under projects:
{
       "name": "my-thing",
       "label": "MY THING",
       "brieffilename": "PROJECTBRIEF.md",
       "tagline": "One-line description shown above the brief"
     }
- name must match the folder name on disk under projects_root.
  • Refresh. If the watcher is running, it picks up changes on the next scan. Otherwise re-run refresh-once. A new tab appears for your project with a live card and the rendered brief.
You can register as many projects as you want โ€” the dashboard just keeps adding tabs.

Workflow diagrams in your briefs

Add a fenced code block tagged mermaid and it renders as a diagram in the project tab.

markdown</code></pre>mermaid
flowchart LR
    A[Source] --> B[Process] --> C[Output]
<pre><code class="lang-"></code></pre>

See the example briefs for working syntax. Mermaid syntax docs.

Auto-start on login

So the watcher is running every time you start your machine.

Windows

  • Press Win + R, type shell:startup, press Enter. A folder opens.
  • Right-click in that folder โ†’ New โ†’ Shortcut.
  • Browse to start-watcher.bat, finish the wizard.
  • Right-click the shortcut you just made โ†’ Properties โ†’ set Run to Minimized.
It boots a background console every login.

macOS

# In war-room-starter/
mkdir -p ~/Library/LaunchAgents
cat > ~/Library/LaunchAgents/com.warroom.watcher.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>com.warroom.watcher</string>
  <key>ProgramArguments</key>
  <array>
    <string>$(pwd)/start-watcher.sh</string>
  </array>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>WorkingDirectory</key><string>$(pwd)</string>
</dict>
</plist>
EOF

launchctl load ~/Library/LaunchAgents/com.warroom.watcher.plist

To stop: launchctl unload ~/Library/LaunchAgents/com.warroom.watcher.plist.

Linux (systemd user service)

mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/war-room.service <<EOF
[Unit]
Description=War Room watcher

[Service] ExecStart=$(pwd)/start-watcher.sh WorkingDirectory=$(pwd) Restart=always

[Install] WantedBy=default.target EOF

systemctl --user daemon-reload systemctl --user enable --now war-room.service

How it works under the hood

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                                    
โ”‚ Your project folders   โ”‚                                                    
โ”‚  /code/my-thing/       โ”‚                                                    
โ”‚    PROJECT_BRIEF.md  โ”€โ”€โ”ผโ”€โ”€โ”                                                 
โ”‚  /code/other/          โ”‚  โ”‚                                                 
โ”‚    PROJECT_BRIEF.md  โ”€โ”€โ”ผโ”€โ”€โ”ค                                                 
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                                                 
                            โ–ผ                                                 
                  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                  โ”‚   scanner.py    โ”‚  โ”€โ”€โ”€โ–ถ โ”‚  war-room.html               โ”‚
                  โ”‚  (every 30s)    โ”‚       โ”‚  โ€ข baked-in JSON payload     โ”‚
                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ”‚  โ€ข marked.js renders briefs  โ”‚
                                            โ”‚  โ€ข mermaid renders diagrams  โ”‚
                                            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                          โ”‚
                                                          โ–ผ
                                                 your browser

The scanner only modifies the block between two HTML comments:

<!-- WARROOMDATA_BEGIN -->

<!-- WARROOMDATA_END -->

Everything else in war-room.html is left alone, so your local edits to layout, CSS, or static content survive scans.

Configuration reference

| Field | Default | Notes | | --- | --- | --- | | dashboard_title | "MY WAR ROOM" | Shown in the topbar and as the page title. | | projects_root | "./example-projects" | Absolute path or relative to scanner.py. Where your project folders live. | | watchintervalsecs | 30 | How often the watcher rescans. | | maxbriefbytes | 1000000 | Briefs larger than this are skipped (with an error in the dashboard). | | ignoredirs | see config | Folders the file-counter skips inside each project (nodemodules, .git, etc.). | | projects[] | [] | One entry per project tab. | | projects[].name | required | Folder name under projects_root. | | projects[].label | name | Display name on the tab. | | projects[].brief_filename | required | Markdown file inside the project folder. | | projects[].tagline | "" | Optional one-liner shown above the brief. |

Customizing the look

war-room.html is one self-contained file. Edit the <style> block to change colors, fonts, spacing. The terminal aesthetic (orange + green + black, Courier New) is in there. CSS variables would be a clean refactor if you want to theme it.

Security

This is a single static HTML file you open from file://. Nothing is sent anywhere. Two CDN dependencies are loaded for rendering: marked for markdown and mermaid for diagrams, both from cdnjs. If you're offline they degrade gracefully โ€” markdown renders as raw text, mermaid blocks render as code.

Don't put secrets in your briefs. API keys, passwords, customer data. The briefs render verbatim into the HTML.

Troubleshooting

The dashboard says "no scan data." The watcher hasn't run yet, or it ran but couldn't find the markers. Check that you ran start-watcher (or refresh-once) and that there are no Python errors in its terminal.

A project tab shows "Brief not found." Double-check the name in config.json matches the folder name exactly, and brief_filename matches the markdown file name. Capitalization matters.

The dashboard looks stale. Hit the REFRESH button in the topbar โ€” it just reloads the HTML from disk. Browsers don't auto-refresh file:// pages.

Mermaid diagrams aren't rendering. Make sure your fenced code block is tagged mermaid (lowercase) and the syntax is valid. Open the browser console for errors.

The dashboard format breaks after a scan. Open scanner.py's output โ€” it should print [scanner] HH:MM:SS scanned N projects, M briefs -> war-room.html on success. If it errors out, the markers may be missing or the JSON injection failed.

License

MIT. See LICENSE.

Credit

Built solo, in public. If you fork it, let me know what you build with it.

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท M5-Lee/war-room-starter ยท Updated daily from GitHub