# How i-have-adhd Ensures Cross-Platform Parity for Its Hooks

> Discover how i-have-adhd maintains cross-platform parity for its hooks. Learn how a single source of truth ensures consistent functionality across different runtimes.

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

---

**i-have-adhd ensures cross-platform parity by maintaining a single source of truth in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) while duplicating hook logic across Unix shell, PowerShell, and JavaScript runtimes that all reference the same flag file and ruleset.**

The **i-have-adhd** repository implements an "always-on" hook system that must behave identically across fundamentally different execution environments. Rather than trying to abstract away platform differences with a complex compatibility layer, the project takes a deliberately simple approach: shared configuration, duplicated implementations, and a unified file-based toggle mechanism.

## Central Configuration: The Single Source of Truth

At the heart of cross-platform parity sits [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json). This JSON file defines the hook name (`always-on`) and the environment variable path that controls activation. Every runtime—whether Bash, PowerShell, or Node.js—parses this same file to determine **where** to look for the toggle flag and **what** behavior to enable.

This design guarantees that any change to the hook's semantics propagates automatically. Update the flag path in one place, and all platforms follow. The configuration file eliminates the class of bugs where "it works on my shell but not in PowerShell."

## Platform-Specific Implementations with Identical Logic

The project maintains three parallel implementations that mirror each other's behavior exactly:

### Unix Shell ([`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh))

The Bash implementation checks for the presence of `~/.config/opencode/.i-have-adhd-always`. If found, it injects the ADHD ruleset into the session context.

### PowerShell (`hooks/always-on.ps1`)

The PowerShell cmdlet performs the identical check using `Test-Path`, targeting the **same** flag file path. The ruleset payload matches byte-for-byte with the Unix version.

### JavaScript (`hooks/always-on.mjs`)

The Node-compatible version reads [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json), resolves the flag path, and conditionally returns the ruleset:

```javascript
import { readFileSync, existsSync, unlinkSync } from 'fs';
import { resolve } from 'path';
import config from '../hooks/hooks.json';

const flagPath = resolve(process.env.HOME, '.config', 'opencode', '.i-have-adhd-always');

export function injectAlwaysOn() {
  if (!existsSync(flagPath)) return '';               // hook disabled
  const rules = readFileSync('rules.txt', 'utf8');     // ADHD ruleset
  return `ADHD MODE ACTIVE (always‑on).\n${rules}\n\n` +
         `Delete ${flagPath} to turn always‑on off for good.\n`;
}

```

All three scripts contain the **same textual payload** (the ADHD ruleset) and follow the **same file-based toggle mechanism**. This duplication is intentional—it trades minor maintenance overhead for absolute behavioral consistency.

## Runtime Integration Through Unified APIs

The **OpenCode plugin** at `.opencode/plugins/i-have-adhd.mjs` imports directly from the JavaScript hook:

```javascript
import { injectAlwaysOn } from '../../hooks/always-on.mjs';

export function onSessionStart() {
  const hookPayload = injectAlwaysOn();
  if (hookPayload) {
    // inject the payload into the session context for every model
    this.context.addHook('always-on', hookPayload);
  }
}

```

When a session starts, the plugin calls `injectAlwaysOn()`—the **same** function that shell scripts expose through their own wrappers. This ensures that OpenCode, Pi, OMP, and Claude runtimes honor the "always-on" flag uniformly, regardless of how the underlying host environment implements file system access.

## Consistent Toggle Semantics Across Platforms

Users control the hook through a single, portable mechanism:

```bash

# Enable "always-on" (works on any platform)

touch ~/.config/opencode/.i-have-adhd-always

# Disable "always-on"

rm ~/.config/opencode/.i-have-adhd-always

```

Because **every** implementation references the exact same path defined in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json), the state cannot diverge between platforms. A flag created in PowerShell is immediately visible to the Bash script and the JavaScript runtime. No registry keys, no environment variable synchronization, no platform-specific state management.

## Automated Testing for Parity Guarantees

The test suite in [`tests/test_always_on_hooks.py`](https://github.com/ayghri/i-have-adhd/blob/main/tests/test_always_on_hooks.py) exercises each implementation against a shared specification:

- **Same rule set injection** — Verifies that Bash, PowerShell, and JavaScript return identical payload content when the flag is present
- **Correct toggle behavior** — Confirms that absence of the flag file disables the hook on all platforms
- **Path resolution** — Ensures that relative path handling produces equivalent results across runtimes

This automated verification catches regressions where a platform-specific script might drift from canonical behavior. A failing test on any implementation blocks the entire change, enforcing cross-platform parity at CI time.

## Summary

- **[`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json)** provides the single source of truth for hook configuration
- **Three parallel implementations** (`.sh`, `.ps1`, `.mjs`) share identical logic and payload
- **Unified flag file** at `~/.config/opencode/.i-have-adhd-always` guarantees consistent state
- **`injectAlwaysOn()` function** exposes the same API to shell scripts and Node-based runtimes
- **[`tests/test_always_on_hooks.py`](https://github.com/ayghri/i-have-adhd/blob/main/tests/test_always_on_hooks.py)** enforces behavioral parity through automated verification

## Frequently Asked Questions

### What happens if the flag file exists on one machine but not another?

The hook is **per-machine stateful**. The flag file lives in the user's home directory (`~/.config/opencode/`), so it does not synchronize across devices by default. Each machine maintains its own "always-on" preference. To enable globally, users must create the flag on each target system—or sync their dotfiles.

### Why duplicate the implementation instead of using a cross-platform abstraction?

The i-have-adhd project prioritizes **behavioral correctness over code reuse**. Shell, PowerShell, and JavaScript have fundamentally different execution models, file system APIs, and error handling. Duplicating the (small, simple) logic eliminates an entire category of abstraction bugs where "it should work the same" turns out to be false. The test suite ensures the duplicates stay synchronized.

### Can I use the "always-on" hook outside of OpenCode?

Yes. The shell scripts function standalone—source [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh) in your `.bashrc` or import `hooks/always-on.ps1` in your PowerShell profile. The JavaScript module works in any Node environment. The OpenCode plugin is simply one consumer of the shared hook API.

### How does the project handle path differences between Windows and Unix?

The JavaScript implementation uses Node's `path.resolve()` and `process.env.HOME` (which maps correctly on Windows via `USERPROFILE`). The shell and PowerShell scripts both hardcode the Unix-style path `~/.config/opencode/`, which PowerShell resolves correctly through its tilde expansion. The JSON configuration centralizes this path definition for future flexibility.