# Application Logging Configuration
Logging:
  LogLevel:
    Default: Information
    Microsoft.AspNetCore: Warning

Telemetry:
  Enabled: true
  EnableTracing: true
  EnableMetrics: true
  ServiceName: "PCode.Web"
  Grains:
    Enabled: true
    MonitoredGrainTypes: []
    ExcludedGrainTypes: []
    MonitoredMethods: []
  Console:
    Enabled: false
  Otlp:
    Enabled: false
    Endpoint:
    Headers:
    Protocol: "grpc"
    TimeoutMilliseconds: 10000

# Serilog Structured Logging Configuration
# Note: Serilog is configured programmatically in PCodeWebHostBootstrap with environment-adaptive settings.
# This section is provided for reference and potential future configuration-based setup.
#
# Environment-Adaptive Behavior:
# - Development (non-container): Console + File dual output for debugging
# - Production (non-container): File only for persistent logging
# - Container (any environment): Compact JSON Lines to stdout for log aggregation
#
# Container Detection (automatically performed in PCodeWebHostBootstrap):
# - Primary: Checks for /.dockerenv file (Docker-specific)
# - Fallback: Analyzes /proc/1/cgroup for docker/containerd/kubepods strings
# - Default: Non-container mode if detection fails
#
Serilog:
  # Minimum log level (can be overridden in environment-specific files)
  MinimumLevel:
    Default: Debug
    # Log level overrides for specific namespaces
    Override:
      Microsoft.EntityFrameworkCore: Warning
      Microsoft: Warning
      System: Warning
      Volo: Warning
      Orleans: Warning
      PCode.Orleans.Storage: Warning
      PCode.ClaudeHelper.AcpImp: Warning

  # Non-container file sinks keep hourly rolling and also roll within the same hour
  # once a single file reaches the configured size limit.
  #
  # The retained data budget is applied per file sink:
  # - logs/app.log
  # - logs/notice/app.log (production non-container only)
  #
  # Default semantics:
  # - FileSizeLimitBytes: 1 MB per rolled file
  # - RetainedDataLimitBytes: 10 MB retained per sink
  # - retainedFileCountLimit is derived as ceil(budget / file size) = 10 files
  FileRolling:
    FileSizeLimitBytes: 1048576
    RetainedDataLimitBytes: 10485760

# ============================================================================
# Server URL Configuration
# ============================================================================
# Option 1: Kestrel Endpoints (Recommended for production)
# Uncomment and configure Kestrel:Endpoints for production deployments
# This provides full control over HTTPS, certificates, and multiple endpoints.
#
# Kestrel:
#   Endpoints:
#     # HTTP endpoint
#     Http:
#       Url: "http://0.0.0.0:5000"
#
#     # HTTPS endpoint with development certificate
#     Https:
#       Url: "https://0.0.0.0:5001"
#       Certificate:
#         Subject: "localhost"
#         Store: "My"
#         StoreLocation: "LocalMachine"
#         AllowInvalid: true
#
#     # HTTPS endpoint with specific certificate file (pfx)
#     # HttpsPfx:
#     #   Url: "https://example.com:443"
#     #   Certificate:
#     #     Path: "/path/to/certificate.pfx"
#     #     Password: "your-password"
#
#     # IPv6 endpoint example
#     # HttpIPv6:
#     #   Url: "http://[::]:5000"
#
#     # Specific IP binding example
#     # HttpSpecificIP:
#     #   Url: "http://192.168.1.100:5000"

# Option 2: Simple URLs configuration (Fallback)
# Semicolon-separated list of URLs for HTTP and HTTPS endpoints.
# This is simpler but doesn't support certificate configuration.

# Option 3: Environment Variable (Alternative)
# Set ASPNETCORE_URLS environment variable to override configuration.
# Example: ASPNETCORE_URLS="http://0.0.0.0:5000;https://0.0.0.0:5001"

