Conversation
…try, escape pipes Closes #59 #54 #53 #61 #58 - #59 outputSchema: declare a step's output shape so downstream $.steps.X.output.field references are validated at flow load time. Catches the most common wiring bug (typo'd field names). - #54 bash env JSON-safe injection: bash step env values now accept { json: ... } (serialized to a temp file, env var holds the path, auto-cleaned) and { shell: ... } (resolved + safely word-split via bash double-quotes). Eliminates the file-write→bash workaround. - #53 conditional retry: onError now supports retryOn / failFastOn so transient (429, 502, ETIMEDOUT) and permanent (401, 403, 404) failures are handled differently. failFastOn takes precedence; retryOn requires a match. - #53 Handlebars escape pipes: {{ \$.x | json|shell|url|md|html }} for context-aware escaping at the template level. Replaces per-call sanitization. - #61 dynamic flow.key dispatch: flow.key already accepted selectors via resolveValue, but the spaced-pipe routing fix here makes it fully reliable; covered by new tests. - #58 parallel partial results: $.steps.X.status / errorCode / durationMs metadata is exposed on parallel substeps so downstream gates can branch on timeout vs failure; covered by new tests. Stress-tested by 6 parallel sub-agents — caught two real bugs that are also fixed here: 1. validateOutputSchemas was duplicate-reporting errors for selectors inside loop/condition/parallel substeps (walkValue recursed into nested step arrays that walkSteps also visited). Fixed by skipping nested-steps fields in walkValue. 2. resolveValue's routing check (\`value.includes('{{\$.')\`) missed the space-padded form \`{{ \$.x | json }}\`. Fixed by switching to a regex that matches optional whitespace. 23 new unit tests added; 70 total / 69 passing (1 pre-existing While Loop failure unrelated to this change). Docs updated in skills/one/references/flows.md and the auto-generated guide via src/lib/flow-schema.ts. Version bumped to 1.27.0. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bundles five flow-engine quick wins into a single PR. Closes #59, #54, #53, #61, #58.
outputSchema— declare a step's output shape so downstream$.steps.X.output.fieldreferences are validated at flow load time. Catches typo'd field names — the most common wiring bug in complex flows.envvalues now accept{ json: ... }(JSON-serialized to a temp file, env var holds the path, auto-cleaned after the step) and{ shell: ... }(resolved + safely word-split via bash double-quotes). Eliminates thefile-write → bashworkaround pattern.onErrorsupportsretryOn/failFastOnso transient errors (429, 502, ETIMEDOUT) and permanent errors (401, 403, 404) are handled differently.failFastOntakes precedence;retryOn(when set) requires a match.{{ $.x | json|shell|url|md|html }}for context-aware escaping at the template level. Removes the need for per-call sanitization steps.flow.keydispatch —flow.keyaccepts a selector or Handlebars interpolation, so a single orchestrator can route to different sub-flows at runtime. Verified end-to-end with new tests.$.steps.X.status/errorCode/durationMs/errorare exposed on parallel substeps so downstream gates can branch on timeout vs failure; covered by new tests.Stress testing
After implementation, 6 parallel sub-agents ran adversarial test suites against each new feature plus a regression sweep. They found two real bugs, both fixed in this PR:
validateOutputSchemaswas double-reporting errors for selectors inside loop/condition/parallel substeps (walkValuerecursed into nested step arrays thatwalkStepsalso visited). Fix: skip nested-steps fields inwalkValue.resolveValue's routing check (value.includes('{{$.')) silently ignored the space-padded pipe form{{ $.x | json }}. Fix: routing check now uses a regex that allows optional whitespace.Both bugs have regression tests.
Test plan
npx tsx test-flow-features.ts— 70 tests, 69 passing (1 pre-existing While Loop failure unrelated to this change)npm run typecheck— only pre-existing errors inrelay.ts/flow-runner.tsremainnpm run build— cleanDocs
skills/one/references/flows.md— new sections on bash structured env, conditional retry, escape pipes, dynamic flow.key, and outputSchemasrc/lib/flow-schema.ts— auto-generated guide picks upoutputSchemain the common-fields table and gets new prose sections for the same featuresVersion
Bumped to 1.27.0 (minor — additive features, no breaking changes).
🤖 Generated with Claude Code