Skip to main content

Configuration Files

Genie uses several configuration files and a PostgreSQL database for state. The main config file is ~/.genie/config.json, but the primary state store is an embedded PostgreSQL instance managed by pgserve.

config.json

Location: ~/.genie/config.json The primary configuration file, managed by genie setup or edited directly. Validated by a Zod schema on every load — invalid configs fall back to defaults with a warning.

Full Schema

{
  "version": 2,
  "session": {
    "name": "genie",
    "defaultWindow": "shell",
    "autoCreate": true
  },
  "terminal": {
    "execTimeout": 120000,
    "readLines": 100,
    "worktreeBase": "~/.genie/worktrees"
  },
  "logging": {
    "tmuxDebug": false,
    "verbose": false
  },
  "shell": {
    "preference": "auto"
  },
  "shortcuts": {
    "tmuxInstalled": false,
    "shellInstalled": false
  },
  "codex": {
    "configured": false
  },
  "installMethod": "bun",
  "updateChannel": "latest",
  "setupComplete": true,
  "workerProfiles": {
    "default": {
      "launcher": "claude",
      "claudeArgs": ["--dangerously-skip-permissions"]
    },
    "safe": {
      "launcher": "claude",
      "claudeArgs": []
    }
  },
  "defaultWorkerProfile": "default",
  "councilPresets": {
    "default": {
      "left": "default",
      "right": "default",
      "skill": "council"
    }
  },
  "systemPromptMode": "append",
  "omni": {
    "apiUrl": "http://localhost:3008",
    "apiKey": "...",
    "defaultInstanceId": "..."
  }
}

Key Sections

Worker profiles define how to launch Claude Code workers. Each profile specifies a launcher binary and CLI arguments.
"workerProfiles": {
  "default": {
    "launcher": "claude",
    "claudeArgs": ["--dangerously-skip-permissions"]
  },
  "safe": {
    "launcher": "claude",
    "claudeArgs": []
  }
}
Use profiles with: genie spawn engineer --profile safe
Council presets configure dual-model deliberation for the /council skill:
"councilPresets": {
  "default": {
    "left": "default",
    "right": "default",
    "skill": "council"
  }
}
Each preset pairs two worker profiles (left/right panes) with a skill.
Controls how Genie injects system prompts into Claude Code workers:
ModeFlagBehavior
replace--system-prompt-fileReplaces Claude Code’s default system prompt
append--append-system-prompt-filePreserves Claude Code default, appends Genie context
Connects Genie to the Omni unified messaging platform:
"omni": {
  "apiUrl": "http://localhost:3008",
  "apiKey": "your-api-key",
  "defaultInstanceId": "instance-uuid"
}

State Storage — PostgreSQL

As of v4, Genie’s primary state store is an embedded PostgreSQL instance managed by pgserve. State that was previously stored in JSON files now lives in PG tables.

State Locations

StateLocationNotes
Tasks, stages, dependenciesPostgreSQL tasks, task_dependencies, task_stage_logFull lifecycle with audit trail
Boards and pipelinesPostgreSQL boards, board_templatesProject-scoped column pipelines
ProjectsPostgreSQL projectsNamed task boards
Agents (workers)PostgreSQL agents, agent_templatesReplaces ~/.genie/workers.json
TeamsPostgreSQL teamsReplaces ~/.genie/teams/*.json
MailboxPostgreSQL mailboxReplaces .genie/mailbox/*.json
Team chatPostgreSQL team_chatReplaces .genie/chat/*.jsonl
SessionsPostgreSQL sessions, session_contentClaude Code session metadata and content
Schedules and triggersPostgreSQL schedules, triggers, runsCron-based automation
Audit eventsPostgreSQL audit_eventsOTel-structured immutable log
HeartbeatsPostgreSQL heartbeatsAgent liveness tracking
App registryPostgreSQL app_store, installed_appsUnified item registry
ConversationsPostgreSQL conversations, messagesTask-linked conversations
pgserve data~/.genie/data/pgserve/PostgreSQL data directory

Legacy File Locations (deprecated)

These locations are no longer the primary state store but may still exist on disk:
FileReplaced ByStatus
~/.genie/workers.jsonagents tableDeprecated — PG is authoritative
~/.genie/teams/*.jsonteams tableDeprecated — PG is authoritative
.genie/mailbox/*.jsonmailbox tableDeprecated — PG is authoritative
.genie/chat/*.jsonlteam_chat tableDeprecated — PG is authoritative

Connection Details

SettingValue
Default port19642
Host127.0.0.1
Database namegenie
Data directory~/.genie/data/pgserve/
Port lockfile~/.genie/pgserve.port
Migration marker~/.genie/pgserve.migrated
See the PostgreSQL architecture page for full schema details and migration history.

Auto-Approve Configuration

Genie supports layered trust configuration for automatic tool approval. Config hierarchy (lower overrides higher):
  1. Global defaults: ~/.config/genie/auto-approve.yaml
  2. Repo-level: .genie/auto-approve.yaml in each repo
  3. Wish-level: ## Auto-Approve section in WISH.md

YAML Schema

# ~/.config/genie/auto-approve.yaml
defaults:
  allow:
    - Read
    - Glob
    - Grep
  deny:
    - Bash
  bash_allow_patterns:
    - "^git status"
    - "^bun test"
  bash_deny_patterns:
    - "^rm -rf"
    - "^git push.*--force"

repos:
  /home/user/myproject:
    inherit: global    # or "none" to start fresh
    allow:
      - Write
      - Edit
    bash_allow_patterns:
      - "^bun run"

Evaluation Order

For each tool use, the auto-approve engine:
  1. Checks deny lists first (deny wins over allow)
  2. Checks allow lists
  3. For Bash commands, checks bash_deny_patterns then bash_allow_patterns
  4. Merges layers: wish > repo > global defaults

Environment Variables

VariableDefaultPurpose
GENIE_HOME~/.genieRelocates all global state
GENIE_AGENT_NAMEAgent identity for hooks (required for auto-spawn)
GENIE_TEAMDefault team name
GENIE_NATS_URLnats://localhost:4222NATS server URL
GENIE_PG_PORT19642pgserve PostgreSQL port
GENIE_MAX_CONCURRENT5Max concurrent scheduler runs
GENIE_IDLE_TIMEOUT_MSAuto-suspend idle workers after N ms
CLAUDECODESet to 1 to enable Claude Code features
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMSSet to 1 for native teammate UI

Claude Code Settings

Genie integrates with Claude Code’s settings at ~/.claude/settings.json. The hook system is registered there:
{
  "hooks": {
    "PreToolUse": [{
      "matcher": ".*",
      "hooks": ["genie hook dispatch"]
    }],
    "PostToolUse": [{
      "matcher": "SendMessage",
      "hooks": ["genie hook dispatch"]
    }]
  }
}
Genie never modifies ~/.claude/settings.json directly. Hook registration is done during genie setup with user confirmation.