feat(settings): KEEL_AW_URL with localhost default

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 19:39:49 -04:00
parent 3a4f498f86
commit 67f91442a4
2 changed files with 24 additions and 3 deletions
+7 -1
View File
@@ -17,11 +17,12 @@ import (
var ErrInvalidBackend = errors.New("settings: invalid ai backend") var ErrInvalidBackend = errors.New("settings: invalid ai backend")
// Settings is the user-editable configuration. Field names mirror the env vars // Settings is the user-editable configuration. Field names mirror the env vars
// they replace: KEEL_AI_BACKEND, KEEL_MARVIN_CMD, KEEL_KNOWLEDGE_FILE. // they replace: KEEL_AI_BACKEND, KEEL_MARVIN_CMD, KEEL_KNOWLEDGE_FILE, KEEL_AW_URL.
type Settings struct { type Settings struct {
AIBackend string `json:"ai_backend"` AIBackend string `json:"ai_backend"`
MarvinCmd string `json:"marvin_cmd"` MarvinCmd string `json:"marvin_cmd"`
KnowledgePath string `json:"knowledge_path"` KnowledgePath string `json:"knowledge_path"`
AWURL string `json:"aw_url"`
} }
// DefaultPath returns ~/.keel/settings.json. // DefaultPath returns ~/.keel/settings.json.
@@ -72,9 +73,14 @@ func SeedFromEnv() Settings {
if backend == "" { if backend == "" {
backend = "claude" backend = "claude"
} }
awURL := os.Getenv("KEEL_AW_URL")
if awURL == "" {
awURL = "http://localhost:5600"
}
return Settings{ return Settings{
AIBackend: backend, AIBackend: backend,
MarvinCmd: os.Getenv("KEEL_MARVIN_CMD"), MarvinCmd: os.Getenv("KEEL_MARVIN_CMD"),
KnowledgePath: os.Getenv("KEEL_KNOWLEDGE_FILE"), KnowledgePath: os.Getenv("KEEL_KNOWLEDGE_FILE"),
AWURL: awURL,
} }
} }
+17 -2
View File
@@ -8,7 +8,7 @@ import (
func TestSaveLoadRoundTrip(t *testing.T) { func TestSaveLoadRoundTrip(t *testing.T) {
path := filepath.Join(t.TempDir(), "settings.json") path := filepath.Join(t.TempDir(), "settings.json")
want := Settings{AIBackend: "codex", MarvinCmd: "uv run am", KnowledgePath: "/tmp/k.md"} want := Settings{AIBackend: "codex", MarvinCmd: "uv run am", KnowledgePath: "/tmp/k.md", AWURL: "http://aw.local:5600"}
if err := Save(path, want); err != nil { if err := Save(path, want); err != nil {
t.Fatalf("save: %v", err) t.Fatalf("save: %v", err)
} }
@@ -32,8 +32,9 @@ func TestSeedFromEnvReadsVars(t *testing.T) {
t.Setenv("KEEL_AI_BACKEND", "codex") t.Setenv("KEEL_AI_BACKEND", "codex")
t.Setenv("KEEL_MARVIN_CMD", "uv run am") t.Setenv("KEEL_MARVIN_CMD", "uv run am")
t.Setenv("KEEL_KNOWLEDGE_FILE", "/tmp/k.md") t.Setenv("KEEL_KNOWLEDGE_FILE", "/tmp/k.md")
t.Setenv("KEEL_AW_URL", "http://aw.local:5600")
got := SeedFromEnv() got := SeedFromEnv()
want := Settings{AIBackend: "codex", MarvinCmd: "uv run am", KnowledgePath: "/tmp/k.md"} want := Settings{AIBackend: "codex", MarvinCmd: "uv run am", KnowledgePath: "/tmp/k.md", AWURL: "http://aw.local:5600"}
if got != want { if got != want {
t.Errorf("SeedFromEnv = %+v, want %+v", got, want) t.Errorf("SeedFromEnv = %+v, want %+v", got, want)
} }
@@ -58,3 +59,17 @@ func TestSaveCreatesDir(t *testing.T) {
t.Fatalf("file not written: %v", err) t.Fatalf("file not written: %v", err)
} }
} }
func TestSeedFromEnvAWURL(t *testing.T) {
t.Setenv("KEEL_AW_URL", "http://aw.example:9999")
if got := SeedFromEnv().AWURL; got != "http://aw.example:9999" {
t.Fatalf("AWURL = %q", got)
}
}
func TestSeedFromEnvAWURLDefault(t *testing.T) {
t.Setenv("KEEL_AW_URL", "")
if got := SeedFromEnv().AWURL; got != "http://localhost:5600" {
t.Fatalf("default AWURL = %q", got)
}
}