@@ -15,6 +15,7 @@ import {
1515} from "@typeagent/agent-sdk/helpers/action" ;
1616import {
1717 type CommandHandler ,
18+ type CommandHandlerNoParams ,
1819 type CommandHandlerTable ,
1920 getCommandInterface ,
2021} from "@typeagent/agent-sdk/helpers/command" ;
@@ -610,6 +611,12 @@ class ImportScriptHandler implements CommandHandler {
610611 implicitQuotes : true ,
611612 } ,
612613 } ,
614+ flags : {
615+ actionName : {
616+ description : "Override the generated action name" ,
617+ type : "string" ,
618+ } ,
619+ } ,
613620 } as const ;
614621 public async run (
615622 context : ActionContext < ScriptFlowAgentContext > ,
@@ -643,11 +650,16 @@ class ImportScriptHandler implements CommandHandler {
643650 }
644651
645652 const analyzer = new ScriptAnalyzer ( ) ;
646- const recipe = await analyzer . analyze ( scriptContent , resolvedPath ) ;
653+ const overrideName = params . flags . actionName ;
654+ const recipe = await analyzer . analyze (
655+ scriptContent ,
656+ resolvedPath ,
657+ overrideName ,
658+ ) ;
647659
648660 if ( store . hasFlow ( recipe . actionName ) ) {
649661 throw new Error (
650- `A flow named '${ recipe . actionName } ' already exists. Delete it first or use a different name.` ,
662+ `A flow named '${ recipe . actionName } ' already exists. Delete it first or use --actionName to specify a different name.` ,
651663 ) ;
652664 }
653665
@@ -663,9 +675,227 @@ class ImportScriptHandler implements CommandHandler {
663675 }
664676}
665677
678+ class ListHandler implements CommandHandlerNoParams {
679+ public readonly description = "List all registered script flows" ;
680+ public async run ( context : ActionContext < ScriptFlowAgentContext > ) {
681+ const store = _agentStore ;
682+ if ( ! store ) {
683+ throw new Error ( "Script flow store not available" ) ;
684+ }
685+ const entries = store . listFlows ( ) ;
686+ if ( entries . length === 0 ) {
687+ context . actionIO . setDisplay ( "No script flows registered." ) ;
688+ return ;
689+ }
690+ const lines = entries . map (
691+ ( e ) =>
692+ ` ${ e . actionName } : ${ e . description } [usage: ${ e . usageCount } ]${ e . source === "seed" ? " (sample)" : "" } ` ,
693+ ) ;
694+ context . actionIO . setDisplay (
695+ `Script flows (${ entries . length } ):\n${ lines . join ( "\n" ) } ` ,
696+ ) ;
697+ }
698+ }
699+
700+ class RunHandler implements CommandHandler {
701+ public readonly description = "Execute a script flow by name" ;
702+ public readonly parameters = {
703+ args : {
704+ flowName : {
705+ description : "Name of the script flow to execute" ,
706+ } ,
707+ } ,
708+ flags : {
709+ flowParametersJson : {
710+ description :
711+ 'JSON string of parameters, e.g. \'{"path":"C:\\\\Users"}\'' ,
712+ type : "string" ,
713+ } ,
714+ } ,
715+ } as const ;
716+ public async run (
717+ context : ActionContext < ScriptFlowAgentContext > ,
718+ params : ParsedCommandParams < typeof this . parameters > ,
719+ ) {
720+ const store = _agentStore ;
721+ if ( ! store ) {
722+ throw new Error ( "Script flow store not available" ) ;
723+ }
724+
725+ const flowName = params . args . flowName ;
726+ if ( ! flowName ) {
727+ throw new Error ( "Missing required argument: flowName" ) ;
728+ }
729+
730+ const flow = await store . getFlow ( flowName ) ;
731+ if ( ! flow ) {
732+ throw new Error (
733+ `Unknown script flow '${ flowName } '. Use '@scriptflow list' to see available flows.` ,
734+ ) ;
735+ }
736+
737+ const script = await store . getScript ( flowName ) ;
738+ if ( ! script ) {
739+ throw new Error ( `Script not found for flow: ${ flowName } ` ) ;
740+ }
741+
742+ let flowParameters : Record < string , unknown > = { } ;
743+ if ( params . flags . flowParametersJson ) {
744+ try {
745+ flowParameters = JSON . parse ( params . flags . flowParametersJson ) ;
746+ } catch {
747+ throw new Error (
748+ `Invalid JSON in --flowParametersJson: ${ params . flags . flowParametersJson } ` ,
749+ ) ;
750+ }
751+ }
752+
753+ expandEnvVarsInParams ( flowParameters , flow . parameters ) ;
754+ const pathError = validatePathParameters (
755+ flowParameters ,
756+ flow . parameters ,
757+ ) ;
758+ if ( pathError ) {
759+ throw new Error ( pathError ) ;
760+ }
761+ const validationError = validateParameterRules (
762+ flowParameters ,
763+ flow . parameters ,
764+ ) ;
765+ if ( validationError ) {
766+ throw new Error ( validationError ) ;
767+ }
768+
769+ const result = await executeFlowScript ( flow , script , flowParameters ) ;
770+ if ( result . error !== undefined ) {
771+ throw new Error ( String ( result . error ) ) ;
772+ }
773+
774+ await store . recordUsage ( flowName ) ;
775+ if ( "displayContent" in result && result . displayContent ) {
776+ const content = result . displayContent ;
777+ const text =
778+ typeof content === "string"
779+ ? content
780+ : "content" in content
781+ ? content . content
782+ : String ( content ) ;
783+ context . actionIO . setDisplay ( text ) ;
784+ }
785+ }
786+ }
787+
788+ class DeleteHandler implements CommandHandler {
789+ public readonly description = "Delete a script flow by name" ;
790+ public readonly parameters = {
791+ args : {
792+ name : {
793+ description : "Name of the script flow to delete" ,
794+ } ,
795+ } ,
796+ } as const ;
797+ public async run (
798+ context : ActionContext < ScriptFlowAgentContext > ,
799+ params : ParsedCommandParams < typeof this . parameters > ,
800+ ) {
801+ const store = _agentStore ;
802+ if ( ! store ) {
803+ throw new Error ( "Script flow store not available" ) ;
804+ }
805+
806+ const name = params . args . name ;
807+ if ( ! name ) {
808+ throw new Error ( "Missing required argument: name" ) ;
809+ }
810+
811+ const deleted = await store . deleteFlow ( name ) ;
812+ if ( ! deleted ) {
813+ throw new Error ( `Script flow not found: ${ name } ` ) ;
814+ }
815+
816+ await context . sessionContext . reloadAgentSchema ( ) ;
817+ context . actionIO . setDisplay ( `Deleted script flow: ${ name } ` ) ;
818+ }
819+ }
820+
821+ class ShowHandler implements CommandHandler {
822+ public readonly description = "Show details of a script flow" ;
823+ public readonly parameters = {
824+ args : {
825+ flowName : {
826+ description : "Name of the script flow to show" ,
827+ } ,
828+ } ,
829+ } as const ;
830+ public async run (
831+ context : ActionContext < ScriptFlowAgentContext > ,
832+ params : ParsedCommandParams < typeof this . parameters > ,
833+ ) {
834+ const store = _agentStore ;
835+ if ( ! store ) {
836+ throw new Error ( "Script flow store not available" ) ;
837+ }
838+
839+ const flowName = params . args . flowName ;
840+ if ( ! flowName ) {
841+ throw new Error ( "Missing required argument: flowName" ) ;
842+ }
843+
844+ const flow = await store . getFlow ( flowName ) ;
845+ if ( ! flow ) {
846+ throw new Error (
847+ `Unknown script flow '${ flowName } '. Use '@scriptflow list' to see available flows.` ,
848+ ) ;
849+ }
850+
851+ const script = await store . getScript ( flowName ) ;
852+ const entries = store . listFlows ( ) ;
853+ const entry = entries . find ( ( e ) => e . actionName === flowName ) ;
854+
855+ const paramLines = flow . parameters . map (
856+ ( p ) =>
857+ ` ${ p . name } (${ p . type } ${ p . required ? ", required" : "" } ): ${ p . description } ${ p . default !== undefined ? ` [default: ${ p . default } ]` : "" } ` ,
858+ ) ;
859+ const grammarLines = flow . grammarPatterns . map (
860+ ( g ) => ` "${ g . pattern } "${ g . isAlias ? " (alias)" : "" } ` ,
861+ ) ;
862+ const cmdletList = flow . sandbox . allowedCmdlets . join ( ", " ) ;
863+
864+ const output = [
865+ `Flow: ${ flow . actionName } ` ,
866+ `Description: ${ flow . description } ` ,
867+ `Display Name: ${ flow . displayName } ` ,
868+ `Source: ${ flow . source ?. type ?? "unknown" } ` ,
869+ `Usage Count: ${ entry ?. usageCount ?? 0 } ` ,
870+ "" ,
871+ "Parameters:" ,
872+ paramLines . length > 0 ? paramLines . join ( "\n" ) : " (none)" ,
873+ "" ,
874+ "Grammar Patterns:" ,
875+ grammarLines . length > 0 ? grammarLines . join ( "\n" ) : " (none)" ,
876+ "" ,
877+ "Sandbox:" ,
878+ ` Cmdlets: ${ cmdletList || "(none)" } ` ,
879+ ` Timeout: ${ flow . sandbox . maxExecutionTime } s` ,
880+ ` Network: ${ flow . sandbox . networkAccess ? "allowed" : "blocked" } ` ,
881+ "" ,
882+ "Script:" ,
883+ "```powershell" ,
884+ script ?? "(script not found)" ,
885+ "```" ,
886+ ] ;
887+
888+ context . actionIO . setDisplay ( output . join ( "\n" ) ) ;
889+ }
890+ }
891+
666892const handlers : CommandHandlerTable = {
667893 description : "ScriptFlow commands" ,
668894 commands : {
895+ list : new ListHandler ( ) ,
896+ run : new RunHandler ( ) ,
897+ delete : new DeleteHandler ( ) ,
898+ show : new ShowHandler ( ) ,
669899 import : new ImportScriptHandler ( ) ,
670900 } ,
671901} ;
0 commit comments