Skip to content

Conversation

@stefandevo
Copy link
Collaborator

@stefandevo stefandevo commented Jan 16, 2026

Summary

This PR introduces a new dedicated Project Settings screen accessible from the sidebar, clearly separating project-specific settings from global application settings. This improves UX by making it clear which settings affect all projects vs. the current project only.

Key Highlights

  • New Project Settings screen with sidebar navigation
  • Clear separation: Global Settings = app-wide defaults, Project Settings = per-project overrides
  • Consistent "inherit from global, override per-project" pattern for Theme and Worktree Isolation
  • Bug fixes for settings not persisting correctly

Motivation

Previously, global settings and project-specific settings were mixed together in a single Settings screen, causing confusion about:

  • Which settings affect all projects vs. just the current one
  • What happens when you change a "global" setting while a project is open
  • Where to find project-specific customizations

This PR addresses these issues by:

  1. Creating a dedicated Project Settings screen
  2. Establishing a clear inheritance pattern: Global → Project Override
  3. Fixing bugs where changing global settings incorrectly affected project overrides

New Project Settings Screen

Access

  • Sidebar: "Project Settings" item in its own section below Tools (with separator line)
  • Keyboard Shortcut: Shift+S
  • Route: /project-settings

Sections

Section Settings
Identity Project name, Lucide icon picker, Custom icon upload
Worktrees Enable worktree isolation (override), Init script indicator, Auto-dismiss, Delete branch default, Init script editor
Theme Project-specific theme override
Danger Zone Delete project

Sidebar Changes

The sidebar now has a clear separation between project-specific and global settings:

Project
├── Kanban Board
├── Graph View  
├── Agent Runner
└── Terminal

Tools
├── Ideation
├── Spec Editor
├── Context
└── Memory

GitHub (if applicable)
├── Issues
└── Pull Requests

─────────────────────
Project Settings      ← New standalone section with separator

─────────────────────
Global Settings       ← Renamed from "Settings"

Settings Separation

Moved to Project Settings (per-project)

These settings now live in Project Settings and are stored in .automaker/settings.json:

  • ✅ Project name and icon customization
  • ✅ Project-specific theme (override global)
  • ✅ Enable Git Worktree Isolation (override global)
  • ✅ Show init script indicator
  • ✅ Auto-dismiss init script indicator
  • ✅ Delete branch by default
  • ✅ Initialization script (.automaker/worktree-init.sh)
  • ✅ Delete project action

Remains in Global Settings (app-wide)

These settings remain in Global Settings as they affect all projects:

  • 🌍 Global theme (default for new projects)
  • 🌍 Enable Git Worktree Isolation (default for new projects)
  • 🌍 Feature Defaults (skip tests, dependency blocking, etc.)
  • 🌍 Model Defaults (phase models)
  • 🌍 API Keys
  • 🌍 AI Providers (Claude, Cursor, Codex, OpenCode)
  • 🌍 MCP Servers
  • 🌍 Prompt Customization
  • 🌍 Terminal, Keyboard Shortcuts, Audio
  • 🌍 Account, Security, Developer

Global → Project Override Pattern

Both Theme and Worktree Isolation now follow a consistent inheritance pattern:

┌─────────────────────────────────────────────────────────────┐
│                     GLOBAL SETTINGS                         │
│  Theme: "dracula"          Worktrees: enabled               │
│  (Default for all projects)                                 │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                   PROJECT SETTINGS                          │
│                                                             │
│  Project A: (no override)     → Uses global: dracula, on    │
│  Project B: theme="nord"      → Override: nord, on          │
│  Project C: worktrees=false   → Override: dracula, off      │
│  Project D: both overridden   → Override: tokyonight, off   │
└─────────────────────────────────────────────────────────────┘

How It Works

  1. Global Settings defines the default value for all projects
  2. New projects automatically inherit the global value
  3. Project Settings can override for that specific project
  4. Changing global does NOT affect projects with their own override

Example: Theme

Action Result
Global theme is "dark" All projects without override show "dark"
Project A sets theme to "dracula" Project A shows "dracula"
Global theme changed to "nord" Project A still shows "dracula" (has override)
Other projects now show "nord" They inherit from global

Bug Fixes

1. Global theme change was overwriting project themes

Before: Changing theme in Global Settings would also set the project's theme, overwriting any override.

After: Global Settings only changes the global theme. Projects with overrides are not affected.

2. Project worktree setting not persisting

Before: Project-specific worktree isolation setting was lost on page refresh.

After: Settings are loaded from server when Project Settings opens, properly restoring overrides.


UI Improvements

Shell Syntax Editor (Init Script)

  • Background: Changed from bg-muted/30 to bg-background for better contrast in all themes
  • Active Line: Removed distracting highlight (gutter indicator is sufficient)

Project Settings Header

  • Matches the simple header pattern used in Context and Memory views
  • Uses bg-glass backdrop-blur-md styling

Sidebar

  • "Settings" renamed to "Global Settings" for clarity
  • "Project Settings" appears in its own section with a separator line above it

Files Changed

New Files (9)

