diff --git a/internal/ai/approval/store.go b/internal/ai/approval/store.go index b30a59f17..bb5929e14 100644 --- a/internal/ai/approval/store.go +++ b/internal/ai/approval/store.go @@ -221,6 +221,11 @@ func (s *Store) Approve(id, username string) (*ApprovalRequest, error) { return nil, fmt.Errorf("approval request not found: %s", id) } + // Idempotent: if already approved, return success (handles double-clicks, race conditions) + if req.Status == StatusApproved { + return req, nil + } + if req.Status != StatusPending { return nil, fmt.Errorf("approval request is not pending (status: %s)", req.Status) } diff --git a/internal/api/auth.go b/internal/api/auth.go index bb03c01af..098dcef07 100644 --- a/internal/api/auth.go +++ b/internal/api/auth.go @@ -183,6 +183,16 @@ func CheckProxyAuth(cfg *config.Config, r *http.Request) (bool, string, bool) { // CheckAuth checks both basic auth and API token func CheckAuth(cfg *config.Config, w http.ResponseWriter, r *http.Request) bool { + // Dev mode bypass for all auth (disabled by default) + if adminBypassEnabled() { + if w != nil { + // Set headers for standard admin user + w.Header().Set("X-Authenticated-User", "admin") + w.Header().Set("X-Auth-Method", "bypass") + } + return true + } + config.Mu.RLock() defer config.Mu.RUnlock() diff --git a/pkg/server/server.go b/pkg/server/server.go index d66f1780e..cca526cf2 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -304,6 +304,9 @@ shutdown: log.Error().Err(err).Msg("Server shutdown error") } + // Stop OpenCode AI service (kills sidecar process group) + router.StopOpenCodeAI(shutdownCtx) + cancel() reloadableMonitor.Stop()