diff --git a/pkg/config/config.go b/pkg/config/config.go index 9d4f62a90..96e2f58cb 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -26,19 +26,19 @@ const CurrentVersion = 2 // Config is the current config structure with version support. type Config struct { - Version int `json:"version" yaml:"-"` // Config schema version for migration + Version int `json:"version" yaml:"-"` // Config schema version for migration Isolation IsolationConfig `json:"isolation,omitempty" yaml:"-"` - Agents AgentsConfig `json:"agents" yaml:"-"` - Bindings []AgentBinding `json:"bindings,omitempty" yaml:"-"` - Session SessionConfig `json:"session,omitempty" yaml:"-"` - Channels ChannelsConfig `json:"channels" yaml:"channels"` - ModelList SecureModelList `json:"model_list" yaml:"model_list"` // New model-centric provider configuration - Gateway GatewayConfig `json:"gateway" yaml:"-"` - Hooks HooksConfig `json:"hooks,omitempty" yaml:"-"` - Tools ToolsConfig `json:"tools" yaml:",inline"` - Heartbeat HeartbeatConfig `json:"heartbeat" yaml:"-"` - Devices DevicesConfig `json:"devices" yaml:"-"` - Voice VoiceConfig `json:"voice" yaml:"-"` + Agents AgentsConfig `json:"agents" yaml:"-"` + Bindings []AgentBinding `json:"bindings,omitempty" yaml:"-"` + Session SessionConfig `json:"session,omitempty" yaml:"-"` + Channels ChannelsConfig `json:"channels" yaml:"channels"` + ModelList SecureModelList `json:"model_list" yaml:"model_list"` // New model-centric provider configuration + Gateway GatewayConfig `json:"gateway" yaml:"-"` + Hooks HooksConfig `json:"hooks,omitempty" yaml:"-"` + Tools ToolsConfig `json:"tools" yaml:",inline"` + Heartbeat HeartbeatConfig `json:"heartbeat" yaml:"-"` + Devices DevicesConfig `json:"devices" yaml:"-"` + Voice VoiceConfig `json:"voice" yaml:"-"` // BuildInfo contains build-time version information BuildInfo BuildInfo `json:"build_info,omitempty" yaml:"-"` diff --git a/pkg/isolation/platform_linux.go b/pkg/isolation/platform_linux.go index 1f5d99235..1b0767fa2 100644 --- a/pkg/isolation/platform_linux.go +++ b/pkg/isolation/platform_linux.go @@ -29,7 +29,12 @@ func applyPlatformIsolation(cmd *exec.Cmd, isolation config.IsolationConfig, roo "disable_isolation": disableHint, "risk": "disabling isolation lets child processes run without Linux filesystem isolation", }) - return fmt.Errorf("linux isolation requires bwrap and does not fall back automatically: %w; install bubblewrap with one of: %s; or disable isolation by setting %s; disabling isolation means child processes can run without Linux filesystem isolation and may access or modify more host files", err, hint, disableHint) + return fmt.Errorf( + "linux isolation requires bwrap and does not fall back automatically: %w; install bubblewrap with one of: %s; or disable isolation by setting %s; disabling isolation means child processes can run without Linux filesystem isolation and may access or modify more host files", + err, + hint, + disableHint, + ) } if cmd == nil || cmd.Path == "" || len(cmd.Args) == 0 { return nil @@ -45,13 +50,13 @@ func applyPlatformIsolation(cmd *exec.Cmd, isolation config.IsolationConfig, roo plan := BuildLinuxMountPlan(root, isolation.ExposePaths) plan = ensureLinuxMountRule(plan, originalPath, originalPath, "ro") plan = ensureLinuxMountRule(plan, filepath.Dir(originalPath), filepath.Dir(originalPath), "ro") - if resolved, err := filepath.EvalSymlinks(originalPath); err == nil && resolved != originalPath { + if resolved, resolveErr := filepath.EvalSymlinks(originalPath); resolveErr == nil && resolved != originalPath { plan = ensureLinuxMountRule(plan, resolved, resolved, "ro") plan = ensureLinuxMountRule(plan, filepath.Dir(resolved), filepath.Dir(resolved), "ro") } if originalDir != "" { plan = ensureLinuxMountRule(plan, originalDir, originalDir, "rw") - if resolved, err := filepath.EvalSymlinks(originalDir); err == nil && resolved != originalDir { + if resolved, resolveErr := filepath.EvalSymlinks(originalDir); resolveErr == nil && resolved != originalDir { plan = ensureLinuxMountRule(plan, resolved, resolved, "rw") } } @@ -101,7 +106,12 @@ func postStartPlatformIsolation(cmd *exec.Cmd, isolation config.IsolationConfig, // buildLinuxBwrapArgs translates the mount plan into the bubblewrap command // line that re-executes the original process inside the isolated mount view. -func buildLinuxBwrapArgs(originalPath string, originalArgs []string, originalDir string, plan []MountRule) ([]string, error) { +func buildLinuxBwrapArgs( + originalPath string, + originalArgs []string, + originalDir string, + plan []MountRule, +) ([]string, error) { bwrapArgs := []string{ "bwrap", "--die-with-parent", diff --git a/pkg/isolation/platform_windows.go b/pkg/isolation/platform_windows.go index 0776557cd..951e74302 100644 --- a/pkg/isolation/platform_windows.go +++ b/pkg/isolation/platform_windows.go @@ -9,9 +9,10 @@ import ( "syscall" "unsafe" + "golang.org/x/sys/windows" + "github.com/sipeed/picoclaw/pkg/config" "github.com/sipeed/picoclaw/pkg/logger" - "golang.org/x/sys/windows" ) const disableMaxPrivilege = 0x1 diff --git a/pkg/isolation/runtime_test.go b/pkg/isolation/runtime_test.go index db268a05c..b8cc816c3 100644 --- a/pkg/isolation/runtime_test.go +++ b/pkg/isolation/runtime_test.go @@ -51,7 +51,12 @@ func TestValidateExposePaths(t *testing.T) { t.Fatal("ValidateExposePaths() expected invalid mode error") } - err = ValidateExposePaths([]config.ExposePath{{Source: "/src", Target: "/dst", Mode: "ro"}, {Source: "/other", Target: "/dst", Mode: "rw"}}) + err = ValidateExposePaths( + []config.ExposePath{ + {Source: "/src", Target: "/dst", Mode: "ro"}, + {Source: "/other", Target: "/dst", Mode: "rw"}, + }, + ) if err == nil { t.Fatal("ValidateExposePaths() expected duplicate target error") } @@ -98,7 +103,10 @@ func TestBuildLinuxMountPlan(t *testing.T) { func TestBuildWindowsAccessRules(t *testing.T) { t.Setenv("USERPROFILE", `C:\Users\tester`) - rules := BuildWindowsAccessRules(`C:\picoclaw`, []config.ExposePath{{Source: `D:\data`, Target: `C:\mapped`, Mode: "ro"}}) + rules := BuildWindowsAccessRules( + `C:\picoclaw`, + []config.ExposePath{{Source: `D:\data`, Target: `C:\mapped`, Mode: "ro"}}, + ) if len(rules) == 0 { t.Fatal("BuildWindowsAccessRules returned empty rules") }