How to Filter Ponytail Skill Bodies to a Specific Mode Using JavaScript
Use the filterSkillBodyForMode(body, mode) function exported from hooks/ponytail-instructions.js to parse raw markdown skill content and return only the sections matching your target intensity (lite, full, or ultra).
The DietrichGebert/ponytail repository implements a mode-based skill filtering system that allows developers to programmatically extract specific intensity levels from Ponytail skill bodies using JavaScript. When working with LLM instructions stored in skills/ponytail/SKILL.md, you often need to present only the relevant content for a specific operational mode rather than the entire skill definition. This guide explains the exact implementation details and practical integration patterns for this filtering mechanism.
Core Filtering Architecture
The filtering system operates as a pure function pipeline that processes raw markdown strings without side effects. When you filter Ponytail skill bodies to a specific mode using JavaScript, the filterSkillBodyForMode function executes four distinct transformation steps to isolate mode-specific content while preserving generic instructional text.
The function signature is straightforward:
filterSkillBodyForMode(body, mode)
It accepts a raw markdown string (typically from skills/ponytail/SKILL.md) and a mode identifier, then returns a filtered markdown string containing only the relevant sections.
Step-by-Step Filtering Logic
The implementation in hooks/ponytail-instructions.js processes content through a rigorous normalization and parsing pipeline.
Mode Normalization and Defaults
Before processing begins, the function calls normalizeMode from hooks/ponytail-config.js (line 6) to resolve mode aliases to canonical values (lite, full, ultra). If an invalid mode is specified, the system falls back to DEFAULT_MODE to ensure predictable behavior.
Stripping YAML Front-Matter
Leading metadata blocks are removed using the regex /^---[\s\S]*?---\s*/ implemented at line 13. This ensures that YAML configuration headers do not contaminate the instructional text presented to the LLM.
Processing Intensity Table Rows
The filter detects mode-specific table rows using the pattern /^\|\s*\*\*(.+?)\*\*\s*\|/ (line 22). When a row starts with a bold cell containing a mode label (e.g., | **lite** |), the label is extracted, normalized, and retained only if it matches the effective mode. Unmatched intensity rows are discarded.
Handling Worked Examples
For quoted examples following the pattern - lite: "...", the regex /^-\s*([^:]+):\s*"/ (line 32) identifies the mode prefix. Lines are kept only when the extracted label aligns with the active mode, ensuring worked examples match the requested intensity level.
Preserving Generic Rules
Any line not matching table-row or example patterns passes through unchanged. This guarantees that universal instructions remain available regardless of the selected mode, as implemented in the filter callback spanning lines 21–38.
Practical Implementation Examples
Direct Node.js Script Usage
For standalone scripts or custom tooling, require the filter function directly and process skill files:
const fs = require('fs');
const { filterSkillBodyForMode } = require('./hooks/ponytail-instructions.js');
const raw = fs.readFileSync('skills/ponytail/SKILL.md', 'utf8');
const mode = 'ultra'; // could be 'lite', 'full', or 'ultra'
const filtered = filterSkillBodyForMode(raw, mode);
console.log(filtered);
This approach gives you complete control over file I/O and mode selection.
Pi Extension Integration
When working within the Ponytail Pi extension ecosystem, use the higher-level helper that wraps the filter:
const { getPonytailInstructions } = require('./hooks/ponytail-instructions.js');
(async () => {
const instructions = await getPonytailInstructions('lite');
console.log(instructions); // full instructions with only lite‑mode content
})();
This pattern handles async loading and automatically applies the filtering logic from hooks/ponytail-instructions.js.
Unit Testing Mode Filtering
Validate that your filtering logic correctly isolates mode-specific content:
const { filterSkillBodyForMode } = require('./hooks/ponytail-instructions.js');
const assert = require('assert');
const body = `
- Full: keep this rule.
- Lite: "example for lite"
- ultra: "example for ultra"
`;
assert.ok(filterSkillBodyForMode(body, 'ultra').includes('ultra:"'));
assert.ok(!filterSkillBodyForMode(body, 'ultra').includes('Lite:'));
This test verifies that the function correctly includes ultra-mode examples while excluding lite-mode content.
Key Source Files
hooks/ponytail-instructions.js– Contains the corefilterSkillBodyForModeimplementation and line processing logic.hooks/ponytail-config.js– DefinesnormalizeModeandDEFAULT_MODEconstants used during filtering.skills/ponytail/SKILL.md– Source markdown containing mode-specific tables and examples.pi-extension/index.js– Demonstrates export patterns for external consumption.pi-extension/test/helpers.test.js– Test suite validating filter behavior across all modes.
Summary
- Use
filterSkillBodyForModefromhooks/ponytail-instructions.jsto transform raw skill markdown into mode-specific content. - The function supports three canonical modes: lite, full, and ultra, with automatic fallback to
DEFAULT_MODEfor invalid inputs. - Content filtering preserves generic rules while extracting mode-specific tables (detected via
/^\|\s*\*\*(.+?)\*\*\s*\|/) and worked examples (detected via/^-\s*([^:]+):\s*"/). - The implementation deliberately maintains purity, accepting strings and returning strings to maximize reusability across hooks, extensions, and test suites.
Frequently Asked Questions
Where is the main filtering logic implemented?
The core implementation resides in hooks/ponytail-instructions.js, specifically within the filterSkillBodyForMode function spanning lines 21–40. This file handles mode normalization, front-matter stripping, and line-by-line content filtering.
How does the system handle invalid or unspecified modes?
The filter delegates mode validation to normalizeMode in hooks/ponytail-config.js. If the requested mode does not match canonical values (lite, full, ultra), the system automatically falls back to DEFAULT_MODE, ensuring the skill body always returns valid instructional content.
Can I use the Ponytail skill filter outside of the Pi extension?
Yes. The filterSkillBodyForMode function is designed as a pure utility that accepts a markdown string and mode identifier, returning a filtered string. This makes it suitable for Node.js scripts, CI/CD pipelines, custom LLM integrations, or any JavaScript context requiring mode-specific content extraction.
What happens to instructional content that does not specify a mode?
Any line that does not match the intensity table pattern (| **mode** |) or the worked example pattern (- mode: "...") passes through the filter unchanged. This ensures that universal guidelines, formatting instructions, and generic rules remain available regardless of which mode is active.
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 →