Skip to content

Commit 0faca3b

Browse files
rsnodgrassSage-Ox
andcommitted
Release v0.8.0: devcontainer status, tree view, gold tmux tabs
- Add wl dc --status for paired devcontainer connection status - Add tree view in wl start matching wl ps for visual continuity - Show forwardPorts from devcontainer.json in status displays - Gold tmux tabs for [dc] devcontainer sessions - Fix tmux status scripts using full $HOME/bin/ paths - Fix JSONC parsing for devcontainer.json with // comments - Define icon variables (ICON_RUNNING, ICON_STOPPED, etc.) in lib/style.sh - ICON_NO_SSHD includes trailing space (⚠ is a wide character) - tmux status: show ⚡dc when connected, ⚠ dc when unreachable Co-Authored-By: SageOx <ox@sageox.ai>
1 parent 3e43bac commit 0faca3b

File tree

6 files changed

+504
-111
lines changed

6 files changed

+504
-111
lines changed

.devcontainer/home/.tmux.conf

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,24 @@ set -g status-right-length 80
2323

2424
# Left: session icon + name (cyan), separator, project with folder icon (white)
2525
# Icons: (nf-oct-terminal), (nf-cod-folder) - folder icon in wl-project-name
26-
set -g status-left '#[fg=#50c8dc,bold] #S #[fg=#3a3f4a]│#[fg=#c8c8c8]#(wl-project-name)#[default] '
26+
set -g status-left '#[fg=#50c8dc,bold] #S #[fg=#3a3f4a]│#[fg=#c8c8c8]#($HOME/bin/wl-project-name)#[default] '
2727

2828
# Right: git (sky blue) · dc status (gold) · time (dim)
2929
# Combined script handles conditional separators (no ` · · ` when dc missing)
3030
# Icons: (git), (folder), ⚡ (dc), 󰥔 (time)
31-
set -g status-right '#(wl-status-right)'
31+
set -g status-right '#($HOME/bin/wl-status-right)'
3232

33-
# Window tabs: rounded pill style
34-
# Active window gets a subtle pill background, inactive stays minimal
33+
# Window tabs: rounded pill style with devcontainer distinction
34+
# [dc] windows (devcontainer sessions) shown in gold to indicate different host
35+
# Regular windows in cyan, devcontainer windows in gold (#ffd23c)
3536
# Powerline rounded chars: (U+E0B6) and (U+E0B4)
36-
set -g window-status-format '#[fg=#555555] #I:#W '
37-
set -g window-status-current-format '#[fg=#3a3f4a,bg=default]#[bg=#3a3f4a,fg=#50c8dc]#I#[fg=#8c969f]:#[fg=#c8c8c8]#W#[fg=#3a3f4a,bg=default]'
37+
38+
# Inactive windows: dim, but gold for [dc] windows
39+
set -g window-status-format '#{?#{m:[dc]*,#W},#[fg=#b8962a] #I:#W ,#[fg=#555555] #I:#W }'
40+
41+
# Active window: pill background, cyan for regular, gold for [dc]
42+
set -g window-status-current-format '#{?#{m:[dc]*,#W},#[fg=#4a3f1a,bg=default]#[bg=#4a3f1a,fg=#ffd23c,bold]#I#[fg=#c8a83c]:#[fg=#ffe066]#W#[fg=#4a3f1a,bg=default,nobold],#[fg=#3a3f4a,bg=default]#[bg=#3a3f4a,fg=#50c8dc]#I#[fg=#8c969f]:#[fg=#c8c8c8]#W#[fg=#3a3f4a,bg=default]}'
43+
3844
set -g window-status-separator ''
3945

