feat(sdk): add WorkflowBuilder.paths() for multi-repo cloud workflows#814
feat(sdk): add WorkflowBuilder.paths() for multi-repo cloud workflows#814khaliqgant merged 1 commit intomainfrom
Conversation
Phase B of the multi-repo cloud workflow rollout (relay#774, cloud#302)
shipped the CLI-side regex parser and the cloud-side bootstrap, but
never added a fluent `.paths(...)` method on the SDK WorkflowBuilder.
Workflows that called `.paths(...)` therefore tarballed correctly at
submit time but threw `TypeError: ... .paths is not a function` once
the runtime evaluated the file inside the sandbox, because the method
didn't exist on the builder the sandbox imports from
`@agent-relay/sdk/workflows`.
Add the missing builder method:
workflow('multi-repo')
.paths([
{ name: 'alpha', path: 'alpha' },
{ name: 'beta', path: 'beta' },
])
.step(...)
.run();
The runner does not consume `paths` to execute steps — that's still a
CLI/cloud concern — but recording it on the built RelayYamlConfig
keeps single-source-of-truth for tools that walk the config (dry-run
reports, dashboards, the cloud bootstrap). Validation is up front:
non-arrays, entries missing name/path, and duplicate names all throw
at builder time so misconfiguration surfaces locally before submit.
`PathDefinition` already existed in `types.ts`; this PR only wires
the fluent setter that callers expect to exist.
Tests: 7 unit tests for the new method (recording, omission when
unset, copy-on-input, validation errors, chain return). SDK suite
otherwise unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe PR adds a fluent ChangesPath Definitions API
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/sdk/src/workflows/builder.ts`:
- Around line 268-270: The current .paths() validation only checks that p.name
and p.path are strings but allows empty or whitespace-only values; update the
validation in builder.ts (the .paths() handling where p is validated) to reject
blank values by trimming p.name and p.path and ensuring their trimmed length is
> 0, and throw a clear error (e.g., ".paths() entries must each have non-empty
string `name` and `path` fields") referencing p.name and p.path when the check
fails.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: db5c0771-3631-48b4-b539-db1ddb6d650c
📒 Files selected for processing (2)
packages/sdk/src/workflows/__tests__/builder-paths.test.tspackages/sdk/src/workflows/builder.ts
| if (!p || typeof p.name !== 'string' || typeof p.path !== 'string') { | ||
| throw new Error('.paths() entries must each have string `name` and `path` fields'); | ||
| } |
There was a problem hiding this comment.
Reject blank name/path values in .paths() validation.
Current validation allows empty/whitespace strings, which can produce invalid declared paths in emitted config.
Suggested patch
- if (!p || typeof p.name !== 'string' || typeof p.path !== 'string') {
- throw new Error('.paths() entries must each have string `name` and `path` fields');
+ if (
+ !p ||
+ typeof p.name !== 'string' ||
+ typeof p.path !== 'string' ||
+ p.name.trim().length === 0 ||
+ p.path.trim().length === 0
+ ) {
+ throw new Error('.paths() entries must each have non-empty string `name` and `path` fields');
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!p || typeof p.name !== 'string' || typeof p.path !== 'string') { | |
| throw new Error('.paths() entries must each have string `name` and `path` fields'); | |
| } | |
| if ( | |
| !p || | |
| typeof p.name !== 'string' || | |
| typeof p.path !== 'string' || | |
| p.name.trim().length === 0 || | |
| p.path.trim().length === 0 | |
| ) { | |
| throw new Error('.paths() entries must each have non-empty string `name` and `path` fields'); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/sdk/src/workflows/builder.ts` around lines 268 - 270, The current
.paths() validation only checks that p.name and p.path are strings but allows
empty or whitespace-only values; update the validation in builder.ts (the
.paths() handling where p is validated) to reject blank values by trimming
p.name and p.path and ensuring their trimmed length is > 0, and throw a clear
error (e.g., ".paths() entries must each have non-empty string `name` and `path`
fields") referencing p.name and p.path when the check fails.
Summary
pathsand the cloud bootstrap that mounts each declared path, but never added a fluent.paths(...)method on the SDKWorkflowBuilder. Workflows that wrote the natural formTypeError: ... .paths is not a functionthe moment the sandbox runtime evaluated the file, because the builder the sandbox imports from@agent-relay/sdk/workflowshad no such method.What changes
packages/sdk/src/workflows/builder.ts: import the existingPathDefinitiontype, add a_pathsprivate field onWorkflowBuilder, add apaths(paths: PathDefinition[]): thismethod with up-front validation (non-array, missingname/path, duplicate names all throw at builder time), and thread_pathsintotoConfig()so the field lands on the builtRelayYamlConfig.packages/sdk/src/workflows/__tests__/builder-paths.test.ts: 7 focused tests — recording, omission when unset, defensive copy-on-input, three validation paths, and the chain-return contract.What does NOT change
pathsto execute steps — that's a CLI/cloud concern. Adding the method is purely about being a no-op-at-runtime, single-source-of-truth setter for tools that walk the built config (dashboards, dry-run reports, cloud bootstrap).PathDefinitiontype already existed intypes.ts; this PR only wires the fluent setter that callers expect to exist.Once published + snapshot rebuilt
Workflow authors can swap the current Phase-B workaround
back to the natural fluent form
without the runtime TypeError.
Test plan
vitest run packages/sdk/src/workflows/__tests__/builder-paths.test.ts— 7/7 passingmain(workflow-runner.test.ts"record review completion in trajectory" — unrelated to this change, also fails onorigin/mainHEAD)tsc --noEmitagainstpackages/sdk— clean@agent-relay/sdkso existing relax + bootstrap PRs (cloud#423/fix: add fallback logic for cross-machine message delivery #425/daytona + sdk work #431) close out the demo end-to-end.🤖 Generated with Claude Code