VS Code Extension
The FlowForger extension for Visual Studio Code adds language support and a debugger for FlowForger DSL files (.ff.ts). The language server, compiler, emitter and debugger are bundled with the extension, so it needs no workspace setup and no separate Node.js installation. For CI and deployment, use the CLI.
Install
Search for FlowForger in the Extensions view, or install it from the command line:
code --install-extension flowforger.flowforger-vscode
The extension requires VS Code 1.90 or later. It activates when the workspace contains a .ff.ts file.
Language features
Files ending in .ff.ts open in the FlowForger DSL language mode, with:
- Completions for
ctx.*methods, connectors and their operations, action names inctx.body('…')/ctx.outputs('…'), variables and connection references. Quick suggestions are on inside strings, so action names complete as you type the quote. - Diagnostics as you type: TypeScript syntax errors, plus the FlowForger rules (
DSL…codes) that catch flows the compiler would mis-compile or the cloud would refuse to save, such as an action call withoutawait, aResponseinside a loop, or a reference to an action that is not on therunAfterpath. The codes are listed in Diagnostics.flowforger validatereports the same rules on the command line. - Hover documentation for methods and decorators.
- Go to Definition and Find All References for action names, variables and other identifiers.
- Syntax highlighting for FlowForger decorators and methods.
- Snippets. Type a prefix and accept the suggestion:
| Prefix | Inserts |
|---|---|
flow-class / ff-flow | A complete flow class |
flow-recurrence / ff-recurrence | A flow with a Recurrence trigger |
http, compose, parsejson, respond, terminate | The matching action |
init-var, set-var | Initialize or set a variable |
if, foreach, scope | Control flow blocks |
sp-getitems, sp-createitem | SharePoint get items / create item |
dv-listrows, dv-createrow | Dataverse list rows / create a row |
body, outputs, triggerbody, variables | Expression helpers |
DSL files need no imports: @Flow, @Action, the trigger decorators and FlowContext are known to both the compiler and the extension.
Commands
Open the Command Palette (Ctrl+Shift+P, or Cmd+Shift+P on macOS) and type "FlowForger":
| Command | What it does |
|---|---|
| FlowForger: Compile to IR | Saves the active .ff.ts file and writes <name>.ir.json next to it |
| FlowForger: Compile to Logic Apps JSON | Saves the file and writes <name>.clientdata.json next to it, using the connection references in flowforger.config.json (workspace root first, then the file's folder) |
| FlowForger: Debug Flow | Starts the debugger on the active file |
| FlowForger: Connect Data Sources (schema completions) | Signs in to the Dataverse and SharePoint resources from your config, for schema completions (see below) |
| FlowForger: Restart Language Server | Restarts the language server |
Settings
| Setting | Default | Description |
|---|---|---|
flowforger.enable | true | Enable the language features. When off, the language server is not started |
flowforger.trace.server | off | Trace the communication with the language server (off, messages, verbose) in the Output panel |
Debugging
Open a .ff.ts file and press F5, or run FlowForger: Debug Flow. Without a launch.json, the debugger runs the active file. To pass input or tokens, add a configuration (the FlowForger: Debug Current Flow snippet creates one):
{
"version": "0.2.0",
"configurations": [
{
"type": "flowforger",
"request": "launch",
"name": "Debug FlowForger Flow",
"program": "${file}",
"triggerPayload": "${workspaceFolder}/payloads/order.json",
"variables": {},
"parameters": {},
"stopOnEntry": false,
"auth": true
}
]
}
| Attribute | Description |
|---|---|
program | The .ff.ts file to debug (required) |
triggerPayload | The trigger body: a JSON object, or the path to a .json file |
variables | Initial variable values |
parameters | Flow parameter values, by parameter key |
stopOnEntry | Pause before the first action (default false) |
auth | Acquire tokens automatically (see Signing in) |
config | Path to flowforger.config.json (default: the workspace root, then the flow's folder) |
spToken, dvUrl, dvToken, graphToken | Explicit tokens, instead of auth |
The run is local, with the same engine as flowforger run: connector and HTTP actions call the real services with your tokens.
Breakpoints and stepping
- Click in the gutter to set a breakpoint on an action. The debugger pauses before the action runs.
- Conditional breakpoints: right-click a breakpoint, choose Edit Condition, and enter a DSL-style expression such as
item.Status === 'Rejected'. The debugger pauses only when it evaluates to exactlytrue. A condition that fails to evaluate, or that is not a boolean, pauses anyway and says why in the Debug Console, so a typo never silently disarms the breakpoint. - Step Over (F10) runs one action. Step Into (F11) on a "Run a Child Flow" action steps into the child flow, when its
.ff.tsfile is found next to the parent (or throughdslPathinctx.flow.childFlows). Step Out (Shift+F11) continues. - The Variables view shows four scopes: Variables, Action Outputs (each action's outputs, and for connector, HTTP and child-flow actions the resolved inputs it was called with), Trigger Data and Parameters.
- The Debug Console, Watch expressions and hovers evaluate DSL expressions (
ctx.body('Get_items')?.['value']), Power Automate expressions starting with@, or a bare variable or action name.
Edit and Continue
While paused, edit the flow and press Restart (Ctrl+Shift+F5). The run restarts with your changes:
- Connector and HTTP calls recorded so far are replayed instead of sent again. A call whose inputs your edit changed runs live. Inputs that differ on every run, such as
utcNow()orguid(), do not count as a change. - The debugger fast-forwards to where you were paused, or to the first action that now behaves differently.
Restarting while not paused starts a clean run.
Jump to Cursor (Set Next Statement)
While paused, right-click a line and choose Jump to Cursor to move the execution point:
- Backward re-runs actions from there, against the current state, with live connector calls.
- Forward skips the actions in between.
The session pauses again before the target. A jump is refused while the file has edits you have not applied: restart to apply them, or revert them. When paused inside a branch of a condition, scope or switch, or inside a loop iteration, a backward jump restarts the run instead, replaying recorded calls up to the target and running live from there. Variable changes made from the Debug Console are not kept in that case.
Signing in
Debugging with "auth": true, schema completions and Connect Data Sources use the app registration in the auth section of flowforger.config.json (clientId, tenantId, resources). FlowForger ships no built-in client ID; see App registration, and flowforger init to write the config.
- When a sign-in is needed, a notification shows the device code (also copied to the clipboard) with an Open Browser button. Progress is written to the FlowForger Auth output channel.
- The extension keeps its own token cache at
~/.flowforger/vscode-token-cache.json, separate from the CLI's~/.flowforger/token-cache.encrypted.json, so you sign in once for each. - A debug session with
authrequests only the scopes the flow needs, including the connectors used by child flows it can find. - With a Dataverse connection, flow parameters backed by environment variables (keys ending in
(schema_name)) get their current values from the environment. A value given underparametersin the launch configuration wins over the environment's value, as--paramdoes in the CLI.
Schema completions
Inside ctx.connectors.dataverse.* and ctx.connectors.sharepoint.* calls, the extension completes names from your real environment:
- Dataverse table logical names (
entityName:). - SharePoint sites (
dataset:) and lists (table:, which inserts the list GUID, labelled with its title). - Column and field names in
item: { … }keys and in$select,$orderbyand$filterstrings.
Sibling parameters are read from string literals, or from the default value of a ctx.parameters('…') parameter.
Completions never start a sign-in while you type. They use only tokens the extension's cache can provide silently, and show nothing when there are none. To enable them, run FlowForger: Connect Data Sources once (or start a debug session with auth). The Dataverse resource comes from auth.resources.dataverse; the SharePoint resource from auth.resources.sharepoint, or else from a SharePoint dataset: URL in the active file. After signing in, lookups that failed earlier are retried.
See also
- MCP debug server: the same debugger, driven by an AI agent.
- Local testing: mocks and stop-before from the CLI.
- DSL overview.