first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
package harness
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/bytedance/sonic"
"github.com/maximhq/bifrost/cli/internal/config"
)
// claudePreLaunch forces Claude Code into its simpler terminal mode when
// launched inside Bifrost's tab multiplexer. This avoids Claude-specific
// full-screen terminal behavior that doesn't restore reliably across tab swaps.
func claudePreLaunch(baseURL, apiKey, model string) ([]string, func(), error) {
env := []string{"CLAUDE_CODE_SIMPLE=1"}
if model = strings.TrimSpace(model); model != "" {
env = append(env, claudeTierModelEnv(model)...)
}
return env, func() {}, nil
}
// claudeWriteNativeConfig writes the bifrost endpoint, API key, and model
// into Claude Code's settings file (~/.claude/settings.json) so the same
// configuration is available when users launch Claude Code directly.
//
// It merges into the existing file, preserving any user-defined settings.
func claudeWriteNativeConfig(baseURL, apiKey, model string) error {
home, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("resolve home dir: %w", err)
}
dir := filepath.Join(home, ".claude")
settingsPath := filepath.Join(dir, "settings.json")
// Read existing settings or start fresh
settings := make(map[string]any)
if b, err := os.ReadFile(settingsPath); err == nil {
if err := sonic.Unmarshal(b, &settings); err != nil {
return fmt.Errorf("parse existing claude settings: %w", err)
}
} else if !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("read claude settings: %w", err)
}
// Get or create the env map
envRaw, ok := settings["env"]
var envMap map[string]any
if ok {
envMap, ok = envRaw.(map[string]any)
if !ok {
envMap = make(map[string]any)
}
} else {
envMap = make(map[string]any)
}
envMap["ANTHROPIC_BASE_URL"] = baseURL
envMap["ANTHROPIC_API_KEY"] = apiKey
if model = strings.TrimSpace(model); model != "" {
for key, value := range claudeTierModelEnvMap(model) {
envMap[key] = value
}
delete(envMap, "ANTHROPIC_MODEL")
}
settings["env"] = envMap
b, err := sonic.MarshalIndent(settings, "", " ")
if err != nil {
return fmt.Errorf("marshal claude settings: %w", err)
}
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("create claude config dir: %w", err)
}
return config.WriteAtomic(settingsPath, b, 0o600)
}
func claudeTierModelEnv(model string) []string {
envMap := claudeTierModelEnvMap(model)
return []string{
"ANTHROPIC_DEFAULT_SONNET_MODEL=" + envMap["ANTHROPIC_DEFAULT_SONNET_MODEL"],
"ANTHROPIC_DEFAULT_OPUS_MODEL=" + envMap["ANTHROPIC_DEFAULT_OPUS_MODEL"],
"ANTHROPIC_DEFAULT_HAIKU_MODEL=" + envMap["ANTHROPIC_DEFAULT_HAIKU_MODEL"],
}
}
func claudeTierModelEnvMap(model string) map[string]string {
return map[string]string{
"ANTHROPIC_DEFAULT_SONNET_MODEL": model,
"ANTHROPIC_DEFAULT_OPUS_MODEL": model,
"ANTHROPIC_DEFAULT_HAIKU_MODEL": model,
}
}