# Configuration Priority:
# 1. Kestrel:Endpoints (highest priority)
# 2. Urls configuration
# 3. ASPNETCORE_URLS environment variable
# 4. Default: http://localhost:5000

# Migration Guide:
# To migrate from Urls to Kestrel:Endpoints:
# 1. Uncomment Kestrel:Endpoints section above
# 2. Copy your URLs from the Urls key to individual endpoint entries
# 3. Add certificate configuration for HTTPS endpoints
# 4. Comment out or remove the Urls key
# ============================================================================

# Allowed hosts for the application
AllowedHosts: "*"

PCodeWebHost:
  # Configuration file hot reload is disabled by default to avoid recursive watcher pressure
  # on large development worktrees. Override to true in a local or environment-specific file
  # only when you explicitly need live appsettings reload while the host is running.
  EnableConfigurationReloadOnChange: false

# ============================================================================
# Remote Deployment Configuration Examples
# ============================================================================
# The application now supports remote deployment without address restrictions.
# To enable remote access, use one of the following methods:
#
# 1. Override Urls in appsettings.Production.yml:
#    Urls: "http://0.0.0.0:35167"
#
# 2. Use Kestrel:Endpoints for more control:
#    Kestrel:
#      Endpoints:
#        Http:
#          Url: "http://0.0.0.0:35167"
#
# 3. Use environment variable:
#    export ASPNETCORE_URLS="http://0.0.0.0:35167"
#
# SECURITY RECOMMENDATION:
# In production, use a reverse proxy (Nginx/IIS) in front of this application
# for proper access control, SSL termination, and security hardening.
# Do not expose the application directly to the internet without protection.
# ============================================================================

# Startup Banner Configuration
StartupBanner:
  Enabled: true               # Whether to display the startup banner
  CheckEnvironment: true      # Whether to check environment dependencies
  ShowOrleansInfo: true       # Whether to display Orleans Silo information
  StrictMode: false           # If true, application will not start if required tools are missing

