diff --git a/go.mod b/go.mod
index b6c2db8..1dd33e1 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/crazy-max/undock
 go 1.23.0
 
 require (
-	github.com/alecthomas/kong v1.6.1
+	github.com/alecthomas/kong v1.9.0
 	github.com/containerd/platforms v0.2.1
 	github.com/containers/image/v5 v5.33.1
 	github.com/docker/docker v27.3.1+incompatible
diff --git a/go.sum b/go.sum
index 9ede9ae..6ed52fe 100644
--- a/go.sum
+++ b/go.sum
@@ -37,8 +37,8 @@ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpH
 github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
 github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
 github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
-github.com/alecthomas/kong v1.6.1 h1:/7bVimARU3uxPD0hbryPE8qWrS3Oz3kPQoxA/H2NKG8=
-github.com/alecthomas/kong v1.6.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
+github.com/alecthomas/kong v1.9.0 h1:Wgg0ll5Ys7xDnpgYBuBn/wPeLGAuK0NvYmEcisJgrIs=
+github.com/alecthomas/kong v1.9.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
 github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
 github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
 github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
diff --git a/vendor/github.com/alecthomas/kong/.golangci.yml b/vendor/github.com/alecthomas/kong/.golangci.yml
index 844092f..1eb0b92 100644
--- a/vendor/github.com/alecthomas/kong/.golangci.yml
+++ b/vendor/github.com/alecthomas/kong/.golangci.yml
@@ -12,7 +12,6 @@ linters:
     - wsl
     - funlen
     - gocognit
-    - gomnd
     - goprintffuncname
     - paralleltest
     - nlreturn
@@ -36,12 +35,14 @@ linters:
     - nilnil
     - depguard    # nothing to guard against yet
     - tagalign    # hurts readability of kong tags
+    - tenv        # deprecated since v1.64, but not removed yet
     - mnd
     - perfsprint
     - err113
     - copyloopvar
     - intrange
-    - execinquery
+    - nakedret
+    - recvcheck   # value receivers are intentionally used for copies
 
 linters-settings:
   govet:
diff --git a/vendor/github.com/alecthomas/kong/README.md b/vendor/github.com/alecthomas/kong/README.md
index 4a86251..3b62344 100644
--- a/vendor/github.com/alecthomas/kong/README.md
+++ b/vendor/github.com/alecthomas/kong/README.md
@@ -13,7 +13,8 @@
 - [Command handling](#command-handling)
   - [Switch on the command string](#switch-on-the-command-string)
   - [Attach a `Run(...) error` method to each command](#attach-a-run-error-method-to-each-command)
-- [Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply() and the Bind() option](#hooks-beforereset-beforeresolve-beforeapply-afterapply-and-the-bind-option)
+- [Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply()](#hooks-beforereset-beforeresolve-beforeapply-afterapply)
+- [The Bind() option](#the-bind-option)
 - [Flags](#flags)
 - [Commands and sub-commands](#commands-and-sub-commands)
 - [Branching positional arguments](#branching-positional-arguments)
@@ -305,7 +306,7 @@ func main() {
 
 ```
 
-## Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply() and the Bind() option
+## Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply()
 
 If a node in the CLI, or any of its embedded fields, has a `BeforeReset(...) error`, `BeforeResolve
 (...) error`, `BeforeApply(...) error` and/or `AfterApply(...) error` method, those
@@ -314,8 +315,6 @@ and after validation/assignment, respectively.
 
 The `--help` flag is implemented with a `BeforeReset` hook.
 
-Arguments to hooks are provided via the `Run(...)` method or `Bind(...)` option. `*Kong`, `*Context` and `*Path` are also bound and finally, hooks can also contribute bindings via `kong.Context.Bind()` and `kong.Context.BindTo()`.
-
 eg.
 
 ```go
@@ -341,6 +340,40 @@ func main() {
 }
 ```
 
+##  The Bind() option
+
+Arguments to hooks are provided via the `Run(...)` method or `Bind(...)` option. `*Kong`, `*Context`, `*Path` and parent commands are also bound and finally, hooks can also contribute bindings via `kong.Context.Bind()` and `kong.Context.BindTo()`.
+
+eg:
+
+```go
+type CLI struct {
+  Debug bool `help:"Enable debug mode."`
+
+  Rm RmCmd `cmd:"" help:"Remove files."`
+  Ls LsCmd `cmd:"" help:"List paths."`
+}
+
+type AuthorName string
+
+// ...
+func (l *LsCmd) Run(cli *CLI) error {
+// use cli.Debug here !!
+  return nil
+}
+
+func (r *RmCmD) Run(author AuthorName) error{
+// use binded author here
+  return nil
+}
+
+func main() {
+  var cli CLI
+  
+  ctx := kong.Parse(&cli, Bind(AuthorName("penguin")))
+  err := ctx.Run()
+```
+
 ## Flags
 
 Any [mapped](#mapper---customising-how-the-command-line-is-mapped-to-go-values) field in the command structure _not_ tagged with `cmd` or `arg` will be a flag. Flags are optional by default.
diff --git a/vendor/github.com/alecthomas/kong/build.go b/vendor/github.com/alecthomas/kong/build.go
index 5d17f53..63afcd4 100644
--- a/vendor/github.com/alecthomas/kong/build.go
+++ b/vendor/github.com/alecthomas/kong/build.go
@@ -54,6 +54,7 @@ func flattenedFields(v reflect.Value, ptag *Tag) (out []flattenedField, err erro
 	if v.Kind() != reflect.Struct {
 		return out, nil
 	}
+	ignored := map[string]bool{}
 	for i := 0; i < v.NumField(); i++ {
 		ft := v.Type().Field(i)
 		fv := v.Field(i)
@@ -61,7 +62,8 @@ func flattenedFields(v reflect.Value, ptag *Tag) (out []flattenedField, err erro
 		if err != nil {
 			return nil, err
 		}
-		if tag.Ignored {
+		if tag.Ignored || ignored[ft.Name] {
+			ignored[ft.Name] = true
 			continue
 		}
 		// Assign group if it's not already set.
@@ -106,9 +108,27 @@ func flattenedFields(v reflect.Value, ptag *Tag) (out []flattenedField, err erro
 		}
 		out = append(out, sub...)
 	}
+	out = removeIgnored(out, ignored)
 	return out, nil
 }
 
+func removeIgnored(fields []flattenedField, ignored map[string]bool) []flattenedField {
+	j := 0
+	for i := 0; i < len(fields); i++ {
+		if ignored[fields[i].field.Name] {
+			continue
+		}
+		if i != j {
+			fields[j] = fields[i]
+		}
+		j++
+	}
+	if j != len(fields) {
+		fields = fields[:j]
+	}
+	return fields
+}
+
 // Build a Node in the Kong data model.
 //
 // "v" is the value to create the node from, "typ" is the output Node type.
diff --git a/vendor/github.com/alecthomas/kong/callbacks.go b/vendor/github.com/alecthomas/kong/callbacks.go
index c1fac81..6096a26 100644
--- a/vendor/github.com/alecthomas/kong/callbacks.go
+++ b/vendor/github.com/alecthomas/kong/callbacks.go
@@ -6,10 +6,59 @@ import (
 	"strings"
 )
 
+// binding is a single binding registered with Kong.
+type binding struct {
+	// fn is a function that returns a value of the target type.
+	fn reflect.Value
+
+	// val is a value of the target type.
+	// Must be set if done and singleton are true.
+	val reflect.Value
+
+	// singleton indicates whether the binding is a singleton.
+	// If true, the binding will be resolved once and cached.
+	singleton bool
+
+	// done indicates whether a singleton binding has been resolved.
+	// If singleton is false, this field is ignored.
+	done bool
+}
+
+// newValueBinding builds a binding with an already resolved value.
+func newValueBinding(v reflect.Value) *binding {
+	return &binding{val: v, done: true, singleton: true}
+}
+
+// newFunctionBinding builds a binding with a function
+// that will return a value of the target type.
+//
+// The function signature must be func(...) (T, error) or func(...) T
+// where parameters are recursively resolved.
+func newFunctionBinding(f reflect.Value, singleton bool) *binding {
+	return &binding{fn: f, singleton: singleton}
+}
+
+// Get returns the pre-resolved value for the binding,
+// or false if the binding is not resolved.
+func (b *binding) Get() (v reflect.Value, ok bool) {
+	return b.val, b.done
+}
+
+// Set sets the value of the binding to the given value,
+// marking it as resolved.
+//
+// If the binding is not a singleton, this method does nothing.
+func (b *binding) Set(v reflect.Value) {
+	if b.singleton {
+		b.val = v
+		b.done = true
+	}
+}
+
 // A map of type to function that returns a value of that type.
 //
 // The function should have the signature func(...) (T, error). Arguments are recursively resolved.
-type bindings map[reflect.Type]any
+type bindings map[reflect.Type]*binding
 
 func (b bindings) String() string {
 	out := []string{}
@@ -21,24 +70,34 @@ func (b bindings) String() string {
 
 func (b bindings) add(values ...any) bindings {
 	for _, v := range values {
-		v := v
-		b[reflect.TypeOf(v)] = func() (any, error) { return v, nil }
+		val := reflect.ValueOf(v)
+		b[val.Type()] = newValueBinding(val)
 	}
 	return b
 }
 
 func (b bindings) addTo(impl, iface any) {
-	b[reflect.TypeOf(iface).Elem()] = func() (any, error) { return impl, nil }
+	val := reflect.ValueOf(impl)
+	b[reflect.TypeOf(iface).Elem()] = newValueBinding(val)
 }
 
-func (b bindings) addProvider(provider any) error {
+func (b bindings) addProvider(provider any, singleton bool) error {
 	pv := reflect.ValueOf(provider)
 	t := pv.Type()
-	if t.Kind() != reflect.Func || t.NumOut() != 2 || t.Out(1) != reflect.TypeOf((*error)(nil)).Elem() {
-		return fmt.Errorf("%T must be a function with the signature func(...)(T, error)", provider)
+	if t.Kind() != reflect.Func {
+		return fmt.Errorf("%T must be a function", provider)
+	}
+
+	if t.NumOut() == 0 {
+		return fmt.Errorf("%T must be a function with the signature func(...)(T, error) or func(...) T", provider)
+	}
+	if t.NumOut() == 2 {
+		if t.Out(1) != reflect.TypeOf((*error)(nil)).Elem() {
+			return fmt.Errorf("missing error; %T must be a function with the signature func(...)(T, error) or func(...) T", provider)
+		}
 	}
 	rt := pv.Type().Out(0)
-	b[rt] = provider
+	b[rt] = newFunctionBinding(pv, singleton)
 	return nil
 }
 
@@ -68,31 +127,48 @@ func getMethod(value reflect.Value, name string) reflect.Value {
 	return method
 }
 
-// Get methods from the given value and any embedded fields.
-func getMethods(value reflect.Value, name string) []reflect.Value {
-	// Collect all possible receivers
-	receivers := []reflect.Value{value}
+// getMethods gets all methods with the given name from the given value
+// and any embedded fields.
+//
+// Returns a slice of bound methods that can be called directly.
+func getMethods(value reflect.Value, name string) (methods []reflect.Value) {
 	if value.Kind() == reflect.Ptr {
 		value = value.Elem()
 	}
-	if value.Kind() == reflect.Struct {
-		t := value.Type()
-		for i := 0; i < value.NumField(); i++ {
-			field := value.Field(i)
-			fieldType := t.Field(i)
-			if fieldType.IsExported() && fieldType.Anonymous {
-				receivers = append(receivers, field)
-			}
-		}
+	if !value.IsValid() {
+		return
+	}
+
+	if method := getMethod(value, name); method.IsValid() {
+		methods = append(methods, method)
 	}
-	// Search all receivers for methods
-	var methods []reflect.Value
-	for _, receiver := range receivers {
-		if method := getMethod(receiver, name); method.IsValid() {
-			methods = append(methods, method)
+
+	if value.Kind() != reflect.Struct {
+		return
+	}
+	// If the current value is a struct, also consider embedded fields.
+	// Two kinds of embedded fields are considered if they're exported:
+	//
+	//   - standard Go embedded fields
+	//   - fields tagged with `embed:""`
+	t := value.Type()
+	for i := 0; i < value.NumField(); i++ {
+		fieldValue := value.Field(i)
+		field := t.Field(i)
+
+		if !field.IsExported() {
+			continue
+		}
+
+		// Consider a field embedded if it's actually embedded
+		// or if it's tagged with `embed:""`.
+		_, isEmbedded := field.Tag.Lookup("embed")
+		isEmbedded = isEmbedded || field.Anonymous
+		if isEmbedded {
+			methods = append(methods, getMethods(fieldValue, name)...)
 		}
 	}
-	return methods
+	return
 }
 
 func callFunction(f reflect.Value, bindings bindings) error {
@@ -122,19 +198,29 @@ func callAnyFunction(f reflect.Value, bindings bindings) (out []any, err error)
 	t := f.Type()
 	for i := 0; i < t.NumIn(); i++ {
 		pt := t.In(i)
-		argf, ok := bindings[pt]
+		binding, ok := bindings[pt]
 		if !ok {
 			return nil, fmt.Errorf("couldn't find binding of type %s for parameter %d of %s(), use kong.Bind(%s)", pt, i, t, pt)
 		}
+
+		// Don't need to call the function if the value is already resolved.
+		if val, ok := binding.Get(); ok {
+			in = append(in, val)
+			continue
+		}
+
 		// Recursively resolve binding functions.
-		argv, err := callAnyFunction(reflect.ValueOf(argf), bindings)
+		argv, err := callAnyFunction(binding.fn, bindings)
 		if err != nil {
 			return nil, fmt.Errorf("%s: %w", pt, err)
 		}
-		if ferrv := reflect.ValueOf(argv[len(argv)-1]); ferrv.IsValid() && !ferrv.IsNil() {
+		if ferrv := reflect.ValueOf(argv[len(argv)-1]); ferrv.IsValid() && ferrv.Type().Implements(callbackReturnSignature) && !ferrv.IsNil() {
 			return nil, ferrv.Interface().(error) //nolint:forcetypeassert
 		}
-		in = append(in, reflect.ValueOf(argv[0]))
+
+		val := reflect.ValueOf(argv[0])
+		binding.Set(val)
+		in = append(in, val)
 	}
 	outv := f.Call(in)
 	out = make([]any, len(outv))
diff --git a/vendor/github.com/alecthomas/kong/context.go b/vendor/github.com/alecthomas/kong/context.go
index b6a56e3..16a7353 100644
--- a/vendor/github.com/alecthomas/kong/context.go
+++ b/vendor/github.com/alecthomas/kong/context.go
@@ -26,6 +26,9 @@ type Path struct {
 
 	// True if this Path element was created as the result of a resolver.
 	Resolved bool
+
+	// Remaining tokens after this node
+	remainder []Token
 }
 
 // Node returns the Node associated with this Path, or nil if Path is a non-Node.
@@ -64,6 +67,15 @@ func (p *Path) Visitable() Visitable {
 	return nil
 }
 
+// Remainder returns the remaining unparsed args after this Path element.
+func (p *Path) Remainder() []string {
+	args := []string{}
+	for _, token := range p.remainder {
+		args = append(args, token.String())
+	}
+	return args
+}
+
 // Context contains the current parse context.
 type Context struct {
 	*Kong
@@ -87,14 +99,15 @@ type Context struct {
 // This just constructs a new trace. To fully apply the trace you must call Reset(), Resolve(),
 // Validate() and Apply().
 func Trace(k *Kong, args []string) (*Context, error) {
+	s := Scan(args...)
 	c := &Context{
 		Kong: k,
 		Args: args,
 		Path: []*Path{
-			{App: k.Model, Flags: k.Model.Flags},
+			{App: k.Model, Flags: k.Model.Flags, remainder: s.PeekAll()},
 		},
 		values:   map[*Value]reflect.Value{},
-		scan:     Scan(args...),
+		scan:     s,
 		bindings: bindings{},
 	}
 	c.Error = c.trace(c.Model.Node)
@@ -119,8 +132,20 @@ func (c *Context) BindTo(impl, iface any) {
 //
 // This is useful when the Run() function of different commands require different values that may
 // not all be initialisable from the main() function.
+//
+// "provider" must be a function with the signature func(...) (T, error) or func(...) T,
+// where ... will be recursively injected with bound values.
 func (c *Context) BindToProvider(provider any) error {
-	return c.bindings.addProvider(provider)
+	return c.bindings.addProvider(provider, false /* singleton */)
+}
+
+// BindSingletonProvider allows binding of provider functions.
+// The provider will be called once and the result cached.
+//
+// "provider" must be a function with the signature func(...) (T, error) or func(...) T,
+// where ... will be recursively injected with bound values.
+func (c *Context) BindSingletonProvider(provider any) error {
+	return c.bindings.addProvider(provider, true /* singleton */)
 }
 
 // Value returns the value for a particular path element.
@@ -465,6 +490,7 @@ func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
 				c.Path = append(c.Path, &Path{
 					Parent:     node,
 					Positional: arg,
+					remainder:  c.scan.PeekAll(),
 				})
 				positional++
 				break
@@ -496,9 +522,10 @@ func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
 				if branch.Type == CommandNode && branch.Name == token.Value {
 					c.scan.Pop()
 					c.Path = append(c.Path, &Path{
-						Parent:  node,
-						Command: branch,
-						Flags:   branch.Flags,
+						Parent:    node,
+						Command:   branch,
+						Flags:     branch.Flags,
+						remainder: c.scan.PeekAll(),
 					})
 					return c.trace(branch)
 				}
@@ -510,9 +537,10 @@ func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
 					arg := branch.Argument
 					if err := arg.Parse(c.scan, c.getValue(arg)); err == nil {
 						c.Path = append(c.Path, &Path{
-							Parent:   node,
-							Argument: branch,
-							Flags:    branch.Flags,
+							Parent:    node,
+							Argument:  branch,
+							Flags:     branch.Flags,
+							remainder: c.scan.PeekAll(),
 						})
 						return c.trace(branch)
 					}
@@ -523,9 +551,10 @@ func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
 			// matches, take the branch of the default command
 			if node.DefaultCmd != nil && node.DefaultCmd.Tag.Default == "withargs" {
 				c.Path = append(c.Path, &Path{
-					Parent:  node,
-					Command: node.DefaultCmd,
-					Flags:   node.DefaultCmd.Flags,
+					Parent:    node,
+					Command:   node.DefaultCmd,
+					Flags:     node.DefaultCmd.Flags,
+					remainder: c.scan.PeekAll(),
 				})
 				return c.trace(node.DefaultCmd)
 			}
@@ -538,19 +567,25 @@ func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
 	return c.maybeSelectDefault(flags, node)
 }
 
+// IgnoreDefault can be implemented by flags that want to be applied before any default commands.
+type IgnoreDefault interface {
+	IgnoreDefault()
+}
+
 // End of the line, check for a default command, but only if we're not displaying help,
 // otherwise we'd only ever display the help for the default command.
 func (c *Context) maybeSelectDefault(flags []*Flag, node *Node) error {
 	for _, flag := range flags {
-		if flag.Name == "help" && flag.Set {
+		if _, ok := flag.Target.Interface().(IgnoreDefault); ok && flag.Set {
 			return nil
 		}
 	}
 	if node.DefaultCmd != nil {
 		c.Path = append(c.Path, &Path{
-			Parent:  node.DefaultCmd,
-			Command: node.DefaultCmd,
-			Flags:   node.DefaultCmd.Flags,
+			Parent:    node.DefaultCmd,
+			Command:   node.DefaultCmd,
+			Flags:     node.DefaultCmd.Flags,
+			remainder: c.scan.PeekAll(),
 		})
 	}
 	return nil
@@ -595,8 +630,9 @@ func (c *Context) Resolve() error {
 				return err
 			}
 			inserted = append(inserted, &Path{
-				Flag:     flag,
-				Resolved: true,
+				Flag:      flag,
+				Resolved:  true,
+				remainder: c.scan.PeekAll(),
 			})
 		}
 	}
@@ -740,7 +776,10 @@ func (c *Context) parseFlag(flags []*Flag, match string) (err error) {
 			}
 			flag.Value.Apply(value)
 		}
-		c.Path = append(c.Path, &Path{Flag: flag})
+		c.Path = append(c.Path, &Path{
+			Flag:      flag,
+			remainder: c.scan.PeekAll(),
+		})
 		return nil
 	}
 	return &unknownFlagError{Cause: findPotentialCandidates(match, candidates, "unknown flag %s", match)}
@@ -789,7 +828,7 @@ func (c *Context) RunNode(node *Node, binds ...any) (err error) {
 					methodt := t.Method(i)
 					if strings.HasPrefix(methodt.Name, "Provide") {
 						method := p.Method(i)
-						if err := methodBinds.addProvider(method.Interface()); err != nil {
+						if err := methodBinds.addProvider(method.Interface(), false /* singleton */); err != nil {
 							return fmt.Errorf("%s.%s: %w", t.Name(), methodt.Name, err)
 						}
 					}
diff --git a/vendor/github.com/alecthomas/kong/error.go b/vendor/github.com/alecthomas/kong/error.go
index 18225ef..e79a15d 100644
--- a/vendor/github.com/alecthomas/kong/error.go
+++ b/vendor/github.com/alecthomas/kong/error.go
@@ -5,8 +5,17 @@ package kong
 // It contains the parse Context that triggered the error.
 type ParseError struct {
 	error
-	Context *Context
+	Context  *Context
+	exitCode int
 }
 
 // Unwrap returns the original cause of the error.
 func (p *ParseError) Unwrap() error { return p.error }
+
+// ExitCode returns the status that Kong should exit with if it fails with a ParseError.
+func (p *ParseError) ExitCode() int {
+	if p.exitCode == 0 {
+		return exitNotOk
+	}
+	return p.exitCode
+}
diff --git a/vendor/github.com/alecthomas/kong/exit.go b/vendor/github.com/alecthomas/kong/exit.go
new file mode 100644
index 0000000..4925f48
--- /dev/null
+++ b/vendor/github.com/alecthomas/kong/exit.go
@@ -0,0 +1,32 @@
+package kong
+
+import "errors"
+
+const (
+	exitOk    = 0
+	exitNotOk = 1
+
+	// Semantic exit codes from https://github.com/square/exit?tab=readme-ov-file#about
+	exitUsageError = 80
+)
+
+// ExitCoder is an interface that may be implemented by an error value to
+// provide an integer exit code. The method ExitCode should return an integer
+// that is intended to be used as the exit code for the application.
+type ExitCoder interface {
+	ExitCode() int
+}
+
+// exitCodeFromError returns the exit code for the given error.
+// If err implements the exitCoder interface, the ExitCode method is called.
+// Otherwise, exitCodeFromError returns 0 if err is nil, and 1 if it is not.
+func exitCodeFromError(err error) int {
+	var e ExitCoder
+	if errors.As(err, &e) {
+		return e.ExitCode()
+	} else if err == nil {
+		return exitOk
+	}
+
+	return exitNotOk
+}
diff --git a/vendor/github.com/alecthomas/kong/help.go b/vendor/github.com/alecthomas/kong/help.go
index 6363ea2..8da1555 100644
--- a/vendor/github.com/alecthomas/kong/help.go
+++ b/vendor/github.com/alecthomas/kong/help.go
@@ -14,9 +14,11 @@ const (
 )
 
 // Help flag.
-type helpValue bool
+type helpFlag bool
 
-func (h helpValue) BeforeReset(ctx *Context) error {
+func (h helpFlag) IgnoreDefault() {}
+
+func (h helpFlag) BeforeReset(ctx *Context) error {
 	options := ctx.Kong.helpOptions
 	options.Summary = false
 	err := ctx.Kong.help(options, ctx)
@@ -415,7 +417,7 @@ func (h *helpWriter) Write(w io.Writer) error {
 
 func (h *helpWriter) Wrap(text string) {
 	w := bytes.NewBuffer(nil)
-	doc.ToText(w, strings.TrimSpace(text), "", "    ", h.width)
+	doc.ToText(w, strings.TrimSpace(text), "", "    ", h.width) //nolint:staticcheck // cross-package links not possible
 	for _, line := range strings.Split(strings.TrimSpace(w.String()), "\n") {
 		h.Print(line)
 	}
@@ -470,7 +472,7 @@ func writeTwoColumns(w *helpWriter, rows [][2]string) {
 
 	for _, row := range rows {
 		buf := bytes.NewBuffer(nil)
-		doc.ToText(buf, row[1], "", strings.Repeat(" ", defaultIndent), w.width-leftSize-defaultColumnPadding)
+		doc.ToText(buf, row[1], "", strings.Repeat(" ", defaultIndent), w.width-leftSize-defaultColumnPadding) //nolint:staticcheck // cross-package links not possible
 		lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
 
 		line := fmt.Sprintf("%-*s", leftSize, row[0])
diff --git a/vendor/github.com/alecthomas/kong/kong.go b/vendor/github.com/alecthomas/kong/kong.go
index b85e145..4f6be87 100644
--- a/vendor/github.com/alecthomas/kong/kong.go
+++ b/vendor/github.com/alecthomas/kong/kong.go
@@ -283,7 +283,7 @@ func (k *Kong) extraFlags() []*Flag {
 	if k.noDefaultHelp {
 		return nil
 	}
-	var helpTarget helpValue
+	var helpTarget helpFlag
 	value := reflect.ValueOf(&helpTarget).Elem()
 	helpFlag := &Flag{
 		Short: 'h',
@@ -311,11 +311,11 @@ func (k *Kong) extraFlags() []*Flag {
 // invalid one, which will report a normal error).
 func (k *Kong) Parse(args []string) (ctx *Context, err error) {
 	ctx, err = Trace(k, args)
-	if err != nil {
-		return nil, err
+	if err != nil { // Trace is not expected to return an err
+		return nil, &ParseError{error: err, Context: ctx, exitCode: exitUsageError}
 	}
 	if ctx.Error != nil {
-		return nil, &ParseError{error: ctx.Error, Context: ctx}
+		return nil, &ParseError{error: ctx.Error, Context: ctx, exitCode: exitUsageError}
 	}
 	if err = k.applyHook(ctx, "BeforeReset"); err != nil {
 		return nil, &ParseError{error: err, Context: ctx}
@@ -332,11 +332,11 @@ func (k *Kong) Parse(args []string) (ctx *Context, err error) {
 	if err = k.applyHook(ctx, "BeforeApply"); err != nil {
 		return nil, &ParseError{error: err, Context: ctx}
 	}
-	if _, err = ctx.Apply(); err != nil {
+	if _, err = ctx.Apply(); err != nil { // Apply is not expected to return an err
 		return nil, &ParseError{error: err, Context: ctx}
 	}
 	if err = ctx.Validate(); err != nil {
-		return nil, &ParseError{error: err, Context: ctx}
+		return nil, &ParseError{error: err, Context: ctx, exitCode: exitUsageError}
 	}
 	if err = k.applyHook(ctx, "AfterApply"); err != nil {
 		return nil, &ParseError{error: err, Context: ctx}
@@ -428,13 +428,15 @@ func (k *Kong) Errorf(format string, args ...any) *Kong {
 	return k
 }
 
-// Fatalf writes a message to Kong.Stderr with the application name prefixed then exits with a non-zero status.
+// Fatalf writes a message to Kong.Stderr with the application name prefixed then exits with status 1.
 func (k *Kong) Fatalf(format string, args ...any) {
 	k.Errorf(format, args...)
 	k.Exit(1)
 }
 
 // FatalIfErrorf terminates with an error message if err != nil.
+// If the error implements the ExitCoder interface, the ExitCode() method is called and
+// the application exits with that status. Otherwise, the application exits with status 1.
 func (k *Kong) FatalIfErrorf(err error, args ...any) {
 	if err == nil {
 		return
@@ -455,7 +457,8 @@ func (k *Kong) FatalIfErrorf(err error, args ...any) {
 			fmt.Fprintln(k.Stdout)
 		}
 	}
-	k.Fatalf("%s", msg)
+	k.Errorf("%s", msg)
+	k.Exit(exitCodeFromError(err))
 }
 
 // LoadConfig from path using the loader configured via Configuration(loader).
diff --git a/vendor/github.com/alecthomas/kong/lefthook.yml b/vendor/github.com/alecthomas/kong/lefthook.yml
new file mode 100644
index 0000000..28ba9ad
--- /dev/null
+++ b/vendor/github.com/alecthomas/kong/lefthook.yml
@@ -0,0 +1,11 @@
+output:
+  - success
+  - failure
+pre-push:
+  parallel: true
+  jobs:
+    - name: test
+      run: go test -v ./...
+
+    - name: lint
+      run: golangci-lint run
diff --git a/vendor/github.com/alecthomas/kong/model.go b/vendor/github.com/alecthomas/kong/model.go
index 065fcdd..33a6f33 100644
--- a/vendor/github.com/alecthomas/kong/model.go
+++ b/vendor/github.com/alecthomas/kong/model.go
@@ -167,6 +167,9 @@ func (n *Node) Summary() string {
 		allFlags = append(allFlags, n.Parent.Flags...)
 	}
 	for _, flag := range allFlags {
+		if _, ok := flag.Target.Interface().(helpFlag); ok {
+			continue
+		}
 		if !flag.Required {
 			summary += " [flags]"
 			break
diff --git a/vendor/github.com/alecthomas/kong/options.go b/vendor/github.com/alecthomas/kong/options.go
index 6263202..d20b2fb 100644
--- a/vendor/github.com/alecthomas/kong/options.go
+++ b/vendor/github.com/alecthomas/kong/options.go
@@ -210,15 +210,33 @@ func BindTo(impl, iface any) Option {
 
 // BindToProvider binds an injected value to a provider function.
 //
-// The provider function must have the signature:
+// The provider function must have one of the following signatures:
+//
+//	func(...) (T, error)
+//	func(...) T
 //
-//	func() (any, error)
+// Where arguments to the function are injected by Kong.
 //
 // This is useful when the Run() function of different commands require different values that may
 // not all be initialisable from the main() function.
 func BindToProvider(provider any) Option {
 	return OptionFunc(func(k *Kong) error {
-		return k.bindings.addProvider(provider)
+		return k.bindings.addProvider(provider, false /* singleton */)
+	})
+}
+
+// BindSingletonProvider binds an injected value to a provider function.
+// The provider function must have the signature:
+//
+//	func(...) (T, error)
+//	func(...) T
+//
+// Unlike [BindToProvider], the provider function will only be called
+// at most once, and the result will be cached and reused
+// across multiple recipients of the injected value.
+func BindSingletonProvider(provider any) Option {
+	return OptionFunc(func(k *Kong) error {
+		return k.bindings.addProvider(provider, true /* singleton */)
 	})
 }
 
diff --git a/vendor/github.com/alecthomas/kong/resolver.go b/vendor/github.com/alecthomas/kong/resolver.go
index 29be1b9..3e37ca7 100644
--- a/vendor/github.com/alecthomas/kong/resolver.go
+++ b/vendor/github.com/alecthomas/kong/resolver.go
@@ -63,6 +63,6 @@ func JSON(r io.Reader) (Resolver, error) {
 }
 
 func snakeCase(name string) string {
-	name = strings.Join(strings.Split(strings.Title(name), "-"), "")
+	name = strings.Join(strings.Split(strings.Title(name), "-"), "") //nolint:staticcheck // Unicode punctuation not an issue
 	return strings.ToLower(name[:1]) + name[1:]
 }
diff --git a/vendor/github.com/alecthomas/kong/scanner.go b/vendor/github.com/alecthomas/kong/scanner.go
index 262d16f..68f708e 100644
--- a/vendor/github.com/alecthomas/kong/scanner.go
+++ b/vendor/github.com/alecthomas/kong/scanner.go
@@ -203,6 +203,11 @@ func (s *Scanner) Peek() Token {
 	return s.args[0]
 }
 
+// PeekAll remaining tokens
+func (s *Scanner) PeekAll() []Token {
+	return s.args
+}
+
 // Push an untyped Token onto the front of the Scanner.
 func (s *Scanner) Push(arg any) *Scanner {
 	s.PushToken(Token{Value: arg})
diff --git a/vendor/modules.txt b/vendor/modules.txt
index ae24ea0..e966698 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -50,7 +50,7 @@ github.com/VividCortex/ewma
 # github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
 ## explicit
 github.com/acarl005/stripansi
-# github.com/alecthomas/kong v1.6.1
+# github.com/alecthomas/kong v1.9.0
 ## explicit; go 1.20
 github.com/alecthomas/kong
 # github.com/andybalholm/brotli v1.1.1