Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
```
cmd/bwai/
main.go # Entry point, flag parsing, bwrap command construction
config.go # Config struct, defaults, JSON loading (~/.bwai.json)
config.go # Config struct and JSON loading (~/.bwai.json)
defaults.json # Built-in default configuration (embedded into the binary at build time)
mounts.go # Filesystem mount logic (home, DNS, GPU, shm)
bwrap.go # Low-level bwrap argument helpers (roBind, rwBind, devBind, tmpfs)
update.go # Self-update from GitHub releases with SHA-256 verification
Expand Down Expand Up @@ -74,8 +75,8 @@ bwai --dump-config # Print default config as JSON

- **New mount type**: Add a helper function in `mounts.go` following the existing pattern (`[]string` return, appended in `main.go`).
- **New CLI flag**: Add to `main.go` using the `flag` package; wire into the bwrap args slice.
- **New config field**: Add to the `Config` struct in `config.go` and update `defaultConfig()`.
- **New agent support**: Add its dotfiles to `home_allow` defaults and its API key to `env_allow` defaults in `config.go`.
- **New config field**: Add to the `Config` struct in `config.go` and add the default value to `defaults.json`.
- **New agent support**: Add its dotfiles to `home_allow` and its API key to `env_allow` in `defaults.json`.

## Testing

Expand Down
69 changes: 2 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,78 +98,13 @@ Everything after `--` is passed as extra arguments to the resolved command.
bwai --config /path/to/my-config.json
```

To see the full default configuration as a starting point, run:
To use the full defaults as a starting point, run:

```sh
bwai --dump-config > ~/.bwai.json
```

Example `~/.bwai.json`:

```json
{
"bwrap_path": "bwrap",
"bwrap_extra_args": ["--unshare-pid", "--unshare-ipc"],
"command": ["bash"],
"home_allow": [
".claude",
".gemini",
".claude.json",
".config/goose",
".config/gcloud",
".local/state",
".local/share/goose",
".cache",
".cargo"
],
"home_block": [
".gnupg",
".ssh",
".pki",
".aws",
".kube",
".azure",
".bashrc",
".bashrc.d",
".password-store",
".bash_history*",
".config/Bitwarden",
".cache/nvidia"
],
"env_allow": [
"TERM",
"COLORTERM",
"LANG",
"LC_ALL",
"LC_MESSAGES",
"LC_CTYPE",
"HOME",
"USER",
"LOGNAME",
"PATH",
"EDITOR",
"ANTHROPIC_API_KEY",
"ANTHROPIC_MODEL",
"ANTHROPIC_DEFAULT_OPUS_MODEL",
"ANTHROPIC_DEFAULT_SONNET_MODEL",
"ANTHROPIC_DEFAULT_HAIKU_MODEL",
"CLAUDE_CODE_USE_VERTEX",
"CLOUD_ML_REGION",
"ANTHROPIC_VERTEX_PROJECT_ID",
"GEMINI_API_KEY",
"GOOGLE_API_KEY",
"GCLOUD_PROJECT",
"GOOGLE_CLOUD_PROJECT",
"GOOSE_PROVIDER",
"GOOSE_MODEL",
"GOOSE_PLANNER_PROVIDER",
"GOOSE_PLANNER_MODEL",
"OPENAI_API_KEY",
"OPENAI_API_BASE",
"OPENROUTER_API_KEY",
]
}
```
The built-in defaults are also available at [`cmd/bwai/defaults.json`](cmd/bwai/defaults.json).

| Field | Description | Default |
|---|---|---|
Expand Down
76 changes: 8 additions & 68 deletions cmd/bwai/config.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package main

import (
_ "embed"
"encoding/json"
"os"
)

//go:embed defaults.json
var defaultConfigJSON []byte

