Task Frontmatter Reader
Thin wrapper around the real script ${CLAUDE_PLUGIN_ROOT}/scripts/fm-read.sh. The script is a deterministic file-parsing pipeline (bash + python3 + jq); this skill exists to give it a name callable via the Skill tool and to document its contract.
Contract
Input: one argument — absolute path to a task folder. Output: a single-line JSON object to stdout. Exit code always 0.
Always-present fields:
id—local:<folder-name>(URI style)kind— one offlat | epic | sub_epic | subtaskparent—local:<id>ornullchildren— array oflocal:<id>stringsblocks— array oflocal:<id>stringsblocked_by— array oflocal:<id>stringsexternal_ids— object (reserved for future tracker integration; currently{})status—draft | in_progress | blocked | completedmechanism_hints— array of{approach, status}(status: suggested | required); the optional mechanism-challenge contract (GAP G,references/mechanism-challenge.md). Defaults to[]when absent — read-if-present; the challenge's prose-extraction floor applies otherwise.folder— absolute path passed inwarnings— array of{code, detail}entries
Defensive posture. Never throws, never blocks, never exits non-zero. All error conditions surface as entries in warnings[]. Callers should treat warnings as observations, not failures.
| Input state | Resulting warnings |
|---|---|
| Folder does not exist | folder_missing |
Folder exists, task.md missing |
task_md_missing |
task.md present, no frontmatter block |
(none — absence of frontmatter is legitimate; kind defaults to flat) |
| Frontmatter YAML malformed | malformed_yaml |
| python3 / yaml unavailable | parser_unavailable |
Invocation
Call the script directly via the Bash tool:
"${CLAUDE_PLUGIN_ROOT}/scripts/fm-read.sh" "/absolute/path/to/task/folder"
Parse the JSON output with jq. Example:
OUTPUT=$("${CLAUDE_PLUGIN_ROOT}/scripts/fm-read.sh" "$TASK_DIR")
KIND=$(jq -r '.kind' <<<"$OUTPUT")
WARNINGS=$(jq -c '.warnings' <<<"$OUTPUT")
Why this is a script, not embedded instructions
Earlier drafts of this skill embedded the parser logic in the skill body as bash pseudo-code. A paper-test (2026-04-22) showed this led to pseudo-function references that would force Claude to re-implement helpers each invocation, with the risk of divergent implementations across runs. The script-based design eliminates that class of bug: the implementation is a single file that can be tested once and reused deterministically.
Consumers (v2.0.0+)
/ai-dev-assistant:migrate-to-epic— preflight kind checkepic-migratorskill — Step 4 validation of generated frontmatter/status,/next,/complete— kind detection for hierarchy-aware rendering
Do NOT
- Do not duplicate the parser logic elsewhere. If another skill needs to read frontmatter, it should call
fm-read.shor sourcefm-helpers.shdirectly (for helper bash functions likefm_read,write_epic_frontmatter, etc.). - Do not treat a non-empty
warnings[]as a blocking error. The contract says warnings are observations. - Do not write to task.md from this skill. Reading is the sole purpose; migration and phase updates live elsewhere.