4046
# Pane borders: subtle
@@ -66,12 +72,12 @@ set -g visual-activity off
6672
# prefix + S opens SSH tunnel to devcontainer (requires sshd feature)
6773
# Useful for sidecar mode where the project has its own devcontainer
6874
# The [dc] prefix clearly indicates this window is connected to the devcontainer
69-
bind D new-window -n '[dc] shell' 'dc-attach || read -p "Press Enter to close..."'
70-
bind S new-window -n '[dc] ssh' 'dc-ssh || read -p "Press Enter to close..."'
75+
bind D new-window -n '[dc] shell' '$HOME/bin/dc-attach || read -p "Press Enter to close..."'
76+
bind S new-window -n '[dc] ssh' '$HOME/bin/dc-ssh || read -p "Press Enter to close..."'
7177

7278
# Session save/restore
7379
# prefix + W saves current session layout (persists across container rebuilds)
74-
bind W run-shell 'wl-session-save && tmux display-message "Session saved"'
80+
bind W run-shell '$HOME/bin/wl-session-save && tmux display-message "Session saved"'
7581

7682
# Source user overrides if present
7783
if-shell "[ -f ~/.config/work-lab/tmux.conf.local ]" "source-file ~/.config/work-lab/tmux.conf.local"
Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
#!/bin/bash
22
# work-lab devcontainer status for tmux status bar
3-
# Shows "⚡ dc" if paired devcontainer is running, nothing otherwise
4-
# Keeping the status bar clean when dc not available
3+
# ⚡dc = connected and reachable
4+
# ⚠dc = devcontainer exists but not connected
5+
# (nothing) = no devcontainer in project
56

6-
# Quick check: is docker available?
7-
command -v docker &>/dev/null || exit 0
7+
has_devcontainer=false
8+
dc_connected=false
89

9-
# Get project name from the mounted workspace
10-
project_name=$(basename /workspaces/project 2>/dev/null) || exit 0
10+
# check if project has a devcontainer config
11+
if [[ -d /workspaces/project/.devcontainer ]] || \
12+
[[ -f /workspaces/project/.devcontainer.json ]]; then
13+
has_devcontainer=true
14+
fi
1115

12-
# Look for a devcontainer matching this project (excluding work-lab containers)
13-
while IFS= read -r container_id; do
14-
[[ -z "$container_id" ]] && continue
15-
16-
container_name=$(docker inspect --format '{{.Name}}' "$container_id" 2>/dev/null | tr -d '/')
17-
[[ "$container_name" == *"work-lab"* ]] && continue
18-
19-
local_folder=$(docker inspect --format '{{index .Config.Labels "devcontainer.local_folder"}}' "$container_id" 2>/dev/null)
20-
folder_name=$(basename "$local_folder" 2>/dev/null)
21-
22-
if [[ "$folder_name" == "$project_name" ]]; then
23-
echo "⚡ dc"
24-
exit 0
16+
# check SSH tunnel connectivity
17+
if [[ -f /workspaces/project/.work-lab/ip ]]; then
18+
dc_ip=$(cat /workspaces/project/.work-lab/ip 2>/dev/null)
19+
if [[ -n "$dc_ip" ]] && nc -z -w 1 "$dc_ip" 22 2>/dev/null; then
20+
dc_connected=true
2521
fi
26-
done < <(docker ps --filter "label=devcontainer.local_folder" --format '{{.ID}}' 2>/dev/null)
22+
fi
23+
24+
if $dc_connected; then
25+
echo "⚡dc"
26+
elif $has_devcontainer; then
27+
echo "⚠ dc"
28+
fi

.devcontainer/home/bin/wl-status-right

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,31 @@ if [[ -n "$branch" ]]; then
2323
fi
2424
fi
2525

