# How the i-have-adhd Plugin Strips Frontmatter: A Complete Technical Breakdown

> Discover how the i-have-adhd plugin strips frontmatter. Learn its technical process for removing YAML delimiters and preserving file content. Understand its functionality.

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

---

**The i-have-adhd plugin removes YAML frontmatter by checking for opening `---` delimiters at the start of the file, locating the closing `---` delimiter on a new line, and returning only the content that follows—preserving the entire file unchanged if the fence is unterminated.**

The **i-have-adhd** repository (available at `ayghri/i-have-adhd`) implements a consistent frontmatter-stripping strategy across multiple runtime environments. This ensures that markdown skill files containing YAML metadata are cleaned before being processed by agents. The implementation prioritizes safety: an unterminated frontmatter block is never stripped, preventing accidental data loss.

Below is a comprehensive walkthrough of the architecture, key source files, and exact algorithms used.

## The Core Algorithm Used Across All Components

Every implementation—whether in JavaScript, Bash, or PowerShell—follows the same three-step logic:

1. **Fast-path rejection**: If the content does not start with `---`, return unchanged.
2. **Locate closing fence**: Search for `\n---` (newline followed by three dashes) starting after position 3.
3. **Slice and trim**: If found, return everything after the closing delimiter line, trimmed of leading whitespace. If not found, return the original content.

This algorithm is intentionally conservative. It only strips frontmatter when both delimiters are present and properly formatted.

## JavaScript Implementations

### Plugin Loader: `.opencode/plugins/i-have-adhd.mjs`

The primary entry point for the plugin loads the skill definition from [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md) and applies the stripper before returning content to agents.

```javascript
// .opencode/plugins/i-have-adhd.mjs
import { readFile } from "node:fs/promises";
import { resolve } from "node:path";

const SKILL_PATH = resolve(import.meta.url, "../../../skills/i-have-adhd/SKILL.md");

function stripFrontmatter(md) {
    if (!md.startsWith("---")) return md;
    const endIdx = md.indexOf("\n---", 3);
    if (endIdx === -1) return md;
    return md.slice(endIdx + 4).trimStart();
}

export async function load() {
    const raw = await readFile(SKILL_PATH, "utf8");
    const content = stripFrontmatter(raw);
    return { name: "i-have-adhd", content };
}

export { stripFrontmatter };

```

Key implementation details:
- **`md.indexOf("\n---", 3)`**: The search starts at index 3 (after the opening `---`) to avoid matching the opening delimiter itself.
- **`md.slice(endIdx + 4)`**: Adds 4 to skip past `\n---` (newline plus three dashes).
- **`.trimStart()`**: Removes leading whitespace so the markdown content begins immediately at the first meaningful character.

### Always-On Hook: `hooks/always-on.mjs`

The runtime hook applies the same transformation to any skill source before parsing:

```javascript
// hooks/always-on.mjs
export function stripFrontmatter(md) {
    if (!md.startsWith('---')) return md;
    const end = md.indexOf('\n---', 3);
    if (end === -1) return md;
    return md.slice(end + 4).trimStart();
}

export function inject(context) {
    const raw = context.source;
    context.source = stripFrontmatter(raw);
}

```

The `inject()` function receives a context object containing the raw skill source, applies `stripFrontmatter()`, and replaces `context.source` with the cleaned version. This ensures consistency regardless of which loader initiates the skill.

## Shell Implementations for Cross-Platform Compatibility

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

For Unix-like environments, a Bash implementation provides identical behavior:

```bash
#!/usr/bin/env bash

# hooks/always-on.sh

content=$(cat "$1")
if [[ $content == "---"* ]]; then
    rest=$(printf "%s" "$content" | sed -n '/^---$/,/^---$/p' | tail -n +2)
    if [[ $rest != "$content" ]]; then
        echo "$rest"
        exit 0
    fi
fi
echo "$content"

```

The `sed` command uses range addressing (`/^---$/,/^---$/`) to capture lines between delimiters, and `tail -n +2` removes the opening delimiter line. The comparison `[[ $rest != "$content" ]]`
verifies that a closing delimiter was actually found.

### PowerShell: `hooks/always-on.ps1`

Windows environments use an equivalent PowerShell script (implementation follows the same pattern, available in the repository).

## Practical Code Example

Here's how to use the exported `stripFrontmatter` function directly:

```javascript
import { stripFrontmatter } from './.opencode/plugins/i-have-adhd.mjs';

const skillWithFrontmatter = `---
name: i-have-adhd
disable-model-invocation: true
always-on: true
---

