Settings

IsonForge reads settings from JSON files at startup. Values become session defaults; command-line flags always override.

File sources (precedence, lowest to highest)

Source Path Scope
User ~/.isonforge/settings.json All your projects
Project <cwd>/.isonforge/settings.json Committed to the repo
Local <cwd>/.isonforge/settings.local.json Gitignored - personal overrides
Runtime --settings <path-or-json> Per-invocation

Each later source overrides keys set in earlier ones. Project beats user, local beats project, runtime beats everything.

Filter which sources load:

isonforge --setting-sources user,project    # skip local
isonforge --setting-sources user            # ignore project + local entirely

Known fields

{
  "effort": "high",
  "permissionMode": "acceptEdits",
  "outputFormat": "text",
  "maxTurns": 10,
  "maxBudgetUsd": 5.00,
  "addDirs": ["../shared", "../utils"],
  "systemPromptAppend": "Always use TypeScript strict mode. No `any`.",
  "theme": "default",

  "hooks": {
    "PreToolUse": [
      {"matcher": "Edit|Write", "hooks": [{"type": "command", "command": "make lint"}]}
    ]
  },

  "mcpServers": {
    "github": {"command": "mcp-github", "args": ["--token", "$GITHUB_TOKEN"]}
  },

  "permissions": {
    "rules": [
      {"tool": "bash", "args_pattern": "git status*", "action": "allow"},
      {"tool": "bash", "args_pattern": "rm -rf*",    "action": "deny"}
    ]
  }
}

Flag values always win over settings:

# settings.json says effort=high; this run uses low
isonforge --effort low "quick fix"

Inline JSON via --settings

--settings accepts either a file path or an inline JSON string:

isonforge --settings '{"effort":"max","permissionMode":"plan"}'
isonforge --settings ./team-settings.json

Inline form is handy for one-off scripts. The JSON is parsed and merged on top of file sources.

Sample .gitignore entry:

.isonforge/settings.local.json

Hooks in settings

See Hooks for the full hook schema. Brief preview:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {"type": "command", "command": "./scripts/check-license.sh", "timeout": 10}
        ]
      }
    ],
    "PostToolUse": [
      {"matcher": "Edit|Write", "hooks": [{"type": "command", "command": "pnpm format"}]}
    ]
  }
}

MCP servers in settings

See MCP. Brief preview:

{
  "mcpServers": {
    "github": {
      "command": "mcp-github",
      "args": ["--repo", "myorg/myrepo"],
      "env": {"GITHUB_TOKEN": "$GITHUB_TOKEN"}
    },
    "postgres": {
      "command": "uvx",
      "args": ["mcp-server-postgres"]
    }
  }
}

Permission rules

Persistent rules at ~/.isonforge/permissions.json get loaded automatically (or override via permissions.rules in settings.json):

{
  "preset": "auto",
  "rules": [
    {"tool": "bash", "args_pattern": "docker compose*", "action": "allow"},
    {"tool": "bash", "args_pattern": "kubectl delete*", "action": "deny"},
    {"tool": "mcp__github__*", "action": "allow"}
  ]
}

See Permission modes.

Inspect effective settings

/config

Opens ~/.isonforge/config.json (API key + endpoint) in $EDITOR. For settings inspection use:

isonforge --verbose "test" 2>&1 | grep -i settings

Verbose mode logs what got loaded from where.

When settings don't apply