App:
  HagipowerGameDriver:
    Enabled: true
    ProbeIntervalSeconds: 15
    AckWindowSeconds: 15
    MinConsumePowerM: 1000000
    MaxConsumePowerM: 3000000
    AdventureEntryCostPower: 1000000
  # v1 only affects new execution allocations. Existing balances are not backfilled,
  # and this change does not redistribute previously accumulated public-pool HagiPower.
  HagipowerAllocation:
    HeroBoundPublicPoolRatio: 0.30
  # Minute-level history starts accumulating only after this feature is enabled.
  # It is stored in an independent SQLite file and does not backfill older balances.
  HagipowerStatistics:
    DatabasePath: "./saves/save0/config/hagipower-statistics/hagipower-statistics.db"
    DefaultRange: "24h"
    MaxRangeHours: 168
    UseWalMode: true
    BusyTimeoutMs: 5000
  DocumentSubjectThemes:
    DefaultThemeId: "agents"
    Themes:
      - Id: "agents"
        DisplayNameKey: "documentSubjectThemes.themes.agents.displayName"
        DescriptionKey: "documentSubjectThemes.themes.agents.description"
        SortOrder: 10
        Enabled: true
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
      - Id: "fantasy-adventure"
        DisplayNameKey: "documentSubjectThemes.themes.fantasy-adventure.displayName"
        DescriptionKey: "documentSubjectThemes.themes.fantasy-adventure.description"
        SortOrder: 20
        Enabled: true
        RequiredDlcId: "pcode.turbo-engine"
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
      - Id: "cattle-ranching"
        DisplayNameKey: "documentSubjectThemes.themes.cattle-ranching.displayName"
        DescriptionKey: "documentSubjectThemes.themes.cattle-ranching.description"
        SortOrder: 30
        Enabled: true
        RequiredDlcId: "pcode.turbo-engine"
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
      - Id: "anime-academy"
        DisplayNameKey: "documentSubjectThemes.themes.anime-academy.displayName"
        DescriptionKey: "documentSubjectThemes.themes.anime-academy.description"
        SortOrder: 40
        Enabled: true
        RequiredDlcId: "pcode.turbo-engine"
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
      - Id: "imperial-court"
        DisplayNameKey: "documentSubjectThemes.themes.imperial-court.displayName"
        DescriptionKey: "documentSubjectThemes.themes.imperial-court.description"
        SortOrder: 50
        Enabled: true
        RequiredDlcId: "pcode.turbo-engine"
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
      - Id: "alien-laboratory"
        DisplayNameKey: "documentSubjectThemes.themes.alien-laboratory.displayName"
        DescriptionKey: "documentSubjectThemes.themes.alien-laboratory.description"
        SortOrder: 60
        Enabled: true
        RequiredDlcId: "pcode.turbo-engine"
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
      - Id: "hive-colony"
        DisplayNameKey: "documentSubjectThemes.themes.hive-colony.displayName"
        DescriptionKey: "documentSubjectThemes.themes.hive-colony.description"
        SortOrder: 70
        Enabled: true
        RequiredDlcId: "pcode.turbo-engine"
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
      - Id: "ocean-sphere-colony"
        DisplayNameKey: "documentSubjectThemes.themes.ocean-sphere-colony.displayName"
        DescriptionKey: "documentSubjectThemes.themes.ocean-sphere-colony.description"
        SortOrder: 80
        Enabled: true
        RequiredDlcId: "pcode.turbo-engine"
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
      - Id: "clockwork-workshop"
        DisplayNameKey: "documentSubjectThemes.themes.clockwork-workshop.displayName"
        DescriptionKey: "documentSubjectThemes.themes.clockwork-workshop.description"
        SortOrder: 90
        Enabled: true
        RequiredDlcId: "pcode.turbo-engine"
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
      - Id: "noir-detective"
        DisplayNameKey: "documentSubjectThemes.themes.noir-detective.displayName"
        DescriptionKey: "documentSubjectThemes.themes.noir-detective.description"
        SortOrder: 100
        Enabled: true
        RequiredDlcId: "pcode.turbo-engine"
        PreviewSlotKeys:
          - "workspaceTitle"
          - "agentPlural"
          - "jobPlural"
          - "historyLabel"
          - "fallbackTeamLabel"
# ============================================================================
# Data Directory Configuration
# ============================================================================
# Shared writable runtime base path for MSIX-safe mutable outputs.
# When ServerData:Home is set to an absolute path, backend defaults derive from:
# - logs: {ServerData:Home}/logs
# - data root: {ServerData:Home}/data
# - save root: {ServerData:Home}/saves/save0/...
# Explicit absolute module overrides such as DataDir, shard roots, or connection strings still win.
ServerData:
  # Optional absolute writable base path for mutable runtime outputs.
  # Environment variable: ServerData__Home
  # MSIX deployments should set this to a writable location such as:
  # - Windows: C:/Users/<user>/AppData/Local/HagiCode/runtime
  # Relative values are rejected at startup.
  Home:

# All application data (SQLite databases, logs, etc.) should be stored
# in a dedicated data directory for easier management and backup.
#
# Default data directory paths:
# - Linux/macOS: ./data or /var/pcode/data
# - Windows: .\data or C:\ProgramData\PCode\data
#
# For Docker deployment, mount this directory to a volume:
#   volumes:
#     - pcode_data:/app/data
#
# For production, consider using environment variable:
#   export DataDir=/var/pcode/data
#
# This directory stays system-scoped for assets such as plugins, images, repos, and editor data.
# Save-scoped runtime state is stored under the sibling {RuntimeRoot}/saves/save0 tree:
# - Main database: {RuntimeRoot}/saves/save0/config/hagicode.db
# - Orleans storage: {RuntimeRoot}/saves/save0/data/orleans/grains/*.db
# - Session message shards: {RuntimeRoot}/saves/save0/data/messages/*.db
# ============================================================================