26-
# DC status (only if docker available and paired dc running)
27-
if command -v docker &>/dev/null; then
28-
project_name=$(basename /workspaces/project 2>/dev/null)
29-
while IFS= read -r container_id; do
30-
[[ -z "$container_id" ]] && continue
31-
container_name=$(docker inspect --format '{{.Name}}' "$container_id" 2>/dev/null | tr -d '/')
32-
[[ "$container_name" == *"work-lab"* ]] && continue
33-
local_folder=$(docker inspect --format '{{index .Config.Labels "devcontainer.local_folder"}}' "$container_id" 2>/dev/null)
34-
folder_name=$(basename "$local_folder" 2>/dev/null)
35-
if [[ "$folder_name" == "$project_name" ]]; then
36-
segments+=("#[fg=#ffd23c]⚡ dc#[default]")
37-
break
38-
fi
39-
done < <(docker ps --filter "label=devcontainer.local_folder" --format '{{.ID}}' 2>/dev/null)
26+
# DC status - shows paired devcontainer state
27+
# ⚡dc (gold) = connected and reachable
28+
# ⚠dc (amber) = devcontainer exists but not connected
29+
# (nothing) = no devcontainer in project
30+
has_devcontainer=false
31+
dc_connected=false
32+
33+
# check if project has a devcontainer config
34+
if [[ -d /workspaces/project/.devcontainer ]] || \
35+
[[ -f /workspaces/project/.devcontainer.json ]]; then
36+
has_devcontainer=true
37+
fi
38+
39+
# check SSH tunnel connectivity (docker not available in work-lab)
40+
if [[ -f /workspaces/project/.work-lab/ip ]]; then
41+
dc_ip=$(cat /workspaces/project/.work-lab/ip 2>/dev/null)
42+
if [[ -n "$dc_ip" ]] && nc -z -w 1 "$dc_ip" 22 2>/dev/null; then
43+
dc_connected=true
44+
fi
45+
fi
46+
47+
if $dc_connected; then
48+
segments+=("#[fg=#ffd23c]⚡dc#[default]")
49+
elif $has_devcontainer; then
50+
segments+=("#[fg=#e5a050]⚠ dc#[default]")
4051
fi
4152

4253
# Time (always shown)

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@ All notable changes to work-lab will be documented in this file.
66
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
77
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
88

9+
## [0.8.0] - 2026-01-10
10+
11+
### Added
12+
13+
- **`wl dc --status`**: Check paired devcontainer connection status at a glance
14+
- **Tree view in `wl start`**: Shows container status matching `wl ps` for visual continuity
15+
- **Devcontainer ports display**: Shows `forwardPorts` in `wl start` and `wl dc --status`
16+
- **Gold tmux tabs for devcontainer sessions**: `[dc]` windows clearly distinguished from regular tabs
17+
18+
### Changed
19+
20+
- **`wl start` cleaner output**: Removed banner, redundant path info; shows activity first
21+
- **`wl doctor --fix` auto-rebuild**: Rebuilds container after pulling new image (if no tmux session attached)
22+
- **tmux status bar**: `⚡dc` when connected, `⚠ dc` when devcontainer exists but unreachable
23+
- **tmux scripts use full paths**: Fixes status bar not displaying on some systems
24+
25+
### Fixed
26+
27+
- **tmux status scripts**: Now work reliably (use `$HOME/bin/` paths instead of relying on PATH)
28+
- **JSONC parsing**: Port extraction handles `//` comments in devcontainer.json
29+
930
## [0.7.1] - 2026-01-10
1031

1132
### Added
@@ -152,6 +173,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
152173
- Manual clone
153174
- Installed tools: tmux, git, curl, jq, ripgrep, fzf, Node.js 22 LTS, Claude CLI, Gastown, Beads
154175

176+
[0.8.0]: https://github.com/modern-tooling/work-lab/releases/tag/v0.8.0
155177
[0.7.1]: https://github.com/modern-tooling/work-lab/releases/tag/v0.7.1
156178
[0.7.0]: https://github.com/modern-tooling/work-lab/releases/tag/v0.7.0
157179
[0.6.0]: https://github.com/modern-tooling/work-lab/releases/tag/v0.6.0

0 commit comments

Comments
 (0)