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

> Learn how to configure the always on flag for the Pi extension in i-have-adhd using flag files or JSON settings. Ensure your agent runs continuously.

- Repository: [Ayoub Ghriss/i-have-adhd](https://github.com/ayghri/i-have-adhd)
- Tags: how-to-guide
- Published: 2026-09-01

---

**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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) lines 15-17, the flag file path is constructed:

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

```

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

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

```

To enable always-on via flag file:

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

```

To disable:

```bash
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`](https://github.com/ayghri/i-have-adhd/blob/main/i-have-adhd.json):

```typescript
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:

```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:

```typescript
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`](https://github.com/ayghri/i-have-adhd/blob/main/scripts/check_pi_extension.py) that validates the flag file behavior:

```python
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:

```typescript
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`](https://github.com/ayghri/i-have-adhd/blob/main/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.