# Application Data Directory
# Base directory for system-scoped runtime assets.
# If ServerData:Home is configured and DataDir stays at the legacy default, the effective data root becomes {ServerData:Home}/data.
# Save-scoped state is routed to the sibling saves/save0 tree automatically.
# Environment variable: DataDir
DataDir: "./data"

# Hero avatar plugins are loaded from dedicated series-plugin roots.
# Bundled plugins stay under the program package at ./plugins/hero-avatars.
# Writable installed plugins and state files default under the effective data root.
HeroAvatarPlugins:
  # Optional. If omitted, resolves to ./plugins/hero-avatars beside the backend host.
  BundledPluginsDirectoryPath: "./plugins/hero-avatars"
  # Optional. If omitted, resolves to {EffectiveDataRoot}/plugins/hero-avatars.
  PluginsDirectoryPath:
  # Optional. If omitted, resolves to {EffectiveDataRoot}/plugins/hero-avatars/state.json.
  StateFilePath:
  # Optional in-memory cache only. Does not persist catalog state across restarts.
  EnableInMemoryCache: true
  # Cache lifetime in seconds for repeated catalog reads within the same process.
  CacheDurationSeconds: 15
  # Version string advertised for bundled series plugin manifests when tests synthesize them.
  BundledPluginVersion: "1.0.0"
  # DLC hero-avatar collection name consumed from the DLC runtime snapshot.
  DlcContentCollectionName: "hero-avatars"
  # Supported content schema version for DLC hero-avatar packs.
  DlcContentSchemaVersion: "1.0"

# Voice reminder plugins are loaded from bundled assets plus {EffectiveDataRoot}/plugins/voice-reminders.
# Bundled reminders keep the historical crisp / gentle / buy_sell selection keys stable.
VoiceReminderPlugins:
  # Optional. If omitted, resolves to ./plugins/voice-reminders beside the backend host.
  BundledPluginsDirectoryPath: "./plugins/voice-reminders"
  # Optional. If omitted, resolves to {EffectiveDataRoot}/plugins/voice-reminders.
  PluginsDirectoryPath:
  # Optional in-memory cache only. Does not persist catalog state across restarts.
  EnableInMemoryCache: true
  # Cache lifetime in seconds for repeated catalog reads within the same process.
  CacheDurationSeconds: 15
  # Optional runtime compatibility version overrides. Defaults to the host informational version.
  CurrentApiVersion:
  CurrentWebVersion:

# Database Connection Strings
# ConnectionStrings:Default is optional for SQLite.
# - If not set, it will be automatically generated as: {RuntimeRoot}/saves/save0/config/hagicode.db
# - To override it, provide a SQLite "Data Source=..." value.
ConnectionStrings:
# Default SQLite connection string:
#   "Data Source=./saves/save0/config/hagicode.db"

# ============================================================================
# Database Configuration
# ============================================================================
# HagiCode Core now uses SQLite as the only supported relational database.
# - Best for: Single-machine deployments, development, software packages
# - Pros: No external dependencies, easy setup, portable database file
# - Cons: Single writer, limited concurrency, not intended for multi-user teams
# - Database file: ./saves/save0/config/hagicode.db (auto-created unless overridden)
# - Override path by setting ConnectionStrings:Default to a SQLite Data Source=... value
# ============================================================================

Database:
  # Whether to automatically apply database migrations on application startup
  AutoMigrateDatabase: true

  # Whether to automatically run DbUp SQL script migrations on application startup
  AutoRunDbUpMigrations: true

  # Whether to seed data after migration
  AutoSeedData: true

  # Timeout for database operations in seconds
  MigrationTimeoutSeconds: 300

