@@ -5,7 +5,7 @@ import { validateFlow } from "../core/validate.js";
55import type { FlowDefinition , FlowNode , PluginConfig , BranchNode , ConditionNode , LoopNode , ParallelNode } from "../core/types.js" ;
66
77// ---- OpenClaw Plugin: clawflow ---------------------------------------------------
8- // Registers nine tools:
8+ // Registers ten tools:
99//
1010// flow_create — create a new flow definition and save to file
1111// flow_delete — soft-delete a flow (moves to .bin/)
@@ -14,6 +14,7 @@ import type { FlowDefinition, FlowNode, PluginConfig, BranchNode, ConditionNode,
1414// flow_resume — resume after approval gate
1515// flow_send_event — push an event into a waiting flow
1616// flow_status — inspect a running/completed flow instance
17+ // flow_list — list all saved flow definitions in the workspace
1718// flow_transpile — convert a .flow definition to Cloudflare Workers TS
1819// flow_edit — edit nodes in a flow definition (file or inline)
1920
@@ -678,6 +679,120 @@ Status values: running | completed | paused | waiting | failed | cancelled`,
678679 { optional : true } ,
679680 ) ;
680681
682+ // ---- flow_list ----------------------------------------------------------------
683+
684+ api . registerTool (
685+ {
686+ name : "flow_list" ,
687+ description : `List all saved flow definitions in the workspace.
688+
689+ Scans the flows directory for .json files and returns a summary of each flow
690+ including its name, description, trigger, version, node count, and file path.
691+ Use this to discover available flows before running or editing them.` ,
692+
693+ parameters : {
694+ type : "object" ,
695+ properties : {
696+ dir : {
697+ type : "string" ,
698+ description :
699+ "Directory to scan. Defaults to workspace/flows/. Absolute paths are used as-is; relative paths resolve from the workspace root." ,
700+ } ,
701+ } ,
702+ } ,
703+
704+ async execute (
705+ _id : string ,
706+ params : { dir ?: string } ,
707+ ) {
708+ const fs = await import ( "fs" ) ;
709+ const path = await import ( "path" ) ;
710+
711+ const base = process . env . OPENCLAW_WORKSPACE ?? process . cwd ( ) ;
712+
713+ let dir : string ;
714+ if ( ! params . dir ) {
715+ dir = path . join ( base , "flows" ) ;
716+ } else if ( params . dir . startsWith ( "/" ) ) {
717+ dir = params . dir ;
718+ } else {
719+ dir = path . join ( base , params . dir ) ;
720+ }
721+
722+ if ( ! fs . existsSync ( dir ) ) {
723+ return {
724+ content : [
725+ {
726+ type : "text" ,
727+ text : `Flows directory not found: ${ dir } ` ,
728+ } ,
729+ ] ,
730+ } ;
731+ }
732+
733+ const files = fs . readdirSync ( dir ) . filter ( ( f : string ) => f . endsWith ( ".json" ) ) ;
734+
735+ if ( files . length === 0 ) {
736+ return {
737+ content : [
738+ {
739+ type : "text" ,
740+ text : `No flow files found in ${ dir } ` ,
741+ } ,
742+ ] ,
743+ } ;
744+ }
745+
746+ const flows : Array < {
747+ file : string ;
748+ flow : string ;
749+ description ?: string ;
750+ version ?: string ;
751+ trigger ?: unknown ;
752+ nodes : number ;
753+ } > = [ ] ;
754+
755+ for ( const file of files ) {
756+ const abs = path . join ( dir , file ) ;
757+ try {
758+ const raw = fs . readFileSync ( abs , "utf-8" ) ;
759+ const def = JSON . parse ( raw ) as FlowDefinition ;
760+ if ( ! def . flow || ! Array . isArray ( def . nodes ) ) continue ;
761+ flows . push ( {
762+ file : abs ,
763+ flow : def . flow ,
764+ ...( def . description && { description : def . description } ) ,
765+ ...( def . version && { version : def . version } ) ,
766+ ...( def . trigger && { trigger : def . trigger } ) ,
767+ nodes : def . nodes . length ,
768+ } ) ;
769+ } catch {
770+ // skip non-flow JSON files
771+ }
772+ }
773+
774+ if ( flows . length === 0 ) {
775+ return {
776+ content : [
777+ {
778+ type : "text" ,
779+ text : `No valid flow definitions found in ${ dir } ` ,
780+ } ,
781+ ] ,
782+ } ;
783+ }
784+
785+ return {
786+ content : [
787+ { type : "text" , text : JSON . stringify ( flows , null , 2 ) } ,
788+ ] ,
789+ details : flows ,
790+ } ;
791+ } ,
792+ } ,
793+ { optional : true } ,
794+ ) ;
795+
681796 // ---- flow_transpile -----------------------------------------------------------
682797
683798 api . registerTool (
0 commit comments