Skip to main content
Version: Next

Command Execution Sequence Diagram

This diagram shows the temporal flow from CLI invocation through discovery, runtime selection, and execution. Understanding this flow helps with debugging and extending Invowk.

Main Execution Flow

Diagram: architecture/execution-main

Container Runtime Flow (Detailed)

When the container runtime is selected, additional steps occur:

Diagram: architecture/execution-container

Virtual Runtime Flow

The virtual runtime uses the embedded mvdan/sh interpreter:

Diagram: architecture/execution-virtual

Phase Descriptions

1. Initialization Phase

StepComponentAction
1CLIReceive user command
2-4Config + CUELoad and parse ~/.config/invowk/config.cue

Key decisions made:

  • Container engine preference (docker vs podman)
  • Configured includes for invowkfiles/modules
  • Default runtime if not specified

2. Discovery Phase

StepComponentAction
5DiscoveryStart command discovery
6-7CUE ParserParse all invowkfile.cue files
8-9DiscoveryScan *.invowkmod directories and vendored invowk_modules/
10DiscoveryBuild unified command tree

Precedence order (highest to lowest):

  1. Current directory invowkfile.cue
  2. Current directory *.invowkmod
  3. Configured includes
  4. User commands directory ~/.invowk/cmds/ (modules only, non-recursive)

3. Resolution Phase

StepComponentAction
11Command ServiceMatch command name to discovered commands
12Command ServiceSelect platform-specific implementation
13-14RegistryGet appropriate runtime instance
15-16RuntimeValidate execution context

Platform matching:

  • Check for platforms: [{name: "linux"}], [{name: "macos"}], [{name: "windows"}]
  • Error if no implementation matches the current platform

4. Execution Phase

StepComponentAction
17RuntimeBegin execution
18-19Selected RuntimeRun the actual script/command
20RuntimeReturn result
21CLIOutput to user

Runtime-specific behavior:

  • Native: Spawns host shell process
  • Virtual: Interprets via mvdan/sh
  • Container: Provisions image, runs container

5. Dry-Run Intercept

When --ivk-dry-run is passed, the pipeline short-circuits after resolution:

StepComponentAction
1CLIDetect --ivk-dry-run flag
2CLIRun discovery + resolution as normal (steps 1-16)
3CLIPrint resolved execution plan (Command, Source, Runtime, Platform, WorkDir, Timeout, Script, Environment)
4CLIExit with code 0 (dependency validation is skipped)

6. Watch Mode Loop

When --ivk-watch is passed, execution is wrapped in a watch loop:

StepComponentAction
1CLIDetect --ivk-watch flag (mutually exclusive with --ivk-dry-run)
2CLIRun initial command execution normally
3Watch EngineSet up file watchers from watch.patterns (or **/* fallback)
4Watch EngineWait for file changes, debounce (default 500ms)
5CLIRe-execute command
6Watch EngineRepeat from step 4 until Ctrl+C

Error handling: Non-zero exit codes from the command continue the watch loop. Infrastructure errors (not ExitError) abort the loop after 3 consecutive failures.

Error Handling Points

Diagram: architecture/execution-errors

Performance Considerations

PhaseTypical DurationOptimization
Initialization< 10msConfig cached after first load
Discovery10-100msPer-request cache eliminates duplicate filesystem scans
Resolution< 1msSimple lookup
ExecutionVariableDepends on command

Key optimizations:

  • Per-request discovery cache: A discoveryRequestCache attached to the request context memoizes DiscoverCommandSet, DiscoverAndValidateCommandSet, and GetCommand results. Cross-population ensures that a DiscoverAndValidateCommandSet call also satisfies downstream DiscoverCommandSet lookups, eliminating redundant filesystem traversals within a single CLI invocation.

Bottlenecks to watch:

  • Many modules in configured includes → slower discovery
  • Large invowkfiles → slower parsing
  • Container image pulls → can be minutes