# Orleans Cluster Configuration
Orleans:
  ClusterId: "pcode-cluster"
  ServiceId: "pcode-service"
  Networking:
    # Orleans endpoint allocation defaults to startup probing with random available ports.
    # Set SiloPort and/or GatewayPort only when you need explicit port reservations.
    AdvertisedIPAddress: "127.0.0.1"
    ListenOnAnyHostAddress: false
    SiloPort: null
    GatewayPort: null
  # BREAKING: Orleans grain storage now uses a sharded SQLite layout.
  # By default, 100 shard databases are created under {RuntimeRoot}/saves/save0/data/orleans/grains.
  # Set ShardRootPath to override the shard directory.
  #  ShardRootPath: "./saves/save0/data/orleans/grains"
  ShardCount: 100
  UseWalMode: true
  InitializationMaxConcurrency: 8
  TimeoutPolicy:
    LongRunningExecutionSeconds: 7200
    HealthCheckSeconds: 60
    DefaultSiloResponseSeconds: 30
    GrainCollectionMinutes: 30
    StorageBusyTimeoutMs: 5000
    DefaultProviderStartupTimeoutMs: 30000

# Claude Code Integration Settings
ClaudeCode:
  ExecutablePath: claude
  WorkspacePath: /tmp/claude-workspaces
  TimeoutSeconds: 7200
  EnableStreaming: true

