Flows
Flows are executable .js scripts that run at native JavaScript speed — no LLM tokens consumed. A login flow that takes 5 LLM iterations (~50 seconds) executes in 2 seconds via Flow.run().
Why Flows
- Speed — native JS execution, not LLM round-trips
- Cost — $0 per run for known workflows
- Determinism — same steps, same order, repeatable
- Composability — chain flows into orchestrators
- Maintainability — plain JS, readable, version in git
Writing a Flow
// flows/app/login.js
function(args) {
agent.go(args.url || 'https://app.example.com/login')
agent.act('{input}Username', 'input', args.username)
agent.act('{input}Password', 'input', args.password)
agent.act('{button}Sign In', 'click')
agent.wait('navigation')
return { ok: true }
}
Flows are plain JavaScript functions that receive an args object and return a result.
Running a Flow
// From Interactive mode or another flow
Flow.run('app/login', { username: 'admin', password: 'secret' })
// Returns: { ok: true }
Composing Flows
Chain multiple flows into an orchestrator:
// flows/gw/full-submission.js
function(args) {
Flow.run('gw/login', { user: args.user, pass: args.pass })
Flow.run('gw/new-submission', { lob: 'PersonalAuto' })
Flow.run('gw/add-driver', args.driver)
Flow.run('gw/add-vehicle', args.vehicle)
Flow.run('gw/quote')
return { ok: true }
}
Each step runs at native speed. The orchestrator completes in seconds, not minutes.
Deviation Reporting
When a flow step fails:
- The error, source location, and current page state are captured
- In autonomous mode, the LLM receives this context and attempts recovery
- Deviations are flagged in the test report
This means the LLM only runs when something unexpected happens — keeping costs minimal.
Flow File Organization
flows/
├── app/
│ ├── login.js
│ ├── navigate.js
│ └── logout.js
├── gw/ # Guidewire-specific
│ ├── login.js
│ ├── new-submission.js
│ ├── add-driver.js
│ └── full-submission.js
└── common/
├── wait-for-load.js
└── take-screenshot.js
Flows in Git
When the flows/ directory is a git repository, the standard version control workflow applies:
- Code review — flow changes go through the same PR process as application code
- Branching — experiment with new locator strategies in a branch
- History —
git log flows/gw/login.jsshows who changed what and when - LLM collaboration — Claude Code, Cursor handle git operations natively
Creating Flows Interactively
The typical workflow:
- Start an Interactive session
- Use
look()andact()to discover the working interaction pattern - Write the flow file:
File.write('flows/app/login.js', content) - Test it:
Flow.run('app/login', {username: 'admin', password: 'secret'}) - Iterate until reliable