66 "fmt"
77 "strings"
88 "sync"
9+ "time"
910
1011 "github.com/xkilldash9x/scalpel-cli/api/schemas"
1112 "github.com/xkilldash9x/scalpel-cli/internal/analysis/core"
@@ -26,19 +27,21 @@ type ExecutorRegistry struct {
2627 sessionProvider SessionProvider
2728 humanoidProvider HumanoidProvider
2829 providerMu sync.RWMutex
30+ kg GraphStore
2931}
3032
3133// Verify interface compliance.
3234var _ ActionExecutor = (* ExecutorRegistry )(nil )
3335
3436// NewExecutorRegistry creates and initializes a new registry, populating it with
3537// all the specialized executors (Browser, Codebase, Analysis, Humanoid).
36- func NewExecutorRegistry (projectRoot string , globalCtx * core.GlobalContext ) * ExecutorRegistry {
38+ func NewExecutorRegistry (projectRoot string , globalCtx * core.GlobalContext , kg GraphStore ) * ExecutorRegistry {
3739 logger := observability .GetLogger ()
3840 r := & ExecutorRegistry {
3941 logger : logger .Named ("executor_registry" ),
4042 executors : make (map [ActionType ]ActionExecutor ),
4143 sessionProvider : nil ,
44+ kg : kg ,
4245 }
4346
4447 // This getter ensures that the latest session provider is used by executors at runtime.
@@ -50,6 +53,9 @@ func NewExecutorRegistry(projectRoot string, globalCtx *core.GlobalContext) *Exe
5053 codebaseExec := NewCodebaseExecutor (projectRoot )
5154 analysisExec := NewAnalysisExecutor (globalCtx , safeProviderGetter )
5255 humanoidExec := NewHumanoidExecutor (safeHumanoidGetter )
56+ loginExec := NewLoginExecutor (safeHumanoidGetter , safeProviderGetter , kg )
57+ controlExec := NewControlExecutor (globalCtx )
58+
5359 signUpExec , err := NewSignUpExecutor (safeHumanoidGetter , safeProviderGetter , globalCtx .Config , NewFileSystemSecListsLoader ())
5460 if err != nil {
5561 // Log a warning if initialization fails for any reason (e.g., SecLists path invalid).
@@ -67,11 +73,15 @@ func NewExecutorRegistry(projectRoot string, globalCtx *core.GlobalContext) *Exe
6773 ActionSubmitForm ,
6874 ActionScroll ,
6975 ActionWaitForAsync ,
70- ActionExecuteLoginSequence , // Complex workflow
71- ActionExploreApplication , // Complex workflow
72- ActionFuzzEndpoint , // Complex workflow
76+ ActionFuzzEndpoint , // Complex workflow stub
7377 )
7478
79+ // Register specialized complex actions.
80+ r .register (loginExec , ActionExecuteLoginSequence )
81+ r .register (controlExec , ActionDecideNextStep )
82+
83+ r .register (browserExec , ActionExploreApplication ) // Still mapped to browser executor for now, though likely complex.
84+
7585 // Register complex, interactive browser actions (Humanoid).
7686 r .register (humanoidExec , ActionClick , ActionInputText , ActionHumanoidDragAndDrop )
7787
@@ -247,6 +257,7 @@ func (e *BrowserExecutor) registerHandlers() {
247257 e .handlers [ActionSubmitForm ] = e .handleSubmitForm
248258 e .handlers [ActionScroll ] = e .handleScroll
249259 e .handlers [ActionWaitForAsync ] = e .handleWaitForAsync
260+ e .handlers [ActionFuzzEndpoint ] = e .handleFuzzEndpoint
250261}
251262
252263// handleNavigate executes the navigation action.
@@ -325,6 +336,73 @@ func (e *BrowserExecutor) handleWaitForAsync(ctx context.Context, session schema
325336 return session .WaitForAsync (ctx , durationMs )
326337}
327338
339+ // handleFuzzEndpoint is a stub implementation for fuzzing endpoints.
340+ func (e * BrowserExecutor ) handleFuzzEndpoint (ctx context.Context , session schemas.SessionContext , action Action ) error {
341+ e .logger .Info ("ActionFuzzEndpoint is a stub. Implementation pending." )
342+ return nil
343+ }
344+
345+ // -- Control Executor --
346+
347+ // ControlExecutor handles high-level control actions like deciding next steps,
348+ // adjusting tactics, and modifying agent behavior.
349+ type ControlExecutor struct {
350+ logger * zap.Logger
351+ globalCtx * core.GlobalContext
352+ }
353+
354+ var _ ActionExecutor = (* ControlExecutor )(nil )
355+
356+ func NewControlExecutor (globalCtx * core.GlobalContext ) * ControlExecutor {
357+ return & ControlExecutor {
358+ logger : observability .GetLogger ().Named ("control_executor" ),
359+ globalCtx : globalCtx ,
360+ }
361+ }
362+
363+ func (e * ControlExecutor ) Execute (ctx context.Context , action Action ) (* ExecutionResult , error ) {
364+ if action .Type == ActionDecideNextStep {
365+ return e .handleDecideNextStep (ctx , action )
366+ }
367+
368+ return & ExecutionResult {
369+ Status : "failed" ,
370+ ObservationType : ObservedSystemState ,
371+ ErrorCode : ErrCodeUnknownAction ,
372+ ErrorDetails : map [string ]interface {}{"message" : "ControlExecutor received unknown action type" },
373+ }, nil
374+ }
375+
376+ func (e * ControlExecutor ) handleDecideNextStep (ctx context.Context , action Action ) (* ExecutionResult , error ) {
377+ // Logic to "tie the scan process into the agents ability to decide, plan, react, replan or reorganize"
378+ // This would parse metadata to adjust global configuration if possible, or trigger
379+ // complex internal state transitions.
380+ // For now, it logs the decision and potentially adjusts some runtime tunable parameters.
381+
382+ e .logger .Info ("Agent is deciding next step / replanning..." , zap .String ("rationale" , action .Rationale ))
383+
384+ if tactics , ok := action .Metadata ["tactics" ].(map [string ]interface {}); ok {
385+ if speed , ok := tactics ["scan_speed" ].(string ); ok {
386+ e .logger .Info ("Adjusting scan speed based on agent decision" , zap .String ("new_speed" , speed ))
387+ // Implementation would involve adjusting rate limiters or delays in global context/config if exposed.
388+ }
389+ }
390+
391+ // Adjusting timing (e.g. sleep)
392+ if delay , ok := action .Metadata ["delay_ms" ].(float64 ); ok {
393+ e .logger .Info ("Agent requested tactical delay" , zap .Float64 ("ms" , delay ))
394+ time .Sleep (time .Duration (delay ) * time .Millisecond )
395+ }
396+
397+ return & ExecutionResult {
398+ Status : "success" ,
399+ ObservationType : ObservedSystemState ,
400+ Data : map [string ]interface {}{
401+ "message" : "Plan updated / Decision processed" ,
402+ },
403+ }, nil
404+ }
405+
328406// -- Shared Error Parsing --
329407
330408// ParseBrowserError is a utility function that inspects an error returned from
0 commit comments