# AI Provider Configuration
# Configure CLI-based AI providers with their specific settings
# Note: Supported providers include ClaudeCodeCli, CodebuddyCli, GitHubCopilot, CodexCli, HermesCli, QoderCli, kiro-cli, KimiCli, GeminiCli, DeepAgentsCli
AI:

  # AI Service Settings
  Service:
    # Whether to automatically inject language preference into prompts that don't contain language instructions
    AutoInjectLanguagePreference: true
    # Default language preference when user hasn't set one (null: follow UI, "zh-CN", "en-US")
    DefaultLanguagePreference: "zh-CN"
    # Default executor type used by SessionGrain (ClaudeCodeCli, CodexCli, GitHubCopilot, CodebuddyCli, HermesCli, QoderCli, kiro-cli, KimiCli, GeminiCli, DeepAgentsCli)
    DefaultExecutorType: "ClaudeCodeCli"

  Providers:
    Providers:
      # Claude Code CLI Provider (Default)
      ClaudeCodeCli:
        Type: "ClaudeCodeCli"
        ExecutablePath: "claude"  # Path to claude CLI executable
        WorkingDirectory: null  # Optional: override working directory

      # Codebuddy CLI Provider (ACP stdio runtime)
      CodebuddyCli:
        Type: "CodebuddyCli"
        Enabled: false
        ExecutablePath: "codebuddy"
        WorkingDirectory: null


      # Hermes CLI Provider (ACP stdio runtime with dynamic auth)
      HermesCli:
        Type: "HermesCli"
        Enabled: false
        ExecutablePath: "hermes"
        Model: null
        WorkingDirectory: null

      # DeepAgents CLI Provider (ACP stdio runtime via deepagents --acp)
      DeepAgentsCli:
        Type: "DeepAgentsCli"
        Enabled: false
        ExecutablePath: "deepagents"
        Model: null
        WorkingDirectory: null
        PermissionMode: "bypassPermissions"
        Settings:
          startupTimeoutMs: "15000"
      
      # GitHub Copilot CLI Provider (shared libs adapter mode)
      GitHubCopilot:
        Type: "GitHubCopilot"
        Enabled: true  # Set to true to enable GitHub Copilot
        ExecutablePath: "copilot"  # Path to copilot CLI executable
        UseLoggedInUser: true  # Use local Copilot login state (set false to use GitHubToken)
        GitHubToken: null  # Optional token when UseLoggedInUser=false
        CliUrl: null  # Optional Copilot CLI URL override
        Timeout: 1800  # Per-request timeout in seconds (default 30 minutes)
        IdleTimeout: 300  # Forced cancel when the stream emits no session events for 5 minutes
        NoAskUser: true  # Maps to the verified --no-ask-user startup flag through HagiCode.Libs
        PermissionMode: "default"  # Explicitly keep normal read flows scoped unless a request or hero override opts into bypassPermissions
        Model: "gpt-5-mini"  # Model: claude-sonnet-4-6, claude-opus-4-7, gpt-5.5, etc.
        WorkingDirectory: null  # Optional: override working directory
        # Permission defaults converted to verified Copilot startup arguments by HagiCode.Libs
        # Supported flags were checked with `copilot --help`; unsupported flags such as --headless are filtered out and the request fails instead of falling back to any core-local transport.
        Permissions:
          AllowAllTools: false  # Allow all tools (not recommended for production)
          AllowAllPaths: false  # Allow all file system paths (not recommended for production)
          AllowAllUrls: false  # Allow all URL access (not recommended for production)
          AllowedTools: [ ]  # Whitelist of allowed tool names
          AllowedPaths: [ ]  # Whitelist of allowed file system paths
          DeniedTools: [ ]  # Blacklist of denied tool names
          DeniedUrls: [ ]  # Blacklist of denied URLs
        AdditionalArgs: [ ]  # Additional startup arguments filtered against the verified Copilot CLI help surface for SDK bootstrap only
      
      # Codex CLI Provider (JSON event mode)
      CodexCli:
        Type: "CodexCli"
        Enabled: false
        ExecutablePath: "codex"
        Model: "gpt-5.5"
        WorkingDirectory: null

      # OpenCode CLI Provider (HTTP runtime mode)
      OpenCodeCli:
        Type: "OpenCodeCli"
        Enabled: true
        ExecutablePath: "opencode"
        Model: null
        WorkingDirectory: null

      # Qoder CLI Provider (shared ACP runtime mode)
      QoderCli:
        Type: "QoderCli"
        Enabled: false
        ExecutablePath: "qodercli"
        Model: null
        WorkingDirectory: null

      # Kiro CLI Provider (shared ACP runtime mode with docs-only auth bootstrap)
      kiro-cli:
        Type: "kiro-cli"
        Enabled: false
        ExecutablePath: "kiro-cli"
        Model: null
        WorkingDirectory: null
        Settings:
          startupTimeoutMs: "60000"
          authMethod: ""
          authToken: ""
          bootstrapMethod: ""

      # Kimi CLI Provider (shared ACP runtime mode with docs-only/manual-auth guidance)
      KimiCli:
        Type: "KimiCli"
        Enabled: false
        ExecutablePath: "kimi"
        Model: null
        WorkingDirectory: null
        Settings:
          startupTimeoutMs: "15000"
          authMethod: null
          authToken: ""
          authHint: "Complete local sign-in or provide a token before refreshing."

      # Gemini CLI Provider (shared ACP runtime mode via upgraded HagiCode.Libs)
      GeminiCli:
        Type: "GeminiCli"
        Enabled: false
        ExecutablePath: "gemini"
        Model: null
        WorkingDirectory: null
        Settings:
          startupTimeoutMs: "15000"
          authMethod: null
          authToken: ""
          authHint: "Complete local sign-in or provide a token before refreshing."

  # ACP session manager settings
  SessionManager:
    MaxSessions: 50
    DefaultWorkingDirectory: null

  # Platform-specific ACP runtime configuration
  PlatformConfigurations:
    CodebuddyCli:
      ExecutablePath: "codebuddy"
      Arguments: "--acp"
      EnvironmentVariables: { }
    HermesCli:
      ExecutablePath: "hermes"
      Arguments: "acp"
      ClientName: "HagiCode"
      Authentication:
        PreferredMethodId: null
        MethodInfo: { }
      SessionDefaults:
        ModeId: "bypassPermissions"
        Metadata: { }
    QoderCli:
      ExecutablePath: "qodercli"
      Arguments: ""
      EnvironmentVariables: { }
    kiro-cli:
      ExecutablePath: "kiro-cli"
      Arguments: ""
      StartupTimeoutMs: 60000
      AuthenticationMethod: null
      AuthenticationToken: null
      BootstrapMethod: ""
      EnvironmentVariables: { }
    KimiCli:
      ExecutablePath: "kimi"
      Arguments: ""
      StartupTimeoutMs: 15000
      AuthenticationMethod: null
      AuthenticationToken: null
      AuthenticationHint: "Complete local sign-in or provide a token before refreshing."
      EnvironmentVariables: { }
    GeminiCli:
      ExecutablePath: "gemini"
      Arguments: ""
      StartupTimeoutMs: 15000
      AuthenticationMethod: null
      AuthenticationToken: null
      AuthenticationHint: "Complete local sign-in or provide a token before refreshing."
      EnvironmentVariables: { }

  # Codex provider settings
  Codex:
    Enabled: true
    ExecutablePath: "codex"
    Model: "gpt-5.5"
    SandboxMode: "danger-full-access"
    WorkingDirectory: null
    SkipGitRepoCheck: true
    ModelReasoningEffort: "high"
    NetworkAccessEnabled: true
    WebSearchMode: null
    WebSearchEnabled: true
    ApprovalPolicy: "never"
    AdditionalDirectories: [ ]
    # SessionThreadBindingDatabaseConnectionString: ""
    # 如未设置，自动使用 {EffectiveDataRoot}/codex.db
    EnvironmentVariables: { }

  # OpenCode provider settings
  OpenCode:
    Enabled: true
    ExecutablePath: "opencode"
    BaseUri: null
    ExecutionMode: "live"
    # Prefer the OpenCode runtime's default model unless a Hero/runtime override supplies one.
    Model: null
    DefaultModelProvider: "anthropic"
    WorkingDirectory: null
    Workspace: null
    SessionTitlePrefix: "PCode OpenCode"
    # SessionThreadBindingDatabaseConnectionString: ""
    # 如未设置，自动使用 {EffectiveDataRoot}/opencode-session-bindings-v2.db（不会读取或迁移旧的 opencode.db）
    # 仅当 AI:OpenCode:Enabled=true 时，后端才会在 Orleans startup task 完成后异步执行 `opencode models`。
    # 如果本次刷新失败，则继续提供上一次成功快照，并通过 stale 元数据暴露该状态。
    ModelCatalogRefreshTimeoutSeconds: 15
    LogLevel: null
    EnvironmentVariables: { }

