Skip to content

Configuration

planeai is configured via a single JSON file at ~/.config/planeai/config.json (or %APPDATA%\planeai\config.json on Windows). The file supports JSONC (comments allowed).

Each provider defines how planeai launches and communicates with an AI agent CLI.

{
"providers": {
"kiro": {
// Command to start the agent
"command": "kiro-cli chat",
// Command to send a prompt to an existing session
"prompt_command": "kiro-cli chat --message \"{{prompt}}\"",
// Template for autonomous prompts (task dispatch)
"autonomous_prompt_template": "Complete this task: {{task.title}}\n\n{{task.description}}",
// Flag to enable autonomous/yolo mode (no confirmations)
"yolo_flag": "--trust",
// Command used when restarting an exited session
"resume_command": "kiro-cli chat --resume",
},
"claude": {
"command": "claude",
"prompt_command": "claude --message \"{{prompt}}\"",
"autonomous_prompt_template": "{{task.title}}: {{task.description}}",
"yolo_flag": "--dangerously-skip-permissions",
},
},
}
FieldDescription
commandShell command to start a new agent session
prompt_commandCommand to send a prompt to a running session
autonomous_prompt_templateTemplate rendered when auto-dispatch sends a task
yolo_flagFlag appended in autonomous mode to skip confirmations
resume_commandCommand to resume interactively when restarting an exited session

Controls how planeai manages terminal sessions.

{
"session_backend": "local", // "local" | "tmux" | "daemon"
}
ValueBehavior
localIn-process PTY — lightweight, no external dependencies (default)
tmuxRequires tmux — sessions persist via tmux
daemonBuilt-in daemon process — sessions persist across app restarts (experimental)

Templates control how tasks map to branches, session names, and prompts.

{
"task_manager": {
"templates": {
// Git branch name for the task
"branch": "{{task.key | slugify}}/{{task.title | slugify}}",
// Session display name
"name": "{{task.key}}: {{task.title | truncate(40)}}",
// Prompt sent to the agent
"prompt": "{{task.description}}",
},
},
}

Templates use {{variable}} interpolation with optional transforms via |:

TransformDescription
slugifyConverts to URL-safe slug
truncate(n)Truncates to n characters
lowercaseConverts to lowercase
uppercaseConverts to uppercase

Available variables: task.key, task.title, task.description, task.status, task.priority.

Hooks run shell commands at task state transitions.

{
"task_manager": {
"lifecycle_hooks": {
// Runs when a task is dispatched to an agent
"on_start": "echo 'Starting {{task.key}}'",
// Runs when the agent signals completion
"on_complete": "git add -A && git commit -m 'feat({{task.key | slugify}}): {{task.title}}'",
// Runs when a notification is received
"on_notify": "say '{{task.key}} needs attention'",
// Runs when a failed task is retried
"on_restart": "git stash && git pull --rebase",
},
},
}
HookTrigger
on_startTask dispatched to an agent session
on_completeAgent signals task completion
on_notifyTask receives a notification
on_restartTask is retried after failure

GUI apps inherit a minimal system PATH that may not include directories where your AI agent CLIs are installed. planeai automatically prepends conventional developer directories (~/.local/bin, ~/.cargo/bin, ~/go/bin, /opt/homebrew/bin, /usr/local/bin), but if your CLI lives in a custom location, configure extra_path_dirs:

{
// Directories prepended to PATH when launching sessions
"extra_path_dirs": ["~/.guardrails/shims", "~/custom-tools/bin"],
}

These directories are prepended before the conventional ones, giving them highest priority.

Set PLANEAI_EXTRA_PATH (colon-separated) to override extra_path_dirs without editing the config file:

Terminal window
export PLANEAI_EXTRA_PATH="$HOME/.guardrails/shims:$HOME/my-tools/bin"

When PLANEAI_EXTRA_PATH is set, extra_path_dirs from the config file is ignored.

planeai can sync issues from Jira Cloud into the local task board and write status changes back to Jira. Configured via the integrations.jira block.

{
"integrations": {
"jira": {
// Your Jira Cloud site URL
"site": "https://mycompany.atlassian.net",
// How often to poll Jira (milliseconds, default: 60000)
"sync_interval_ms": 60000,
// Named sync sources — each is a JQL filter
"sources": {
"my-sprint": {
// JQL query selecting which issues to sync
"jql": "project = ENG AND assignee = currentUser() AND sprint in openSprints()",
// Map Jira status names to planeai statuses
"status_map": {
"In Progress": "in_progress",
"In Review": "in_review",
"Done": "done",
},
// Optional: write local status changes back to Jira
"writeback": {
// Transition the Jira issue to this status when work starts
"on_start": "In Progress",
// Transition the Jira issue to this status when work completes
"on_complete": "Done",
// Add a comment to the Jira issue on each transition
"comment": true,
},
},
},
},
},
}
FieldDescription
siteJira Cloud site URL (e.g., https://myco.atlassian.net)
sync_interval_msPolling interval in milliseconds (default: 60000)
sourcesNamed JQL filters to sync
sources.<name>.jqlJQL query selecting issues to import
sources.<name>.status_mapMap of Jira status → planeai status (todo, in_progress, in_review, done)
sources.<name>.writebackOptional writeback configuration
writeback.on_startJira status to transition to when work starts locally
writeback.on_completeJira status to transition to when work completes locally
writeback.commentWhether to add a comment on each transition (default: false)

Jira integration uses OAuth 2.0 with PKCE. Connect via Preferences → Jira → Connect to Jira, which opens the Atlassian consent screen in your browser. Tokens are stored locally in the app data directory.

When a synced issue no longer matches its source JQL (e.g., it was reassigned or moved to another project), planeai marks it as “departed” and shows a prompt asking whether to mark the local task as done or dismiss it.