# i-have-ADHD Skill

Your ADHD-friendly assistant that helps maintain focus...
`;

const cleanSkill = stripFrontmatter(skillWithFrontmatter);
console.log(cleanSkill);
// Output:
// # i-have-ADHD Skill

//
// Your ADHD-friendly assistant that helps maintain focus...

```

If the frontmatter is malformed or incomplete, the function returns the original unchanged:

```javascript
const malformed = `---
name: i-have-adhd

# Missing closing delimiter

Some content here...
`;

console.log(stripFrontmatter(malformed) === malformed); // true

```

## Key Files and Their Roles

| File Path | Purpose |
|-----------|---------|
| `.opencode/plugins/i-have-adhd.mjs` | Main plugin loader; reads [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md), applies `stripFrontmatter()`, returns cleaned skill content to agents |
| `hooks/always-on.mjs` | JavaScript always-on hook injected into every agent runtime; transforms `context.source` before parsing |
| [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh) | Bash equivalent for Unix-like shell environments |
| `hooks/always-on.ps1` | PowerShell equivalent for Windows environments |
| [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) | The actual skill definition containing YAML frontmatter that gets stripped |
| [`tests/test_always_on_hooks.py`](https://github.com/ayghri/i-have-adhd/blob/main/tests/test_always_on_hooks.py) | Unit tests validating correct behavior with closed, unclosed, and missing frontmatter |
| [`tests/test_opencode_plugin.py`](https://github.com/ayghri/i-have-adhd/blob/main/tests/test_opencode_plugin.py) | Tests ensuring plugin `stripFrontmatter` matches hook behavior |

## Why This Design Matters

**Safety over convenience**: The explicit requirement for a closing `\n---` delimiter prevents accidental stripping of files that happen to start with `---` but aren't actually frontmatter (for example, a horizontal rule or ASCII art).

**Consistency across runtimes**: By implementing identical logic in JavaScript, Bash, and PowerShell, the plugin guarantees uniform behavior regardless of deployment environment.

**Testability**: Both the plugin and hook export their `stripFrontmatter` functions, enabling direct unit testing without requiring full runtime initialization.

The `i-have-adhd` plugin's frontmatter stripping is a textbook example of defensive markdown processing—minimal, predictable, and thoroughly validated.

## Summary

- The **i-have-adhd plugin** strips frontmatter using a three-step algorithm: check opening delimiter, locate closing delimiter, slice and trim.
- The implementation is duplicated across `.opencode/plugins/i-have-adhd.mjs` and `hooks/always-on.mjs` with identical logic to ensure consistency.
- **Unterminated frontmatter blocks are preserved unchanged**, protecting against accidental data loss.
- Cross-platform shell implementations ([`always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/always-on.sh), `always-on.ps1`) provide the same behavior in non-JavaScript environments.
- The `stripFrontmatter` function is exported for direct use in tests and external tooling.

## Frequently Asked Questions

### What happens if the SKILL.md file doesn't have frontmatter?

The `stripFrontmatter` function checks `md.startsWith("---")` as its first operation. If this returns `false`, the original markdown is returned unchanged with zero modifications. This fast-path check ensures no unnecessary processing occurs on files without frontmatter.

### Can the frontmatter block contain nested `---` strings?

Yes. The algorithm searches specifically for `\n---` (newline followed by three dashes). This means `---` appearing within the frontmatter content on the same line—as part of a value or description—will not prematurely terminate the block. Only a delimiter appearing at the start of a new line ends the frontmatter section.

### Why does the closing delimiter need to be on a new line?

This requirement aligns with the YAML frontmatter specification and CommonMark conventions. The opening `---` must be at the absolute start of the file, and the closing `---` must follow a newline. This prevents ambiguity with horizontal rules (`---`) that may appear in document content, which are typically preceded by blank lines or other content.

### How can I test the frontmatter stripping behavior myself?

Import the exported `stripFrontmatter` function from either `.opencode/plugins/i-have-adhd.mjs` or `hooks/always-on.mjs` and pass various markdown strings to it. The repository's test suite in [`tests/test_opencode_plugin.py`](https://github.com/ayghri/i-have-adhd/blob/main/tests/test_opencode_plugin.py) and [`tests/test_always_on_hooks.py`](https://github.com/ayghri/i-have-adhd/blob/main/tests/test_always_on_hooks.py) provides additional examples of edge cases including empty frontmatter, missing delimiters, and frontmatter with complex values.