Today, when a block needs to determine "am I ready to run?", two independent systems analyze its template content:
extractTemplateVariables — finds {{ .VarName }} references and checks them against registered <Inputs> data
extractOutputDependencies — finds {{ ._blocks.*.outputs.* }} references and checks them against block output data
Both parse the same {{ }} blocks, both feed into separate "unmet dependencies" warnings, and every block component (Command, Check, Template, TemplateInline) wires them up independently. The two systems don't know about each other, which led to a bug where _blocks appeared in both (fixed with a variables.delete('_blocks') exclusion in extractTemplateVariables).
At render time, buildInputsWithBlocks() merges inputs and outputs into a single map anyway; the split only exists for readiness checking.
Proposed change
Replace the two extractors with a single extractTemplateDependencies function that classifies each reference:
type TemplateDependency =
| { type: 'input'; name: string }
| { type: 'output'; blockId: string; outputName: string }
Then provide a single useTemplateDependencies hook (or similar) that takes the classified list and resolves readiness against both blockInputs and blockOutputs. Block components would replace their current dual wiring with one call.
What this simplifies
- Eliminates the
_blocks exclusion hack
- Removes duplicated "unmet dependencies" warning logic across 4+ components
- Single parse pass over template content instead of two
- Clearer mental model for contributors: one system, not two
Suggested timing
Good candidate to do alongside the next feature that touches the dependency system. Not urgent — the current system works and the seams are mostly hidden from runbook authors.
Today, when a block needs to determine "am I ready to run?", two independent systems analyze its template content:
extractTemplateVariables— finds{{ .VarName }}references and checks them against registered<Inputs>dataextractOutputDependencies— finds{{ ._blocks.*.outputs.* }}references and checks them against block output dataBoth parse the same
{{ }}blocks, both feed into separate "unmet dependencies" warnings, and every block component (Command, Check, Template, TemplateInline) wires them up independently. The two systems don't know about each other, which led to a bug where_blocksappeared in both (fixed with avariables.delete('_blocks')exclusion inextractTemplateVariables).At render time,
buildInputsWithBlocks()merges inputs and outputs into a single map anyway; the split only exists for readiness checking.Proposed change
Replace the two extractors with a single
extractTemplateDependenciesfunction that classifies each reference:Then provide a single
useTemplateDependencieshook (or similar) that takes the classified list and resolves readiness against bothblockInputsandblockOutputs. Block components would replace their current dual wiring with one call.What this simplifies
_blocksexclusion hackSuggested timing
Good candidate to do alongside the next feature that touches the dependency system. Not urgent — the current system works and the seams are mostly hidden from runbook authors.