How to Configure the Always-On Flag for the Pi Extension in i-have-adhd

The Pi extension in i-have-adhd checks two sources for the always-on flag: a flag file at .i-have-adhd-always in the agent directory and a JSON configuration setting "alwaysOn": true in i-have-adhd.json.

The i-have-adhd project provides ADHD-friendly enhancements for AI coding assistants, and the Pi extension implements a persistent "always-on" mode that survives across sessions. Understanding how this flag is configured helps you control whether ADHD mode starts automatically when you launch the Pi agent.

Two Methods to Enable Always-On Mode

The Pi extension supports dual configuration paths, giving you flexibility in how you enable persistent ADHD mode.

Flag File Method

The extension checks for a sentinel file that signals always-on status without requiring valid JSON syntax.

In extensions/i-have-adhd.ts lines 15-17, the flag file path is constructed:

const alwaysOnFlag = join(getAgentDir(), ".i-have-adhd-always");

The restoreState function at lines 64-67 uses existsSync() to check this file:

const enabledByDefault =
  pi.getFlag("adhd") === true ||
  config.alwaysOn === true ||
  existsSync(alwaysOnFlag);

To enable always-on via flag file:

touch ~/.pi/agent/.i-have-adhd-always

To disable:

rm ~/.pi/agent/.i-have-adhd-always

JSON Configuration Method

For programmatic control, you can set the alwaysOn property in the extension's JSON configuration file.

The loadConfig() function at lines 42-49 reads i-have-adhd.json:

function loadConfig(): { alwaysOn?: boolean } {
  const configPath = join(getAgentDir(), "i-have-adhd.json");
  // ... file reading logic
  return JSON.parse(content);
}

The configuration object is then checked in restoreState via config.alwaysOn === true.

To enable always-on via JSON:

// ~/.pi/agent/i-have-adhd.json
{
  "alwaysOn": true
}

How the Decision Logic Works

The Pi extension evaluates always-on status through a priority-based OR condition. The final enabled state in restoreState follows this precedence:

  1. Explicit flag check: pi.getFlag("adhd") === true — runtime flag override
  2. JSON configuration: config.alwaysOn === true — persistent config setting
  3. Flag file presence: existsSync(alwaysOnFlag) — simple file marker

The complete logic at lines 64-67:

const enabledByDefault =
  pi.getFlag("adhd") === true ||
  config.alwaysOn === true ||
  existsSync(alwaysOnFlag);
enabled = savedState ?? enabledByDefault;

The ?? operator means saved session state takes precedence when it exists; otherwise, enabledByDefault determines the initial state.

Cross-Runtime Compatibility

The Pi extension mirrors the same always-on flag pattern used by Claude Code. The hooks/always-on.mjs file implements an identical hook using ~/.claude/.i-have-adhd-always, ensuring consistent behavior across different AI agent runtimes.

This shared convention at lines 2-5 of hooks/always-on.mjs allows users to maintain synchronized ADHD mode settings across multiple coding assistant platforms.

Testing the Always-On Configuration

The repository includes a verification script at scripts/check_pi_extension.py that validates the flag file behavior:

from pathlib import Path

# Create the flag file to test always-on activation

Path(agent_dir, ".i-have-adhd-always").touch()

This test harness confirms that file creation correctly triggers the enabled state.

Programmatic Detection

If building tools that interact with Pi's ADHD mode, replicate the extension's detection logic:

import { existsSync } from "node:fs";
import { join } from "node:path";
import { getAgentDir } from "@earendil-works/pi-coding-agent";

const alwaysOnFlag = join(getAgentDir(), ".i-have-adhd-always");
const isEnabled = existsSync(alwaysOnFlag);

Summary

  • The Pi extension always-on flag can be configured via file presence (.i-have-adhd-always) or JSON property ("alwaysOn": true)
  • extensions/i-have-adhd.ts implements the dual-source check in restoreState with existsSync() and config.alwaysOn === true
  • Session state takes precedence over default enablement when present
  • The flag file pattern is compatible with Claude Code's identical hook implementation
  • Use touch to enable and rm to disable via command line for quick toggling

Frequently Asked Questions

What takes priority: the flag file or the JSON config?

Both the flag file and alwaysOn: true in JSON contribute equally to enabledByDefault through an OR condition. If either is present, always-on activates. However, saved session state overrides both when it exists from a previous run.

Where exactly is the Pi agent directory located?

By default, getAgentDir() returns ~/.pi/agent on Linux and macOS. The actual path depends on your Pi installation and any PI_AGENT_DIR environment variable overrides.

Can I use both the flag file and JSON config simultaneously?

Yes. Setting both creates redundant activation paths with no negative effects. The extension simply checks both sources and enables ADHD mode if either signals true.

Why does the extension use a hidden file instead of just JSON?

The .i-have-adhd-always file provides a language-agnostic, shell-friendly toggle that requires no JSON parsing. This enables quick scripting and aligns with the Claude Code hook pattern for cross-platform consistency.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →