How `latestMarkerIsActive` Works in the i-have-adhd Extension: State Detection Explained

latestMarkerIsActive checks a list of context messages and returns true if the most recent marker indicates that a ruleset is currently active, false otherwise.

The latestMarkerIsActive function is the core state-detection utility in the i-have-adhd open-source extension. It determines whether the ADHD ruleset is currently present in the model's context window by scanning custom marker messages and applying a "last-write-wins" precedence rule. This article breaks down the implementation in extensions/context-compat.ts and shows how the main extension logic uses it to sync state.

What latestMarkerIsActive Does

The function solves a specific problem: context windows accumulate messages over time, and markers can be added or removed dynamically. Simply checking for the presence of an "active" marker isn't enough—an "active" marker followed by a "disabled" marker means the ruleset is currently off.

latestMarkerIsActive walks through messages in chronological order and tracks the most recent state change. It takes three parameters:

  • messages: an array of ContextMessageMarker objects from the session manager
  • activeType: the customType string that indicates activation (e.g., "i-have-adhd-rules")
  • disabledType: the customType string that indicates deactivation (e.g., "i-have-adhd-disabled")

Implementation in extensions/context-compat.ts

The source code lives at lines 41–60 of extensions/context-compat.ts:

export function latestMarkerIsActive(
  messages: readonly ContextMessageMarker[],
  activeType: string,
  disabledType: string,
): boolean {
  let active = false;

  for (const message of messages) {
    // Only consider custom-type markers injected by the extension
    if (message.role !== "custom" && message.type !== "custom_message") {
      continue;
    }

    if (message.customType === activeType) {
      active = true;               // an "active" marker was seen
    } else if (message.customType === disabledType) {
      active = false;              // a later "disabled" marker overrides it
    }
  }

  return active;
}

Filtering Logic

The function ignores non-marker messages by checking two fields:

  • message.role === "custom" — the message originates from the extension, not the user or model
  • message.type === "custom_message" — the message is a custom injection, not standard chat content

Only messages satisfying both conditions are evaluated for state changes.

Precedence Rule

The loop uses a simple boolean flag that gets overwritten by each matching marker. This guarantees that the final value reflects the most recent relevant marker in the context window. An early "active" marker followed by a later "disabled" marker results in false.

Practical Usage: Checking ADHD Rules State

The main extension file extensions/i-have-adhd.ts calls latestMarkerIsActive to decide whether to inject or retract the ruleset. Here's the typical check (around lines 101–110):

import { contextMessages, latestMarkerIsActive } from "./context-compat";

function rulesAreInContext(ctx: ExtensionContext): boolean {
  return latestMarkerIsActive(
    contextMessages(ctx.sessionManager),          // ← all custom markers
    "i-have-adhd-rules",                         // active marker type
    "i-have-adhd-disabled",                     // disabled marker type
  );
}

State-Driven Message Injection

The boolean result drives the extension's main control flow. When the user toggles ADHD mode, the extension compares the desired state against the detected state:

if (enabled && !rulesAreInContext(ctx)) {
  // Inject the ADHD ruleset because it isn't present yet
  pi.sendMessage({ customType: "i-have-adhd-rules", content: rules, display: false });
} else if (!enabled && rulesAreInContext(ctx)) {
  // Retract the ruleset because ADHD mode was turned off
  pi.sendMessage({ customType: "i-have-adhd-disabled", content: DISABLED_NOTICE, display: false });
}

This pattern prevents duplicate injections and ensures the ruleset is properly cleaned up when disabled.

Key Design Characteristics

Aspect Implementation Detail
Time complexity O(n) — single pass through the message array
Space complexity O(1) — single boolean accumulator
Precedence behavior Last matching marker wins
Message filtering Requires role: "custom" AND type: "custom_message"
Return type booleantrue if active marker is most recent

Summary

  • latestMarkerIsActive in extensions/context-compat.ts detects whether a ruleset is currently active by scanning context messages in order.
  • It filters non-custom messages and tracks state changes via a boolean flag that gets overwritten by each matching marker.
  • The latest marker takes precedence, so a "disabled" marker always overrides an earlier "active" one.
  • The main extension logic in extensions/i-have-adhd.ts uses this utility to avoid redundant injections and properly clean up when ADHD mode is toggled off.

Frequently Asked Questions

What happens if no markers are found?

The function returns false. The active variable initializes to false and only flips to true if an activeType marker is encountered. With no matching markers, the default inactive state is returned.

Why check both role and type instead of just one?

The dual check ensures robust filtering. According to the i-have-adhd source code, custom marker messages must satisfy both conditions: role === "custom" identifies extension-originated messages, while type === "custom_message" distinguishes them from other custom role variants. This prevents accidental matching of unrelated message types.

Can the active and disabled types be the same string?

Technically yes, but this would cause unpredictable behavior. The else if structure prioritizes the disabled check, so a matching string would always result in false. The extension uses distinct strings ("i-have-adhd-rules" vs "i-have-adhd-disabled") to avoid this collision.

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 →