# Session Concurrency Settings
SessionConcurrency:
  DefaultMaxConcurrentSessions: 20

# Workspace Persistence Configuration
# Configure where PCode stores temporary workspace files for coding sessions.
# By default, uses the system Temp directory. Uncomment WorkspaceRoot to use a persistent location.
Workspace:
  # WorkspaceRoot: ""  # Optional: Set to a persistent path like "/var/lib/pcode/workspaces" on Linux
  # If empty or not set, defaults to system Temp directory.
  # Can be overridden via PCODE_WORKSPACE_ROOT environment variable.
  AutoCreateDirectory: true  # Automatically create the workspace directory if it doesn't exist

# Local entitlement configuration
License:
  SteamDlc:
    HasBaseEntitlement: true
    BaseEditionName: "standard"
    HasAnnualDlcEntitlement: false
    AnnualDlcName: "annual-license"
    AnnualDlcIdentifier: ""
    AnnualDlcExpiresAtUtc: null
    AnnualDlcMaxConcurrentSessions: 10

Dlc:
  RootDirectory: "./dlcs"

# Version Check Configuration
# Frontend will check for updates and display notifications when available
VersionCheck:
  Enabled: true  # Whether version checking is enabled
  GitHubRepositoryOwner: "HagiCode-org"  # GitHub repository owner
  GitHubRepositoryName: "releases"  # GitHub repository name
  CurrentVersion: null  # Optional: Override auto-detected version (e.g., "v0.1.0")
  HttpTimeoutSeconds: 30  # HTTP timeout for GitHub API requests
  MaxRetries: 3  # Maximum retry attempts for GitHub API requests
  RetryBaseDelayMs: 1000  # Base delay in milliseconds for exponential backoff

