detached 2b5a473

feat(config): add isolated dev environment with ENV=dev

Add ENV=dev support to isolate test builds from production config/data.
When ENV=dev is set, all XDG directories (config, state, data) redirect
to .dev/dumber/ in the project root for easy testing and cleanup.

Usage: ENV=dev ./dist/dumber
Purge: ENV=dev ./dist/dumber purge --force
commit
2b5a47327aabf547f5e54f1dc838a661e013ad0e
author
bamen · · 2025-10-08 05:16 UTC
parent
c4208a6
signature
unsigned
2 files · +15 -0
M .gitignore +1 -0
@@ -80,3 +80,4 @@ specs/
8080 templates/
8181 .serena/
8282 config.yaml
83+.dev/
@@ -80,3 +80,4 @@ specs/
80 templates/80 templates/
81 .serena/81 .serena/
82 config.yaml82 config.yaml
83+.dev/
M internal/config/xdg.go +14 -0
@@ -21,6 +21,20 @@ type XDGDirs struct {
2121 // - $XDG_DATA_HOME/dumber (default: ~/.local/share/dumber)
2222 // - $XDG_STATE_HOME/dumber (default: ~/.local/state/dumber)
2323 func GetXDGDirs() (*XDGDirs, error) {
24+ // Development mode: use .dev directory in current working directory
25+ if os.Getenv("ENV") == "dev" {
26+ cwd, err := os.Getwd()
27+ if err != nil {
28+ return nil, err
29+ }
30+ devDir := filepath.Join(cwd, ".dev", appName)
31+ return &XDGDirs{
32+ ConfigHome: devDir,
33+ DataHome: devDir,
34+ StateHome: devDir,
35+ }, nil
36+ }
37+
2438 homeDir, err := os.UserHomeDir()
2539 if err != nil {
2640 return nil, err
@@ -21,6 +21,20 @@ type XDGDirs struct {
21 // - $XDG_DATA_HOME/dumber (default: ~/.local/share/dumber)21 // - $XDG_DATA_HOME/dumber (default: ~/.local/share/dumber)
22 // - $XDG_STATE_HOME/dumber (default: ~/.local/state/dumber)22 // - $XDG_STATE_HOME/dumber (default: ~/.local/state/dumber)
23 func GetXDGDirs() (*XDGDirs, error) {23 func GetXDGDirs() (*XDGDirs, error) {
24+ // Development mode: use .dev directory in current working directory
25+ if os.Getenv("ENV") == "dev" {
26+ cwd, err := os.Getwd()
27+ if err != nil {
28+ return nil, err
29+ }
30+ devDir := filepath.Join(cwd, ".dev", appName)
31+ return &XDGDirs{
32+ ConfigHome: devDir,
33+ DataHome: devDir,
34+ StateHome: devDir,
35+ }, nil
36+ }
37+
24 homeDir, err := os.UserHomeDir()38 homeDir, err := os.UserHomeDir()
25 if err != nil {39 if err != nil {
26 return nil, err40 return nil, err

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close