How to Add a New Runtime Platform to i-have-adhd from Scratch

Adding a new runtime platform to i-have-adhd requires creating a manifest JSON file, optionally implementing a TypeScript extension module, configuring persistent hooks in hooks/hooks.json, and validating the integration through the repository's test suite.

The i-have-adhd repository supports multiple AI runtimes—including Claude, Codex, Pi, OMP, OpenCode, Qwen, Kimi, and Gemini—through a unified extension architecture. Adding a new runtime platform follows a predictable pattern that ties together manifest declarations, optional runtime-specific code, and hook-based automation to integrate seamlessly with the existing skill system.

Define the Runtime Manifest

Every runtime platform begins with a declarative manifest that identifies the plugin and points to the shared skills directory.

Choose a Runtime Identifier

Select a short, lowercase identifier (e.g., myruntime) that will serve as the prefix for configuration files and JSON keys throughout the repository.

Create the Extension JSON

Create a <runtime>-extension.json file at the repository root, following the structure of qwen-extension.json. This file declares the plugin metadata and skill location.

{
  "name": "i-have-adhd",
  "version": "0.2.0",
  "description": "ADHD-friendly output shaping for MyRuntime: action first, numbered steps, no tangents, visible progress.",
  "skills": "skills"
}

Key requirements for this manifest:

  • The name field must remain i-have-adhd to identify the plugin.
  • The version should match the repository version specified in package.json (0.2.0 as of the current codebase).
  • The skills property points to the ./skills/ directory containing the prompt templates.

Add the Plugin Descriptor (If Required)

Some runtimes (Kimi, Gemini) utilize a *.plugin.json format instead of or in addition to the extension JSON. Duplicate the structure from kimi.plugin.json or gemini-extension.json and adapt the runtime-specific fields.

{
  "name": "i-have-adhd",
  "version": "0.2.0",
  "description": "Shape output for MyRuntime: lead with the next action, number steps, suppress tangents, restate state, make wins visible.",
  "license": "MIT",
  "homepage": "https://github.com/ayghri/i-have-adhd",
  "skills": "./skills/",
  "interface": {
    "displayName": "I Have ADHD",
    "shortDescription": "ADHD-friendly output shaping for MyRuntime CLI"
  }
}

Implement Runtime-Specific Code

Not all runtimes require custom code, but those with unique integration points (like Pi or OMP) need a TypeScript extension module.

Create the Extension Entry Point

Add a TypeScript file under extensions/ that exports runtime-specific helpers. Use extensions/i-have-adhd.ts as the reference implementation for Pi/OMP integration.

// extensions/myruntime.ts
export const myruntime = {
  // Insert runtime-specific initialization or helper functions here.
};

For minimal runtimes that only need manifest-based skill loading, you can export an empty object or omit this file entirely.

Register in package.json

If you created an extension module, register it in package.json under a runtime-specific key. For Pi and OMP, this appears as:

"pi": {
  "extensions": ["./extensions/i-have-adhd.ts"]
}

For a new runtime, add a corresponding top-level key:

"myruntime": {
  "extensions": ["./extensions/myruntime.ts"]
}

Configure Persistent Hooks

For runtimes requiring "always-on" background behavior, register persistent hooks in the central registry.

Register in hooks.json

Add an entry to hooks/hooks.json that maps your runtime identifier to an execution script.

{
  "runtime": "myruntime",
  "command": "always-on.mjs"
}

Create the Hook Script

Implement the corresponding script in the hooks/ directory. The script should import your extension module if runtime-specific logic is required.

// hooks/always-on.mjs
import { myruntime } from '../extensions/myruntime.ts';

export default async function () {
  // Runtime-specific initialization or monitoring logic.
}

Validate the Integration

Before publishing, verify that your runtime integrates correctly with the build system and test suite.

Update Documentation

Add the new runtime to the Runtime entry points table in AGENTS.md (lines 44–51) and include a brief description in the Repository map section (lines 33–35). If you created a *.plugin.json file, ensure the interface.displayName value appears in any UI-facing documentation.

Add Unit Tests

Create a test file under tests/ that validates manifest loading and extension exports. Follow the patterns established in tests/test_opencode_plugin.py and tests/test_omp_package.py to verify JSON schema compliance and module structure.

Run the Verification Suite

Execute the repository's validation commands to ensure no regressions:

python3 -m unittest discover -s tests -v
python3 scripts/run_evals.py validate
bun scripts/check_context_compat.ts

If your runtime requires dedicated CI validation, add a workflow file under .github/workflows/ (e.g., myruntime-load-check.yml) modeled after plugin-load-check.yml or pi-load-check.yml.

Publish the Runtime

For plugin-based runtimes (Claude, Codex, Kimi, Gemini), publish the new manifest to the respective marketplace using the runtime's CLI tools (e.g., claude plugin or codex plugin commands) as referenced in the Tune it section of README.md. Ensure the manifest files are committed to the repository root before distribution.

Summary

  • Manifest creation involves adding a <runtime>-extension.json (and optionally a <runtime>.plugin.json) to declare metadata and skills location.
  • Extension modules in extensions/ provide runtime-specific TypeScript glue code when native integration is required.
  • Hook registration in hooks/hooks.json enables persistent background behavior for supported runtimes.
  • Validation requires updating AGENTS.md, adding tests under tests/, and passing the full verification suite including check_context_compat.ts.
  • Publication follows runtime-specific marketplace workflows while maintaining the repository's structural conventions.

Frequently Asked Questions

What is the difference between -extension.json and .plugin.json files?

The -extension.json format serves as the base manifest used by most runtimes including Qwen and Gemini, declaring essential metadata like name, version, and skills. The .plugin.json format (seen in kimi.plugin.json) provides additional marketplace-specific metadata such as license, homepage, and interface display properties required by certain runtime ecosystems. You should provide both if your target runtime supports the plugin marketplace model.

Do I need to write TypeScript code for every new runtime?

No. Many runtimes—including Qwen and Gemini—require only the manifest JSON files to load the skills directory. You only need to create a TypeScript extension module (in extensions/) if your runtime requires custom initialization, API adapters, or runtime-specific helper functions, as implemented for Pi and OMP in extensions/i-have-adhd.ts.

How do I ensure my new runtime passes the repository's integrity checks?

Run the three-tier validation suite: python3 -m unittest discover -s tests -v for Python-based manifest tests, python3 scripts/run_evals.py validate for evaluation logic, and bun scripts/check_context_compat.ts for TypeScript compatibility. Additionally, create a runtime-specific test file following the patterns in tests/test_opencode_plugin.py to verify your JSON manifests parse correctly and your extension exports the expected object shape.

Where does the runtime identifier appear in the codebase beyond the manifest files?

The runtime identifier appears in four critical locations: the root manifest filename (<runtime>-extension.json), the hooks/hooks.json runtime field for persistent activation, the package.json key for extension registration (if using TypeScript modules), and the CI workflow filename (e.g., .github/workflows/<runtime>-load-check.yml) for automated testing. Consistent naming across these files ensures the build system recognizes your platform.

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 →