apps/ui/src/routes/project-settings.tsx
apps/ui/src/components/views/project-settings-view/
├── index.ts
├── project-settings-view.tsx
├── project-identity-section.tsx
├── project-theme-section.tsx
├── worktree-preferences-section.tsx
├── config/navigation.ts
├── hooks/index.ts
├── hooks/use-project-settings-view.ts
└── components/project-settings-navigation.tsx

Modified Files (13)

apps/ui/src/components/layout/sidebar/hooks/use-navigation.ts  # Added project settings as standalone section
apps/ui/src/components/layout/sidebar/components/sidebar-footer.tsx  # Renamed "Settings" to "Global Settings"
apps/ui/src/components/layout/sidebar/components/sidebar-navigation.tsx  # Added separator for label-less sections
apps/ui/src/components/ui/shell-syntax-editor.tsx              # Improved contrast
apps/ui/src/components/views/settings-view.tsx                 # Simplified (removed project settings)
apps/ui/src/components/views/settings-view/appearance/         # Theme only (removed project name/icon)
apps/ui/src/components/views/settings-view/worktrees/          # Global toggle only
apps/ui/src/components/views/settings-view/config/navigation.ts
apps/ui/src/components/views/settings-view/components/settings-navigation.tsx
apps/ui/src/lib/http-api-client.ts                             # Added missing response fields
apps/ui/src/store/app-store.ts                                 # Added useWorktreesByProject state
libs/types/src/settings.ts                                     # Added projectSettings shortcut

Test Plan

  • Navigation: Open a project → Verify "Project Settings" appears below Tools with separator
  • Keyboard shortcut: Press Shift+S → Opens Project Settings
  • Global Settings label: Verify bottom settings link shows "Global Settings"
  • No project: Navigate to /project-settings without a project → Shows "No Project Selected" message
  • Identity section: Change project name/icon → Persists after refresh
  • Theme section:
    • Shows current theme (inherited from global initially)
    • Change theme → Project uses new theme
    • Change global theme → Project still uses its override
  • Worktrees section:
    • Shows current worktree isolation setting
    • Toggle → Setting persists after refresh
    • Change global setting → Project still uses its override
  • Init script: Edit, save, delete → All operations work
  • Danger Zone: Delete project → Works correctly
  • Global Settings: No longer shows project-specific options (name, icon, init script settings)
  • Import/Export: Export settings → Project themes are included in projects array

Screenshots

CleanShot 2026-01-16 at 23 30 36@2x CleanShot 2026-01-16 at 23 30 56@2x

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This PR introduces a comprehensive prompt customization system, backlog plan feature for batch feature planning, project-level settings interface, event hooks for automation, enhanced graph visualization with dependency management, ideation dashboard improvements, and developer-facing logging/provider controls across server and UI.

Changes