# Container First-Run Configuration
# Settings for containerized deployments with auto project discovery
Container:
  MountPath: "/app/workdir"  # Default container mount path for project discovery
  FirstRunCheckEnabled: true  # Enable first-run project discovery flow
  # Environment variable override: HAGICODE_CONTAINER__MOUNTPATH or HAGICODE_CONTAINER__FIRSTRUNCHECKENABLED

# Community Configuration
# Settings for official community entry points managed by the backend
Community:
  # Official Discord community invite link
  DiscordLink: "https://discord.gg/qY662sJK"

# RSS Feed Configuration
# Settings for RSS blog feed integration
RssFeed:
  # RSS feed URL to fetch blog posts from
  FeedUrl: "https://docs.hagicode.com/blog/rss.xml"
  # Cache duration in hours for RSS feed content
  CacheDurationHours: 24
  # Maximum number of items to return from the RSS feed
  MaxItems: 5

# Prompts Configuration
# Settings for multilingual prompt file management system
Prompts:
  RootPath: "Resources/Prompts"  # Root path for prompt files (relative to Web project root)
  DefaultLocale: "en-US"  # Default language locale for fallback
  EnableHotReload: false  # Enable runtime hot reload of prompts (requires admin API)
  StrictMode: false  # In strict mode, startup fails if prompt files are missing or invalid
  EnableCache: true  # Enable in-memory caching of prompts
  SupportedLocales: # List of supported language locales
    - "zh-CN"
    - "en-US"
  # Prompt completeness validation settings
  ValidationMode: "Lenient"  # Validation mode: "Lenient" (warnings only) or "Strict" (throws exception)
  EnableCompletenessValidation: true  # Enable placeholder completeness validation at startup
  TemplateValidationMode: "Strict"  # Template validation mode: "Lenient" or "Strict"

  # Scenario enumeration validation settings
  ValidateAllScenarios: true  # Validate all PromptScenario enum values have corresponding prompt files
  RequiredLocales: # Required locales for scenario validation
    - "zh-CN"
    - "en-US"

  # Fallback lookup for deprecated filenames (during deprecation period)
  EnableFallbackLookup: true  # Enable fallback lookup for old filename patterns during deprecation

  # Default template engine configuration
  DefaultSyntax: "handlebars"  # Default template syntax: "handlebars" or "scriban"

  # Handlebars template engine configuration
  Handlebars:
    CacheSize: 100  # Maximum number of compiled templates to cache

# Session Message Shard Storage Configuration
# Stores new session messages in dedicated SQLite shard databases under saves/save0/data/messages
MessageStorage:
  # Base directory for shard database files
  # If omitted or set to default, automatically uses: {RuntimeRoot}/saves/save0/data/messages
  DirectoryPath: "./saves/save0/data/messages"

  # Enable WAL mode for shard databases
  UseWalMode: true

  # SQLite busy timeout in milliseconds
  BusyTimeoutMs: 5000

# Image Storage Configuration
# Stores uploaded chat images under the effective data root by default
ImagesStorage:
  # Base directory for uploaded image files
  # If omitted or set to default, automatically uses: {EffectiveDataRoot}/images
  DirectoryPath: "./data/images"

# Hero History Shard Storage Configuration
# Stores active hero history in dedicated SQLite shard databases under saves/save0/data/hero-history
HeroHistoryStorage:
  # Base directory for shard database files
  # If omitted or set to default, automatically uses: {RuntimeRoot}/saves/save0/data/hero-history
  DirectoryPath: "./saves/save0/data/hero-history"

  # Enable WAL mode for shard databases
  UseWalMode: true

  # SQLite busy timeout in milliseconds
  BusyTimeoutMs: 5000
