What Is the context-compat.ts Module and Why Is It Essential for i-have-adhd?
The context-compat.ts module normalizes session-manager APIs across Pi and OMP runtimes so the i-have-adhd extension can safely inspect conversation context and determine whether its ADHD ruleset is currently active.
The context-compat.ts module lives at extensions/context-compat.ts inside the ayghri/i-have-adhd repository. It acts as a runtime compatibility bridge that shields the extension from platform-specific differences, enabling a single codebase to operate reliably in both the Pi and OMP environments.
The Pi and OMP Session-Manager API Problem
The i-have-adhd extension targets two distinct runtimes, but each exposes a different session-manager API for retrieving conversation context.
Pi provides buildContextEntries(), which returns a flat array of custom message objects. OMP provides buildSessionContext(), which returns an object whose messages property contains the same kind of array.
Hard-coding either method into the extension logic would create a rigid dependency on one platform. If the API shape changes or the other runtime is used, the extension would break. The extension must inspect the context to know whether the ADHD ruleset in skills/i-have-adhd/SKILL.md is already present or has been disabled.
How the context-compat.ts Module Normalizes the API
The module solves this by exposing two pure functions that abstract away the underlying differences.
contextMessages(sessionManager)
The contextMessages() function accepts a session-manager instance and returns a plain array of ContextMessageMarker objects regardless of which runtime method the manager implements.
It first detects whether the manager exposes buildSessionContext() or buildContextEntries(), then normalizes the result into a consistent array shape. If the manager is null, not an object, or throws while building the context, the function fails open and returns an empty array. This prevents the extension from crashing during session startup.
latestMarkerIsActive(messages, activeType, disabledType)
The latestMarkerIsActive() function evaluates the normalized array to determine the effective state of a custom marker. It walks through the messages and returns true only if the most recent marker of activeType has not been overridden by a later marker of disabledType.
This logic is critical for toggle-style behavior, where a user might activate the ADHD rules and later disable them within the same session.
Integration with the Main Extension Logic
In extensions/i-have-adhd.ts, the rulesAreInContext() helper relies entirely on the compatibility layer to decide whether the ADHD rules are currently "live" in the model's context.
import { contextMessages, latestMarkerIsActive } from "./context-compat";
function rulesAreInContext(ctx: ExtensionContext): boolean {
return latestMarkerIsActive(
contextMessages(ctx.sessionManager), // ← works for Pi & OMP
"i-have-adhd-rules", // active marker type
"i-have-adhd-disabled", // disabled marker type
);
}
By delegating to contextMessages(), the extension avoids platform-specific conditionals. By delegating to latestMarkerIsActive(), it accurately tracks the ruleset state without manually scanning arrays in multiple places.
Verifying the Compatibility Layer
The repository includes scripts/check_context_compat.ts, which contains unit-style sanity checks that exercise both runtime paths. These tests verify that contextMessages() correctly handles an OMP-style manager with buildSessionContext() and a Pi-style manager with buildContextEntries().
import {
contextMessages,
latestMarkerIsActive,
} from "../extensions/context-compat";
const ACTIVE = "i-have-adhd-rules";
const DISABLED = "i-have-adhd-disabled";
const ompMgr = {
buildSessionContext: () => ({ messages: [{ role: "custom", customType: ACTIVE }] })
};
console.assert(contextMessages(ompMgr).length === 1);
const piMgr = {
buildContextEntries: () => [{ type: "custom_message", customType: ACTIVE }]
};
console.assert(contextMessages(piMgr).length === 1);
const markers = [
{ role: "custom", customType: ACTIVE },
{ role: "custom", customType: DISABLED },
{ role: "custom", customType: ACTIVE },
];
console.assert(latestMarkerIsActive(markers, ACTIVE, DISABLED));
This stand-alone script demonstrates that the abstraction works for both platforms and that marker evaluation respects chronological order.
Summary
extensions/context-compat.tsbridges the Pi and OMP session-manager APIs by normalizingbuildContextEntries()andbuildSessionContext()into a single array of markers.contextMessages()provides fail-open error handling, returning an empty array when the manager is missing or throws.latestMarkerIsActive()determines whether the most recent state marker is active or has been superseded by a disable marker.- The module keeps
extensions/i-have-adhd.tsplatform-agnostic and protects against future changes in session-manager implementations.
Frequently Asked Questions
What runtimes does the context-compat.ts module support?
The module supports the Pi runtime, which uses buildContextEntries(), and the OMP runtime, which uses buildSessionContext(). Both return conversation context data, but the wrapper methods and object shapes differ.
What happens if the session manager is null or throws an error?
The contextMessages() function returns an empty array. This fail-open design prevents the i-have-adhd extension from crashing during session startup when the manager is unavailable or the underlying API throws.
How does i-have-adhd.ts know whether to inject its ruleset?
extensions/i-have-adhd.ts calls rulesAreInContext(), which uses contextMessages() to fetch normalized markers and latestMarkerIsActive() to check whether the latest "i-have-adhd-rules" marker is still active. If the rules are not present or have been disabled, the extension re-injects them.
Where can I find the actual ADHD ruleset that gets injected?
The ruleset content lives in skills/i-have-adhd/SKILL.md. The compatibility layer itself does not contain the rules; it only ensures the extension can safely detect whether that content is already present in the model's conversation context.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →