Skip to content

Commit 2125763

Browse files
halfaipgclaude
andcommitted
feat: auto-load .env files, remove VS Code boot throttle
Add dotenv.go — loads .env from cwd and ~/.codebase/.env on startup so users can drop a config file next to the binary instead of setting environment variables manually. Real env vars always win. Remove VS Code/Cursor boot animation throttle (8fps → 20fps) and re-enable logo glow effect in all terminals. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 45784f9 commit 2125763

3 files changed

Lines changed: 64 additions & 10 deletions

File tree

boot.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,9 @@ func buildBootSteps(cfg *Config) []bootStep {
207207

208208
// ── Bubble Tea ───────────────────────────────────────────────
209209

210-
// demoFPS returns the frame interval for the boot animation.
211-
// Throttled in VS Code/Cursor to prevent PTY flooding that affects other terminals.
210+
// demoFPS returns the frame interval for the boot animation (~20fps).
212211
func demoFPS() time.Duration {
213-
if termInfo.IsVSCode || termInfo.IsCursor {
214-
return 120 * time.Millisecond // ~8fps — gentle on VS Code's terminal handler
215-
}
216-
return 50 * time.Millisecond // ~20fps — full speed in standalone terminals
212+
return 50 * time.Millisecond
217213
}
218214

219215
func (m bootModel) Init() tea.Cmd {
@@ -538,10 +534,6 @@ func (m bootModel) renderLogo(px []rgb, w, h, ox, oy, scale int, t, reveal float
538534
}
539535
}
540536

541-
// Glow (skip in VS Code to reduce ANSI output volume)
542-
if termInfo.IsVSCode || termInfo.IsCursor {
543-
continue
544-
}
545537
for dy := -glowR; dy <= scale+glowR; dy++ {
546538
for dx := -glowR; dx <= scale+glowR; dx++ {
547539
x := ox + lx*scale + dx

dotenv.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"os"
6+
"path/filepath"
7+
"strings"
8+
)
9+
10+
// loadDotEnv loads .env files into os environment variables.
11+
// Only sets vars that aren't already set (real env always wins).
12+
// Searches: .env in cwd, then ~/.codebase/.env.
13+
func loadDotEnv() {
14+
paths := []string{".env"}
15+
if home, err := os.UserHomeDir(); err == nil {
16+
paths = append(paths, filepath.Join(home, ".codebase", ".env"))
17+
}
18+
for _, p := range paths {
19+
parseDotEnv(p)
20+
}
21+
}
22+
23+
func parseDotEnv(path string) {
24+
f, err := os.Open(path)
25+
if err != nil {
26+
return
27+
}
28+
defer f.Close()
29+
30+
scanner := bufio.NewScanner(f)
31+
for scanner.Scan() {
32+
line := strings.TrimSpace(scanner.Text())
33+
if line == "" || line[0] == '#' {
34+
continue
35+
}
36+
// Strip optional "export " prefix
37+
line = strings.TrimPrefix(line, "export ")
38+
line = strings.TrimSpace(line)
39+
40+
eq := strings.IndexByte(line, '=')
41+
if eq < 1 {
42+
continue
43+
}
44+
key := strings.TrimSpace(line[:eq])
45+
val := strings.TrimSpace(line[eq+1:])
46+
47+
// Unquote
48+
if len(val) >= 2 {
49+
if (val[0] == '"' && val[len(val)-1] == '"') ||
50+
(val[0] == '\'' && val[len(val)-1] == '\'') {
51+
val = val[1 : len(val)-1]
52+
}
53+
}
54+
55+
// Don't override real environment
56+
if os.Getenv(key) == "" {
57+
os.Setenv(key, val)
58+
}
59+
}
60+
}

main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ func promptForAPIKey() (string, error) {
214214
// ──────────────────────────────────────────────────────────────
215215

216216
func main() {
217+
loadDotEnv()
218+
217219
cfg, err := loadConfig()
218220
if err != nil {
219221
fmt.Fprintf(os.Stderr, "Error: %v\n", err)

0 commit comments

Comments
 (0)