type Config struct {
// Path to the bwrap binary. Defaults to "bwrap"
BwrapPath string `json:"bwrap_path"`
Expand All @@ -26,75 +30,11 @@ type Config struct {
}

func defaultConfig() Config {
return Config{
BwrapPath: "bwrap",
BwrapExtraArgs: []string{"--unshare-pid", "--unshare-ipc"},
Command: []string{"bash"},
EnvAllow: []string{
"TERM",
"COLORTERM",
"LANG",
"LC_ALL",
"LC_MESSAGES",
"LC_CTYPE",
"HOME",
"USER",
"LOGNAME",
"PATH",
"EDITOR",
// Claude
"ANTHROPIC_API_KEY",
// Claude model selection / pinning
"ANTHROPIC_MODEL",
"ANTHROPIC_DEFAULT_OPUS_MODEL",
"ANTHROPIC_DEFAULT_SONNET_MODEL",
"ANTHROPIC_DEFAULT_HAIKU_MODEL",
// Claude Code on Google Vertex AI
"CLAUDE_CODE_USE_VERTEX",
"CLOUD_ML_REGION",
"ANTHROPIC_VERTEX_PROJECT_ID",
// Gemini / Google
"GEMINI_API_KEY",
"GOOGLE_API_KEY",
"GCLOUD_PROJECT",
"GOOGLE_CLOUD_PROJECT",
// Goose (uses provider keys above + its own config)
"GOOSE_PROVIDER",
"GOOSE_MODEL",
"GOOSE_PLANNER_PROVIDER",
"GOOSE_PLANNER_MODEL",
// OpenAI-compatible providers (used by Goose and others)
"OPENAI_API_KEY",
"OPENAI_API_BASE",
// OpenRouter
"OPENROUTER_API_KEY",
},
HomeAllow: []string{
".claude",
".gemini",
".claude.json",
".config/goose",
".config/gcloud",
".local/state",
".local/share/goose",
".cache",
".cargo",
},
HomeBlock: []string{
".gnupg",
".ssh",
".pki",
".aws",
".kube",
".azure",
".bashrc",
".bashrc.d",
".password-store",
".bash_history*",
".config/Bitwarden",
".cache/nvidia",
},
var cfg Config
if err := json.Unmarshal(defaultConfigJSON, &cfg); err != nil {
panic("bwai: invalid defaults.json: " + err.Error())
}
return cfg
}

// loadConfig reads the config file at the given path if it exists and returns the resulting Config.
Expand Down
62 changes: 62 additions & 0 deletions cmd/bwai/defaults.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"bwrap_path": "bwrap",
"bwrap_extra_args": ["--unshare-pid", "--unshare-ipc"],
"command": ["bash"],
"home_allow": [
".claude",
".gemini",
".claude.json",
".config/goose",
".config/gcloud",
".local/state",
".local/share/goose",
".cache",
".cargo"
],
"home_block": [
".gnupg",
".ssh",
".pki",
".aws",
".kube",
".azure",
".bashrc",
".bashrc.d",
".password-store",
".bash_history*",
".config/Bitwarden",
".cache/nvidia"
],
"env_allow": [
"TERM",
"COLORTERM",
"LANG",
"LC_ALL",
"LC_MESSAGES",
"LC_CTYPE",
"HOME",
"USER",
"LOGNAME",
"PATH",
"EDITOR",
"ANTHROPIC_API_KEY",
"ANTHROPIC_MODEL",
"ANTHROPIC_DEFAULT_OPUS_MODEL",
"ANTHROPIC_DEFAULT_SONNET_MODEL",
"ANTHROPIC_DEFAULT_HAIKU_MODEL",
"CLAUDE_CODE_USE_VERTEX",
"CLOUD_ML_REGION",
"ANTHROPIC_VERTEX_PROJECT_ID",
"GEMINI_API_KEY",
"GOOGLE_API_KEY",
"GCLOUD_PROJECT",
"GOOGLE_CLOUD_PROJECT",
"GOOSE_PROVIDER",
"GOOSE_MODEL",
"GOOSE_PLANNER_PROVIDER",
"GOOSE_PLANNER_MODEL",
"OPENAI_API_KEY",
"OPENAI_API_BASE",
"OPENROUTER_API_KEY"
]
}
Loading