Cohort / File(s) Summary
Prompt Customization Infrastructure
libs/prompts/src/defaults.ts, libs/prompts/src/merge.ts, libs/prompts/src/index.ts, libs/types/src/prompts.ts, libs/types/src/index.ts, apps/server/src/lib/settings-helpers.ts
Introduces comprehensive prompt customization system with new prompt categories (title generation, issue validation, ideation, app specs, context description, suggestions, task execution); adds merge utilities and resolved types to combine custom and default prompts.
Backlog Plan Feature
apps/server/src/routes/backlog-plan/*, apps/ui/src/lib/electron.ts, apps/ui/src/lib/http-api-client.ts, apps/ui/src/components/views/board-view/dialogs/backlog-plan-dialog.tsx
Implements complete backlog plan generation workflow with server-side state management, plan persistence, apply/clear operations, and UI dialog for creating and reviewing batch feature changes.
Project Settings Interface
apps/ui/src/components/views/project-settings-view/*, apps/ui/src/routes/project-settings.tsx
New project settings view with identity section (name/icon), theme selection, worktree preferences, and danger zone actions.
Event Hooks System
apps/server/src/services/event-hook-service.ts, apps/ui/src/components/views/settings-view/event-hooks/*
Introduces event-driven hooks system supporting shell commands and HTTP requests triggered by auto-mode events, with configuration UI and execution logic.
Graph View & Dependency Management
apps/ui/src/components/views/graph-view/*, apps/ui/src/components/ui/dependency-selector.tsx, apps/ui/src/components/views/board-view/hooks/use-board-actions.ts, graph-layout-bug.md
Enhances graph visualization with layout computation, search filtering, dependency selection UI, circular dependency prevention, and bidirectional dependency management.
Ideation Dashboard
apps/ui/src/components/views/ideation-view/*, apps/server/src/services/ideation-service.ts
Updates ideation dashboard with discard-all workflow, dynamic prompt customization, visual state indicators, and improved UX for suggestion management.
Server Route & Service Updates
apps/server/src/routes/app-spec/*, apps/server/src/routes/context/routes/*, apps/server/src/routes/features/routes/*, apps/server/src/routes/github/routes/*, apps/server/src/routes/suggestions/*, apps/server/src/services/auto-mode-service.ts, apps/server/src/routes/running-agents/routes/index.ts
Updates multiple route handlers and services to use dynamic prompt customization via getPromptCustomization, wires SettingsService parameters, and integrates backlog plan status into running agents view.
Settings & Developer Features
apps/ui/src/components/views/settings-view/*, apps/ui/src/hooks/use-settings-*.ts, apps/server/src/routes/settings/routes/update-global.ts, libs/types/src/settings.ts
Introduces server log level control, HTTP request logging toggle, provider disabling, event hooks configuration, and synchronized settings across client/server.
Terminal & Service Improvements
apps/server/src/services/terminal-service.ts, apps/server/src/services/claude-usage-service.ts
Adds platform-aware PTY termination logic using SIGTERM on Unix and direct kill on Windows.
Type System Extensions
libs/types/src/cursor-models.ts, libs/types/src/settings.ts
Adds cursor GPT-5.2 Codex models, ServerLogLevel type, EventHook types, and extends GlobalSettings with new configuration fields.
UI Components & Utilities
apps/ui/src/components/ui/json-syntax-editor.tsx, apps/ui/src/components/ui/shell-syntax-editor.tsx, apps/ui/src/components/views/settings-view/prompts/*, apps/ui/src/components/layout/project-switcher/*
New CodeMirror-based JSON/shell syntax editors, prompt field UI components, import/export dialog, and wiki navigation in project switcher.
Board & Selection Updates
apps/ui/src/components/views/board-view/board-header.tsx, apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx, apps/ui/src/components/views/board-view/components/selection-action-bar.tsx, apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx, apps/ui/src/components/views/board-view/dialogs/edit-feature-dialog.tsx
Extends board view to support waiting_approval selection mode, bulk verify action, pending plan display, and dependency management in feature dialogs.
Settings Views Reorganization
apps/ui/src/components/views/settings-view.tsx, apps/ui/src/components/layout/sidebar.tsx, apps/ui/src/components/layout/sidebar/components/sidebar-footer.tsx
Removes per-project theme logic from settings, consolidates to global-only theming, moves project settings to dedicated route, adds event hooks and developer sections.
Docker & Documentation
docker-compose.yml, docker-compose.dev.yml, docker-compose.dev-server.yml, docs/docker-isolation.md, README.md, start-automaker.sh
Updates Docker environment configuration, removes docker-isolation guide, adds new interactive TUI launcher script with multi-mode support.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant UI as Board View
    participant Server as Server API
    participant Claude as Claude API
    participant Disk as Disk Storage

    User->>UI: Open backlog plan dialog
    UI->>UI: Load saved plan (if exists)
    User->>UI: Enter plan description
    User->>UI: Click "Generate Plan"
    
    UI->>Server: POST /api/backlog-plan/generate
    Server->>Server: Record running details
    Server->>Claude: Stream plan generation
    Claude-->>Server: Plan response
    Server->>Disk: Save plan to disk
    Server->>UI: Send backlog_plan_complete event
    
    UI->>UI: Load saved plan
    UI->>User: Display plan for review
    User->>UI: Click "Apply Changes"
    UI->>Server: POST /api/backlog-plan/apply
    Server->>Server: Parse and apply changes
    Server->>Disk: Clear saved plan
    Server->>UI: Confirm success
    UI->>User: Refresh board with changes
Loading
sequenceDiagram
    participant System as System
    participant Emitter as Event Emitter
    participant EventHookService as Event Hook Service
    participant Store as Settings Store
    participant Shell as Shell/HTTP
    participant User as User Webhook

    System->>Emitter: Emit autoMode event (feature_success)
    Emitter->>EventHookService: Event received
    EventHookService->>Store: Load global settings
    EventHookService->>Store: Filter enabled hooks by trigger
    
    par Shell Hooks
        EventHookService->>Shell: Execute shell command
        Shell-->>EventHookService: Return stdout/stderr
        EventHookService->>EventHookService: Log result
    and HTTP Hooks
        EventHookService->>User: POST with substituted variables
        User-->>EventHookService: Response
        EventHookService->>EventHookService: Log result
    end
    
    EventHookService->>EventHookService: Complete all hooks
Loading
sequenceDiagram
    participant UI as Graph Canvas
    participant Hook as useGraphLayout Hook
    participant Dagre as Dagre Library
    participant ReactFlow as React Flow

    UI->>Hook: Mount with nodes & edges
    Hook->>Hook: Compute structureKey from nodes+edges
    Hook->>Dagre: Compute hierarchical layout
    Dagre-->>Hook: Positioned nodes & edges
    Hook->>Hook: Increment layoutVersion
    Hook->>Hook: Cache positions by structureKey
    Hook->>UI: Return layoutedNodes, layoutedEdges, layoutVersion
    
    UI->>ReactFlow: Apply layout
    ReactFlow->>ReactFlow: Render graph with positions
    
    User->>UI: Update dependencies
    UI->>Hook: Edges changed
    Hook->>Hook: Detect structureKey change
    Hook->>Dagre: Recompute layout
    Hook->>UI: Return new layout + updated layoutVersion
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested labels

Enhancement, scope: ui

Suggested reviewers

  • Shironex
  • webdevcody

Poem

A rabbit hops through prompts so grand,
With backlog plans and hooks that stand,
Settings dance in project view,
Graph layouts sparkle, fresh and new,
Dependencies weave their careful thread,
hop hop — tomorrow's code is led! 🐰✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a dedicated Project Settings screen that separates project-specific settings from global application settings.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @stefandevo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the application's settings architecture by introducing a dedicated Project Settings screen, thereby clearly distinguishing between global and project-specific configurations. This change aims to eliminate user confusion regarding the scope of various settings and provides a more intuitive customization experience. The new design supports a robust inheritance model, allowing projects to override global defaults for key functionalities like themes and Git worktree isolation, while also resolving critical bugs related to how these settings were previously handled. Additionally, the PR introduces a new event hook system for custom automation, an interactive TUI launcher for improved startup, and various UI/UX enhancements across the application, including the graph view and feature management workflows.

Highlights

  • Dedicated Project Settings Screen: Introduced a new screen accessible from the sidebar (or Shift+S) to clearly separate project-specific settings from global application settings, improving user experience by clarifying which settings apply where.
  • Clear Settings Separation: Project-specific settings like name, icon, theme, Git worktree isolation, init scripts, and project deletion are now managed under Project Settings. Global settings (e.g., global theme, feature defaults, API keys) remain in Global Settings.
  • Consistent Global → Project Override Pattern: Implemented a clear inheritance model for Theme and Worktree Isolation, allowing projects to override global defaults without affecting other projects or the global setting itself.
  • Bug Fixes for Settings Persistence: Resolved issues where changing the global theme would incorrectly overwrite project-specific themes and where project-specific worktree settings were not persisting after refresh.
  • Enhanced Prompt Customization: Expanded prompt customization options to cover more AI features, including title generation, issue validation, ideation, app specification, context description, suggestions, and detailed task execution prompts.
  • New Interactive TUI Launcher: Added a user-friendly interactive terminal UI launcher script (start-automaker.sh) for easier startup and mode selection, including pre-flight checks and history.
  • Dynamic Server Logging Configuration: Implemented runtime configuration for server log level and HTTP request logging, allowing users to adjust verbosity and request logging via settings without restarting the server.
  • Event Hooks System: Introduced a new Event Hooks service and settings section, enabling users to configure custom shell commands or HTTP webhooks to trigger on specific system events (e.g., feature success/error, auto-mode completion).
  • Improved Graph View Layout and Interactivity: Addressed a graph layout bug, implemented viewport persistence, added a search filter, and enabled direct dependency removal from the graph view. Also updated status mapping to treat 'completed' features as 'verified' for display.
  • Bulk Actions for Features: Enhanced the Kanban board with bulk delete and bulk update (including bulk verify for 'waiting_approval' features) capabilities, improving efficiency for managing multiple features.
  • Advanced Dependency Management: Introduced a new DependencySelector UI component for adding parent and child dependencies to features, including circular dependency detection.
  • Settings Import/Export: Added a new dialog for importing and exporting all global settings as a JSON file, facilitating easy transfer of configurations between installations.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant updates across the application, primarily focusing on enhanced configuration, improved user experience, and expanded functionality. Key changes include updating the README.md with new Node.js requirements, simplified authentication instructions, and details for a new interactive TUI launcher script. The server-side code now supports runtime-configurable logging levels and HTTP request logging, and integrates a new EventHookService for custom actions on system events. Prompt customization has been greatly expanded, allowing users to modify a wider range of AI prompts for features like title generation, issue validation, ideation, app specification, context description, and task execution. The backlog planning feature now includes persistence, allowing plans to be saved, loaded, and cleared, and its status is reflected in the running agents view. Dependency management for features has been enhanced with a new UI component and logic to prevent circular dependencies. The UI introduces a dedicated 'Project Settings' view for per-project configuration of identity, theme, and worktree preferences, separating these from global settings. The graph view now includes search functionality and improved layout stability, along with a new 'Plan' button. The ideation dashboard received UI/UX improvements, including bulk discard functionality. Several internal refactorings were made, such as consolidating ptyProcess.kill logic into a helper function for cross-platform compatibility, and optimizing bulk feature operations with batch processing. Docker configurations were updated to reflect the new Node.js version and authentication changes. Overall, these changes aim to provide a more robust, customizable, and user-friendly development experience.

@stefandevo stefandevo changed the base branch from main to v0.12.0rc January 16, 2026 21:37
@stefandevo
Copy link
Collaborator Author

@coderabbitai review this please

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

Tip

For best results, initiate chat on the files or code changes.

@stefandevo, I'll review this comprehensive PR that introduces separate project and global settings. This is a significant architectural improvement! Here's my detailed review:

🎯 Overall Architecture - Excellent Design

The separation of global and project settings is well-architected. The Global → Project Override pattern for theme and worktree isolation is intuitive and follows common configuration paradigms.

Strengths

  1. Clear Separation of Concerns: Project-specific settings (.automaker/settings.json) vs. global settings is well-defined
  2. Consistent UI Patterns: New Project Settings navigation mirrors the existing Settings view structure
  3. Proper State Management: Settings persistence through both store and HTTP API is well-coordinated
  4. Keyboard Navigation: Shift+S shortcut for project settings is consistent with the app's navigation patterns

🔍 Areas for Review

1. Settings Migration & Backwards Compatibility

In apps/ui/src/hooks/use-settings-migration.ts, new fields are added (disabledProviders, serverLogLevel, enableRequestLogging), but I don't see explicit migration logic for existing users. Consider:

  • What happens to users with existing projects when they upgrade?
  • Should there be a migration step to initialize .automaker/settings.json for existing projects?

2. Race Conditions in Settings Loading

In apps/ui/src/components/views/project-settings-view/worktree-preferences-section.tsx (lines ~100-150):

// Multiple sequential API calls without proper loading states coordination

Consider consolidating settings load into a single endpoint or adding proper request queuing to avoid race conditions when rapidly switching between projects.

3. Error Handling in Project Settings

In project-identity-section.tsx, the custom icon upload error handling could be more robust:

  • File size validation happens client-side, but server-side validation results aren't shown to users
  • Consider adding retry logic for failed uploads
  • Network errors during save should preserve user input

4. Theme Override Persistence

The bug fix mentioned in the PR summary is good, but verify:

  • In apps/ui/src/store/app-store.ts, when useWorktreesByProject is updated, ensure theme overrides are also properly scoped per project
  • Test scenario: Switch between projects with different theme overrides rapidly

5. Dependency Management

New dependencies added in board-view/dialogs/add-feature-dialog.tsx and edit-feature-dialog.tsx:

  • The childDependencies feature is powerful but complex
  • Consider adding validation to prevent orphaned dependencies when features are deleted
  • Circular dependency detection is present, but test edge cases thoroughly

6. Settings Sync Performance

In use-settings-sync.ts, settings are synced on every change:

// Multiple fields now trigger full settings sync
serverLogLevel, enableRequestLogging, disabledProviders, eventHooks

Consider debouncing settings updates to reduce server load, especially for fields like enableRequestLogging that might be toggled frequently during debugging.

🐛 Potential Issues

High Priority:

  1. Shell Script Injection - In event-hook-service.ts (line ~150-180), shell commands from event hooks are executed:

    • Ensure proper escaping/sanitization of variables substituted into shell commands
    • Consider using a safer subprocess API with argument arrays instead of shell strings
  2. Prompt Customization Injection - Multiple new prompt fields accept user input that's inserted into AI prompts. Validate/sanitize to prevent prompt injection attacks.

Medium Priority:

  1. Large File Handling - Init script editor in worktree-preferences-section.tsx loads entire file content. Consider size limits or streaming for large scripts.

  2. Concurrent Modifications - Project settings can be modified from multiple places (UI, API, file system). Add file watching or optimistic locking.

🎨 Code Quality Suggestions

  1. TypeScript Strictness: Some new files use any types. Consider strengthening types, especially in HTTP client responses.

  2. Component Size: worktree-preferences-section.tsx is 450+ lines. Consider splitting into sub-components (InitScriptEditor, PreferenceToggles, etc.).

  3. Magic Strings: Several files use string literals like 'identity', 'theme', etc. Consider using enums or constants.

  4. Duplicate Logic: Settings persistence logic is duplicated across multiple sections. Consider a shared useProjectSetting hook.

🧪 Testing Recommendations

  1. Test project switching with different override combinations
  2. Test rapid theme changes while auto-mode is running
  3. Test event hooks with various shell commands and HTTP endpoints
  4. Test init script save/delete with concurrent modifications
  5. Test dependency management with complex feature graphs

📝 Documentation Suggestions

  1. Add inline documentation for the settings hierarchy and override resolution
  2. Document the event hook variable substitution system with examples
  3. Add migration guide for users upgrading from previous versions
  4. Document the .automaker/settings.json schema

🎉 Conclusion

This is a well-executed feature with solid architecture. The separation of concerns is clean, and the UI is consistent with existing patterns. Address the security concerns around shell command execution and prompt injection, and consider the performance optimizations for settings sync. Great work overall!

Priority: Address the shell injection vulnerability in event hooks service before merging.

@stefandevo
Copy link
Collaborator Author

@coderabbitai Can you review ONLY the file changes from this PR and know that we moved existing code to other places (global settings to project settings).

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

Tip

For best results, initiate chat on the files or code changes.

@stefandevo, understood! I'll focus specifically on the project/global settings separation and how code was moved/reorganized. Let me provide a more targeted review:

🎯 Core Architecture Review: Project vs Global Settings Split

What Was Moved Successfully

From appearance-section.tsxproject-identity-section.tsx + project-theme-section.tsx:

  • Project name and icon management → correctly moved to project settings
  • Theme selection UI → properly split (global theme in settings, project override in project settings)
  • Custom icon upload → cleanly extracted to project identity

From worktrees-section.tsxworktree-preferences-section.tsx:

  • Init script editor and preferences → correctly moved to project-specific settings
  • Preference toggles (show indicator, auto-dismiss, delete branch default) → properly scoped to project

🔍 Separation Architecture Review

1. Override Mechanism (Global → Project Pattern)

// In app-store.ts - NEW
useWorktreesByProject: Record<string, boolean | undefined>
getEffectiveUseWorktrees: (projectPath: string) => boolean

Well-designed: The override system properly falls back to global defaults when project override is undefined or null.

Issue Found: In project-theme-section.tsx, the theme override logic uses a special sentinel value:

const USE_GLOBAL_THEME = '' as const;

This is inconsistent with the worktree override pattern which uses null for "use global". Consider using null for both for consistency.

2. Settings Persistence

  • Global: Still in localStorage + /api/settings/global
  • Project: New .automaker/settings.json via /api/settings/project
  • Separation is clean: No cross-contamination observed

Issue Found: In worktree-preferences-section.tsx (lines 100-140), multiple sequential API calls are made:

// Loads project settings
await api.Settings.getProject(project.path)
// Then loads init script
await api.Worktree.getInitScript(project.path)

Consider a single endpoint or proper loading coordination to avoid race conditions during rapid project switching.

🐛 Bugs in the Separation Logic

1. Theme Override Persistence Bug (claimed as fixed)
Looking at board-view.tsx and graph-view-page.tsx:

  • Bug fix mentioned: "prevent global theme changes from overwriting project overrides"
  • Fix appears to be in the store logic where setProjectTheme is now separate from setTheme
  • Verified: The separation correctly prevents global changes from affecting project overrides

2. Worktree Isolation Override Loading
In worktree-preferences-section.tsx (line ~70-80):

const effectiveUseWorktrees = projectSettings?.useWorktrees ?? globalSettings.useWorktrees ?? false;

This logic duplicates getEffectiveUseWorktrees from the store. The component should use the store method instead for consistency.

📦 New Project Settings Structure

Navigation (PROJECT_SETTINGS_NAV_ITEMS):

  • Identity ✅
  • Worktrees ✅
  • Theme ✅
  • Danger Zone (Delete Project) ✅

Routing: /project-settings with Shift+S shortcut ✅

Issue: The sidebar now has TWO settings entries:

  1. Settings (global) - in footer
  2. Project Settings - in Tools section

This could be confusing. Consider:

  • More distinct icons or labels
  • Tooltip clarification: "Project Settings (current project)" vs "Global Settings (application)"

🔄 Migration & Backwards Compatibility

Concern: Existing projects upgrading to this version:

  • No .automaker/settings.json will exist initially
  • Code appears to handle this gracefully (falls back to global settings) ✅
  • But: No migration to initialize project settings with current global values

Recommendation: Add a one-time migration that:

  1. Detects projects without .automaker/settings.json
  2. Offers to initialize with current global theme/worktree settings
  3. Or clearly documents that projects start with "use global" by default

🎨 UI/UX of the Separation

Project Settings View:

  • Mobile-responsive navigation ✅
  • Sections well-organized ✅
  • Danger Zone appropriately styled ✅

Global Settings View:

  • Successfully simplified (removed project-specific UI) ✅
  • Retained all global settings ✅

Minor UI Issue: In project-context-menu.tsx, the theme submenu now includes a "Use Global Theme" option. The empty string sentinel (USE_GLOBAL_THEME = '') is inconsistent. Use null instead.

🔐 Separation of Concerns

What stayed global (correct):

  • API keys and providers ✅
  • MCP servers ✅
  • Model defaults ✅
  • Prompt customization ✅
  • Terminal/keyboard/audio settings ✅
  • Account/developer settings ✅

What moved to project (correct):

  • Project name/icon ✅
  • Theme override ✅
  • Worktree isolation override ✅
  • Init script and preferences ✅
  • Delete project action ✅

No concerns - the separation is logical and complete.

📊 Store Changes for Override System

In app-store.ts:

// NEW per-project tracking
useWorktreesByProject: Record<string, boolean | undefined>
setProjectUseWorktrees: (projectPath: string, useWorktrees: boolean | null) => void
getEffectiveUseWorktrees: (projectPath: string) => boolean

Well-implemented: The override map and effective value computation are clean.

Minor optimization: Consider adding clearProjectOverrides(projectPath) method for cleanup when projects are deleted or reset.

🎯 Summary: Separation-Specific Issues

Critical:

None - the separation logic is sound.

Important:

  1. Inconsistent override sentinel: Theme uses '', worktrees use null - standardize on null
  2. Duplicate logic: worktree-preferences-section.tsx reimplements getEffectiveUseWorktrees instead of using store method
  3. Race conditions: Multiple sequential API calls in project settings loading - consolidate or add proper coordination

Nice to Have:

  1. Migration assistant for existing projects
  2. More distinct labels for two settings entries in sidebar
  3. Store cleanup method for deleted projects

What Was Done Well

  1. Clean architectural separation of global vs project concerns
  2. Override pattern is intuitive and consistent
  3. UI is well-organized and responsive
  4. Persistence layer properly separated
  5. Backwards compatibility handled gracefully
  6. No code duplication between moved sections

Overall: The separation is architecturally sound. The main issues are minor consistency problems (sentinel values, duplicate logic) that can be easily addressed.

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

Tip

For best results, initiate chat on the files or code changes.

@stefandevo, absolutely! Let me provide a focused review on the actual changes rather than relocated code.

🎯 Understanding the Refactoring

I see the architectural split:

  • Global Settings retained: AI providers, model defaults, prompts, MCP servers, terminal, shortcuts, account
  • Project Settings (new route /project-settings): Identity, theme override, worktree override, init script, danger zone
  • Moved but not changed: Project name/icon, project theme selector, worktree toggle, project deletion

🆕 Actual New Features to Review

1. Per-Project Settings Storage (.automaker/settings.json)

New fields in project settings:

// apps/ui/src/lib/http-api-client.ts
showInitScriptIndicator?: boolean
autoDismissInitScriptIndicator?: boolean  
defaultDeleteBranchWithWorktree?: boolean

✅ Good: Clean separation, stored per-project
⚠️ Consider: What happens when .automaker/settings.json is corrupted or manually edited?

2. Event Hooks System (Entirely New)

apps/server/src/services/event-hook-service.ts - 316 new lines

🔴 Critical Security Issue:

// Line ~150-180: Shell command execution with variable substitution
private substituteVariables(template: string, context: HookContext): string
  • User-provided commands are executed via shell
  • Variable substitution could allow injection if context values aren't sanitized
  • Action Needed: Validate/escape context values before substitution, or use parameterized execution

Recommendation: Use execFile with argument array instead of shell string interpolation.

3. Developer Settings (New Global Section)

apps/ui/src/components/views/settings-view/developer/developer-section.tsx

✅ Good additions:

  • serverLogLevel: Dynamic log level control
  • enableRequestLogging: Toggle HTTP request logs

Question: Do these settings require server restart, or are they hot-reloaded? The code suggests hot-reload via apps/server/src/routes/settings/routes/update-global.ts calling setLogLevel() and setRequestLoggingEnabled(), which is excellent.

4. Import/Export Dialog (New Global Feature)

apps/ui/src/components/views/settings-view/components/import-export-dialog.tsx

✅ Strengths:

  • JSON syntax validation before save
  • Loads/saves via API (no direct file access)

⚠️ Concern:

// No schema validation - users can inject arbitrary fields
await api.Settings.updateGlobal(parsed)

Consider validating against a known schema before accepting the import.

5. Provider Visibility Toggles (New Feature)

apps/ui/src/store/app-store.ts - disabledProviders: ModelProvider[]

✅ Clean implementation: Centralized in store, respected across model selectors

Minor Issue: In apps/ui/src/components/views/board-view/shared/model-selector.tsx, filtering logic is duplicated. Consider extracting to a shared hook.

6. Prompt Customization Expansion

Added 8 new prompt categories with merge utilities:

  • Title Generation, Issue Validation, Ideation, App Spec, Context Description, Suggestions, Task Execution

✅ Excellent: Centralized defaults, merge patterns are consistent

⚠️ Prompt Injection Risk: User-provided prompts are inserted into AI calls without validation. While this is somewhat expected for customization, consider:

  • Warning users about the risks
  • Sanitizing common injection patterns
  • Documenting that custom prompts bypass safety checks

7. Backlog Plan Persistence

apps/server/src/routes/backlog-plan/common.ts - New save/load/clear functions

✅ Good: Stored per-project, cleared after apply
Question: What's the retention policy? Should old plans be auto-cleaned?

8. Per-Project Worktree Override

apps/ui/src/store/app-store.ts - useWorktreesByProject: Record<string, boolean | undefined>

✅ Excellent: Global default → Project override pattern implemented correctly

Verify: When a project is deleted, is its entry in useWorktreesByProject cleaned up? I don't see cleanup in the delete flow.

🔄 Integration Points

Settings Sync Changes

apps/ui/src/hooks/use-settings-sync.ts - Added fields:

serverLogLevel, enableRequestLogging, disabledProviders, eventHooks

⚠️ Performance: Every change triggers a full sync. Consider debouncing, especially for enableRequestLogging which might be toggled frequently during debugging.

Shell Editor Contrast Fix

apps/ui/src/components/ui/shell-syntax-editor.tsx

- bg-muted/30 → bg-background
- active line highlight removed

✅ Good fix for readability, aligns with user feedback.

🐛 Actual Bugs Fixed

  1. Theme Override Bug:

    • Before: Global theme changes overwrote project overrides
    • After: useWorktreesByProject pattern prevents this
    • ✅ Verified in store logic
  2. Worktree Isolation Persistence:

    • Now loads from server when Project Settings opens
    • ✅ Good fix

🎨 Code Quality - New Code Only

Strong Points:

  • Consistent navigation patterns between Settings and Project Settings
  • Clean separation of concerns
  • Good use of TypeScript for new types

Improvements Needed:

  1. worktree-preferences-section.tsx (450 lines) - Extract InitScriptEditor sub-component
  2. Event hooks use any in some places - strengthen types
  3. Some magic strings - use constants/enums

🧪 Testing Focus Areas

Focus testing on the new functionality:

  1. Event hooks with shell injection attempts
  2. Import/Export with malformed JSON
  3. Provider toggle state across page refreshes
  4. Per-project worktree override persistence
  5. Backlog plan save/load/clear flow
  6. Init script editor with large files
  7. Project settings isolation (multiple projects)

🚨 Must Fix Before Merge

Critical: Shell command injection in event-hook-service.ts

// Current approach is unsafe
await exec(shellCommand) // User-controlled string

// Recommended approach
import { execFile } from 'node:child_process'
await execFile(command, args) // Parameterized

Conclusion

The architectural refactoring (moving code) is clean and well-executed. The new features are solid with a few security concerns:

  1. Fix immediately: Event hooks shell injection vulnerability
  2. Consider: Prompt injection risks (document or mitigate)
  3. Nice to have: Import/Export schema validation, settings sync debouncing

The separation of global vs. project settings is a significant UX improvement and the implementation is mostly sound!

@stefandevo
Copy link
Collaborator Author

It seems CodeRabbit did take existing code or other code from the target branch into account for the review. I fixed the reviews that where valid based upon the changes in the file.

This PR introduces a new dedicated Project Settings screen accessible from
the sidebar, clearly separating project-specific settings from global
application settings.

- Added new route `/project-settings` with dedicated view
- Sidebar navigation item "Settings" in Tools section (Shift+S shortcut)
- Sidebar-based navigation matching global Settings pattern
- Sections: Identity, Worktrees, Theme, Danger Zone

**Moved to Project Settings:**
- Project name and icon customization
- Project-specific theme override
- Worktree isolation enable/disable (per-project override)
- Init script indicator visibility and auto-dismiss
- Delete branch by default preference
- Initialization script editor
- Delete project (Danger Zone)

**Remains in Global Settings:**
- Global theme (default for all projects)
- Global worktree isolation (default for new projects)
- Feature Defaults, Model Defaults
- API Keys, AI Providers, MCP Servers
- Terminal, Keyboard Shortcuts, Audio
- Account, Security, Developer settings

Both Theme and Worktree Isolation now follow a consistent override pattern:
1. Global Settings defines the default value
2. New projects inherit the global value
3. Project Settings can override for that specific project
4. Changing global setting doesn't affect projects with overrides

- Fixed: Changing global theme was incorrectly overwriting project themes
- Fixed: Project worktree setting not persisting across sessions
- Project settings now properly load from server on component mount

- Shell syntax editor: improved background contrast (bg-background)
- Shell syntax editor: removed distracting active line highlight
- Project Settings header matches Context/Memory views pattern

- `apps/ui/src/routes/project-settings.tsx`
- `apps/ui/src/components/views/project-settings-view/` (9 files)

- Global settings simplified (removed project-specific options)
- Sidebar navigation updated with project settings link
- App store: added project-specific useWorktrees state/actions
- Types: added projectSettings keyboard shortcut
- HTTP client: added missing project settings response fields
- Fix race conditions when rapidly switching projects
  - Added cancellation logic to prevent stale responses from updating state
  - Both project settings and init script loading now properly cancelled on unmount

- Improve error handling in custom icon upload
  - Added toast notifications for validation errors (file type, file size)
  - Added toast notifications for upload success/failure
  - Handle network errors gracefully with user feedback
  - Handle file reader errors
@stefandevo stefandevo force-pushed the feature/project-settings branch from 8399bbb to 6a23e6c Compare January 16, 2026 22:03
@stefandevo
Copy link
Collaborator Author

Response to CodeRabbit Review

Thanks for the detailed review! After careful analysis, I've identified which feedback applies to our actual changes vs. code we didn't modify.

❌ Not in This PR (Should Be Addressed Separately)

The following concerns are about files/features not modified in this PR:

Topic File Notes
Event Hooks Shell Injection event-hook-service.ts Not touched in this PR
Developer Settings developer-section.tsx Not touched in this PR
Import/Export Schema Validation import-export-dialog.tsx Not touched in this PR
Provider Visibility Toggles Different code paths Not touched in this PR
Prompt Customization/Injection Prompt files Not touched in this PR
Backlog Plan Persistence backlog-plan/ routes Not touched in this PR
Settings Sync Debouncing use-settings-sync.ts Not touched in this PR

These are valid concerns but should be addressed in separate PRs by the respective feature authors.

✅ Verified Working in This PR

Item Status
Shell Editor Contrast Fix ✅ Changed bg-muted/30bg-background, removed distracting active line highlight
Theme Override Bug ✅ Global theme changes no longer overwrite project-specific overrides
Worktree Isolation Persistence ✅ Settings load from server on mount with race condition handling (cancellation logic)

⚠️ Minor Concerns (No Action Needed)

1. useWorktreesByProject cleanup on project deletion

The entry stays in the store after deletion. However:

  • This follows the same pattern as existing settings (showInitScriptIndicatorByProject, defaultDeleteBranchByProject, etc.) - we didn't introduce this pattern
  • Projects can be restored from trash, so keeping settings is arguably correct behavior
  • Stale entries cause no functional issues
  • Per-project settings in .automaker/settings.json are deleted with the project folder

2. File size of worktree-preferences-section.tsx (478 lines)

Valid suggestion to extract InitScriptEditor as a sub-component. This is a "nice-to-have" refactoring that can be addressed in a follow-up PR if desired.


Conclusion: No fixes required for this PR. All critical security concerns mentioned are in unrelated files that should be addressed separately.

…tings

- Move "Settings" from Tools section to Project section in sidebar
- Rename bottom settings link from "Settings" to "Global Settings"
- Update keyboard shortcut description accordingly
- Remove Project Settings from Project section
- Add Project Settings as standalone section below Tools/GitHub
- Use empty label for visual separation without header
- Add horizontal separator line above sections without labels
- Rename to "Project Settings" for clarity
- Keep "Global Settings" at bottom of sidebar
@webdevcody webdevcody merged commit 5407e1a into AutoMaker-Org:v0.12.0rc Jan 16, 2026
5 of 6 checks passed
@stefandevo stefandevo deleted the feature/project-settings branch January 18, 2026 22:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants