diff --git a/cmd/flux/completion.go b/cmd/flux/completion.go
index 08406ac7ffa68bf60b22d5854afbcae17783d2a0..077d768eb6878371d67ab36e1e2a15585d4df9f4 100644
--- a/cmd/flux/completion.go
+++ b/cmd/flux/completion.go
@@ -17,7 +17,18 @@ limitations under the License.
 package main
 
 import (
+	"context"
+	"strings"
+
+	"github.com/fluxcd/flux2/internal/utils"
 	"github.com/spf13/cobra"
+	"k8s.io/apimachinery/pkg/api/meta"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/client-go/discovery"
+	memory "k8s.io/client-go/discovery/cached"
+	"k8s.io/client-go/dynamic"
+	"k8s.io/client-go/restmapper"
 )
 
 var completionCmd = &cobra.Command{
@@ -29,3 +40,77 @@ var completionCmd = &cobra.Command{
 func init() {
 	rootCmd.AddCommand(completionCmd)
 }
+
+func contextsCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+	rawConfig, err := utils.ClientConfig(rootArgs.kubeconfig, rootArgs.kubecontext).RawConfig()
+	if err != nil {
+		return completionError(err)
+	}
+
+	var comps []string
+
+	for name := range rawConfig.Contexts {
+		if strings.HasPrefix(name, toComplete) {
+			comps = append(comps, name)
+		}
+	}
+
+	return comps, cobra.ShellCompDirectiveNoFileComp
+}
+
+func resourceNamesCompletionFunc(gvk schema.GroupVersionKind) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+	return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+		ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
+		defer cancel()
+
+		cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
+		if err != nil {
+			return completionError(err)
+		}
+
+		dc, err := discovery.NewDiscoveryClientForConfig(cfg)
+		if err != nil {
+			return completionError(err)
+		}
+		mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(dc))
+
+		mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
+		if err != nil {
+			return completionError(err)
+		}
+
+		client, err := dynamic.NewForConfig(cfg)
+		if err != nil {
+			return completionError(err)
+		}
+
+		var dr dynamic.ResourceInterface
+		if mapping.Scope.Name() == meta.RESTScopeNameNamespace {
+			dr = client.Resource(mapping.Resource).Namespace(rootArgs.namespace)
+		} else {
+			dr = client.Resource(mapping.Resource)
+		}
+
+		list, err := dr.List(ctx, metav1.ListOptions{})
+		if err != nil {
+			return completionError(err)
+		}
+
+		var comps []string
+
+		for _, item := range list.Items {
+			name := item.GetName()
+
+			if strings.HasPrefix(name, toComplete) {
+				comps = append(comps, name)
+			}
+		}
+
+		return comps, cobra.ShellCompDirectiveNoFileComp
+	}
+}
+
+func completionError(err error) ([]string, cobra.ShellCompDirective) {
+	cobra.CompError(err.Error())
+	return nil, cobra.ShellCompDirectiveError
+}
diff --git a/cmd/flux/delete_alert.go b/cmd/flux/delete_alert.go
index 3b1ac9ce25e8f0b761682597d539366ad538c642..c9e6f1abb35426777f3585b88d2f8fdeb9f8a6a2 100644
--- a/cmd/flux/delete_alert.go
+++ b/cmd/flux/delete_alert.go
@@ -28,6 +28,7 @@ var deleteAlertCmd = &cobra.Command{
 	Long:  "The delete alert command removes the given Alert from the cluster.",
 	Example: `  # Delete an Alert and the Kubernetes resources created by it
   flux delete alert main`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)),
 	RunE: deleteCommand{
 		apiType: alertType,
 		object:  universalAdapter{&notificationv1.Alert{}},
diff --git a/cmd/flux/delete_alertprovider.go b/cmd/flux/delete_alertprovider.go
index c1de6fea04446497cb838aafb6f428b54696f5a9..08f0526c3b33528d775ec07d3f7465de3899fc6e 100644
--- a/cmd/flux/delete_alertprovider.go
+++ b/cmd/flux/delete_alertprovider.go
@@ -28,6 +28,7 @@ var deleteAlertProviderCmd = &cobra.Command{
 	Long:  "The delete alert-provider command removes the given Provider from the cluster.",
 	Example: `  # Delete a Provider and the Kubernetes resources created by it
   flux delete alert-provider slack`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)),
 	RunE: deleteCommand{
 		apiType: alertProviderType,
 		object:  universalAdapter{&notificationv1.Provider{}},
diff --git a/cmd/flux/delete_helmrelease.go b/cmd/flux/delete_helmrelease.go
index 05ad157afe05540716d495557de9c455cba5a7a3..c721d3dcba46a858cfc2b1c2798d7806f3d13e95 100644
--- a/cmd/flux/delete_helmrelease.go
+++ b/cmd/flux/delete_helmrelease.go
@@ -29,6 +29,7 @@ var deleteHelmReleaseCmd = &cobra.Command{
 	Long:    "The delete helmrelease command removes the given HelmRelease from the cluster.",
 	Example: `  # Delete a Helm release and the Kubernetes resources created by it
   flux delete hr podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)),
 	RunE: deleteCommand{
 		apiType: helmReleaseType,
 		object:  universalAdapter{&helmv2.HelmRelease{}},
diff --git a/cmd/flux/delete_image_policy.go b/cmd/flux/delete_image_policy.go
index a11b7b5915a1e211b4ee9f024de3feced54b7286..e86924da990c9cdf44ae2da3e4ecba73b275a04d 100644
--- a/cmd/flux/delete_image_policy.go
+++ b/cmd/flux/delete_image_policy.go
@@ -28,6 +28,7 @@ var deleteImagePolicyCmd = &cobra.Command{
 	Long:  "The delete image policy command deletes the given ImagePolicy from the cluster.",
 	Example: `  # Delete an image policy
   flux delete image policy alpine3.x`,
+	ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind)),
 	RunE: deleteCommand{
 		apiType: imagePolicyType,
 		object:  universalAdapter{&imagev1.ImagePolicy{}},
diff --git a/cmd/flux/delete_image_repository.go b/cmd/flux/delete_image_repository.go
index 10b85ff902bbd81a207530c2f6e813c83d512544..a8769788a5e2d2edd8f0f7ef3f4211e9e4920726 100644
--- a/cmd/flux/delete_image_repository.go
+++ b/cmd/flux/delete_image_repository.go
@@ -28,6 +28,7 @@ var deleteImageRepositoryCmd = &cobra.Command{
 	Long:  "The delete image repository command deletes the given ImageRepository from the cluster.",
 	Example: `  # Delete an image repository
   flux delete image repository alpine`,
+	ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)),
 	RunE: deleteCommand{
 		apiType: imageRepositoryType,
 		object:  universalAdapter{&imagev1.ImageRepository{}},
diff --git a/cmd/flux/delete_image_update.go b/cmd/flux/delete_image_update.go
index cede3840a657efc71bf7891f1fbab40ba13b6966..3c38f078d29acd62df264be271fadd25123eb1f3 100644
--- a/cmd/flux/delete_image_update.go
+++ b/cmd/flux/delete_image_update.go
@@ -28,6 +28,7 @@ var deleteImageUpdateCmd = &cobra.Command{
 	Long:  "The delete image update command deletes the given ImageUpdateAutomation from the cluster.",
 	Example: `  # Delete an image update automation
   flux delete image update latest-images`,
+	ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)),
 	RunE: deleteCommand{
 		apiType: imageUpdateAutomationType,
 		object:  universalAdapter{&autov1.ImageUpdateAutomation{}},
diff --git a/cmd/flux/delete_kustomization.go b/cmd/flux/delete_kustomization.go
index 5e03ad9526291671b7da28df45ebb409e3b9ff51..142eed262572295e84fc516bd3b0858edd551f79 100644
--- a/cmd/flux/delete_kustomization.go
+++ b/cmd/flux/delete_kustomization.go
@@ -29,6 +29,7 @@ var deleteKsCmd = &cobra.Command{
 	Long:    "The delete kustomization command deletes the given Kustomization from the cluster.",
 	Example: `  # Delete a kustomization and the Kubernetes resources created by it
   flux delete kustomization podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
 	RunE: deleteCommand{
 		apiType: kustomizationType,
 		object:  universalAdapter{&kustomizev1.Kustomization{}},
diff --git a/cmd/flux/delete_receiver.go b/cmd/flux/delete_receiver.go
index 5806b6df8ff30c92beadf90ac03543cba1c6cc3b..bfdc5dbc8910ce1d244203091ff24d664b35f19d 100644
--- a/cmd/flux/delete_receiver.go
+++ b/cmd/flux/delete_receiver.go
@@ -28,6 +28,7 @@ var deleteReceiverCmd = &cobra.Command{
 	Long:  "The delete receiver command removes the given Receiver from the cluster.",
 	Example: `  # Delete an Receiver and the Kubernetes resources created by it
   flux delete receiver main`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)),
 	RunE: deleteCommand{
 		apiType: receiverType,
 		object:  universalAdapter{&notificationv1.Receiver{}},
diff --git a/cmd/flux/delete_source_bucket.go b/cmd/flux/delete_source_bucket.go
index 3549efb98cbca247d2451dcfe4ced6c56b62173a..56d9bdf8e6f9e51c025fad3cad86664707605390 100644
--- a/cmd/flux/delete_source_bucket.go
+++ b/cmd/flux/delete_source_bucket.go
@@ -28,6 +28,7 @@ var deleteSourceBucketCmd = &cobra.Command{
 	Long:  "The delete source bucket command deletes the given Bucket from the cluster.",
 	Example: `  # Delete a Bucket source
   flux delete source bucket podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)),
 	RunE: deleteCommand{
 		apiType: bucketType,
 		object:  universalAdapter{&sourcev1.Bucket{}},
diff --git a/cmd/flux/delete_source_git.go b/cmd/flux/delete_source_git.go
index 36e4303a011e2ab363113b06a30dd4d0ceeaa299..5c521a5b2e93afd52a43711f92a36ddad05f9266 100644
--- a/cmd/flux/delete_source_git.go
+++ b/cmd/flux/delete_source_git.go
@@ -28,6 +28,7 @@ var deleteSourceGitCmd = &cobra.Command{
 	Long:  "The delete source git command deletes the given GitRepository from the cluster.",
 	Example: `  # Delete a Git repository
   flux delete source git podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)),
 	RunE: deleteCommand{
 		apiType: gitRepositoryType,
 		object:  universalAdapter{&sourcev1.GitRepository{}},
diff --git a/cmd/flux/delete_source_helm.go b/cmd/flux/delete_source_helm.go
index 35cc2ad073ff2d679bafa8a823d73514d894ddb0..87b708ad72abb956234e8d2533e87c21f7425123 100644
--- a/cmd/flux/delete_source_helm.go
+++ b/cmd/flux/delete_source_helm.go
@@ -28,6 +28,7 @@ var deleteSourceHelmCmd = &cobra.Command{
 	Long:  "The delete source helm command deletes the given HelmRepository from the cluster.",
 	Example: `  # Delete a Helm repository
   flux delete source helm podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)),
 	RunE: deleteCommand{
 		apiType: helmRepositoryType,
 		object:  universalAdapter{&sourcev1.HelmRepository{}},
diff --git a/cmd/flux/export_alert.go b/cmd/flux/export_alert.go
index 32b660e2c5340a139df04f3653e65b1983938199..9c358e0c643a9124f9dcbd42fc2bfe2e8326fcdc 100644
--- a/cmd/flux/export_alert.go
+++ b/cmd/flux/export_alert.go
@@ -32,6 +32,7 @@ var exportAlertCmd = &cobra.Command{
 
   # Export a Alert
   flux export alert main > main.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)),
 	RunE: exportCommand{
 		object: alertAdapter{&notificationv1.Alert{}},
 		list:   alertListAdapter{&notificationv1.AlertList{}},
diff --git a/cmd/flux/export_alertprovider.go b/cmd/flux/export_alertprovider.go
index ddb6fe2fdf7ad7f59f5dc102e21e79204f6b6070..eb47294f9a6ee5c55e48993a78fe9f8072cf7688 100644
--- a/cmd/flux/export_alertprovider.go
+++ b/cmd/flux/export_alertprovider.go
@@ -32,6 +32,7 @@ var exportAlertProviderCmd = &cobra.Command{
 
   # Export a Provider
   flux export alert-provider slack > slack.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)),
 	RunE: exportCommand{
 		object: alertProviderAdapter{&notificationv1.Provider{}},
 		list:   alertProviderListAdapter{&notificationv1.ProviderList{}},
diff --git a/cmd/flux/export_helmrelease.go b/cmd/flux/export_helmrelease.go
index 961caa3c4b4689bfbf0c133aad45abc74f9f246b..8fd8c87fb3035818285af711d10892d8dde420f9 100644
--- a/cmd/flux/export_helmrelease.go
+++ b/cmd/flux/export_helmrelease.go
@@ -33,6 +33,7 @@ var exportHelmReleaseCmd = &cobra.Command{
 
   # Export a HelmRelease
   flux export hr my-app > app-release.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)),
 	RunE: exportCommand{
 		object: helmReleaseAdapter{&helmv2.HelmRelease{}},
 		list:   helmReleaseListAdapter{&helmv2.HelmReleaseList{}},
diff --git a/cmd/flux/export_image_policy.go b/cmd/flux/export_image_policy.go
index 6aa64f7b055941c021f57ffd175f92712f7c96f6..5302dd635d629d2c95eace5f9f6d8949bab1aac8 100644
--- a/cmd/flux/export_image_policy.go
+++ b/cmd/flux/export_image_policy.go
@@ -32,6 +32,7 @@ var exportImagePolicyCmd = &cobra.Command{
 
   # Export a specific policy
   flux export image policy alpine1x > alpine1x.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind)),
 	RunE: exportCommand{
 		object: imagePolicyAdapter{&imagev1.ImagePolicy{}},
 		list:   imagePolicyListAdapter{&imagev1.ImagePolicyList{}},
diff --git a/cmd/flux/export_image_repository.go b/cmd/flux/export_image_repository.go
index 7fad1da639ddb3a6a53ec884a0a61433d7a6c1c3..13f72f7d43b08c589412ca45cb219c4c5cd6ca4b 100644
--- a/cmd/flux/export_image_repository.go
+++ b/cmd/flux/export_image_repository.go
@@ -32,6 +32,7 @@ var exportImageRepositoryCmd = &cobra.Command{
 
   # Export a specific ImageRepository resource
   flux export image repository alpine > alpine.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)),
 	RunE: exportCommand{
 		object: imageRepositoryAdapter{&imagev1.ImageRepository{}},
 		list:   imageRepositoryListAdapter{&imagev1.ImageRepositoryList{}},
diff --git a/cmd/flux/export_image_update.go b/cmd/flux/export_image_update.go
index 6d6fcffabc6b57933fa980d78efe6bef04b229de..44f4b4a165a84840d375aa6ffb9ec7d066a1ecfd 100644
--- a/cmd/flux/export_image_update.go
+++ b/cmd/flux/export_image_update.go
@@ -32,6 +32,7 @@ var exportImageUpdateCmd = &cobra.Command{
 
   # Export a specific automation
   flux export image update latest-images > latest.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)),
 	RunE: exportCommand{
 		object: imageUpdateAutomationAdapter{&autov1.ImageUpdateAutomation{}},
 		list:   imageUpdateAutomationListAdapter{&autov1.ImageUpdateAutomationList{}},
diff --git a/cmd/flux/export_kustomization.go b/cmd/flux/export_kustomization.go
index d6f4e1db8613c01a7c9f3c5ea5fadf354a2a349a..fcf488194cdc63d760e30cdb030459b1ccfeca4e 100644
--- a/cmd/flux/export_kustomization.go
+++ b/cmd/flux/export_kustomization.go
@@ -33,6 +33,7 @@ var exportKsCmd = &cobra.Command{
 
   # Export a Kustomization
   flux export kustomization my-app > kustomization.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
 	RunE: exportCommand{
 		object: kustomizationAdapter{&kustomizev1.Kustomization{}},
 		list:   kustomizationListAdapter{&kustomizev1.KustomizationList{}},
diff --git a/cmd/flux/export_receiver.go b/cmd/flux/export_receiver.go
index 54c8e75debefa99d2a131b7be32b06b001dc5e75..0a79d853c7e3dfe34a617b41041b2c5b94f6dd8e 100644
--- a/cmd/flux/export_receiver.go
+++ b/cmd/flux/export_receiver.go
@@ -32,6 +32,7 @@ var exportReceiverCmd = &cobra.Command{
 
   # Export a Receiver
   flux export receiver main > main.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)),
 	RunE: exportCommand{
 		list:   receiverListAdapter{&notificationv1.ReceiverList{}},
 		object: receiverAdapter{&notificationv1.Receiver{}},
diff --git a/cmd/flux/export_source_bucket.go b/cmd/flux/export_source_bucket.go
index 7a7039c180c717889f2167c8950fb249b676c32f..33e36ebd17059d4275825bf96b7474c505c0f103 100644
--- a/cmd/flux/export_source_bucket.go
+++ b/cmd/flux/export_source_bucket.go
@@ -33,6 +33,7 @@ var exportSourceBucketCmd = &cobra.Command{
 
   # Export a Bucket source including the static credentials
   flux export source bucket my-bucket --with-credentials > source.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)),
 	RunE: exportWithSecretCommand{
 		list:   bucketListAdapter{&sourcev1.BucketList{}},
 		object: bucketAdapter{&sourcev1.Bucket{}},
diff --git a/cmd/flux/export_source_git.go b/cmd/flux/export_source_git.go
index 7f0691930aa309603c864a32358a419ba62c1984..c93e0fd1a1f435754136b259377073562f70317b 100644
--- a/cmd/flux/export_source_git.go
+++ b/cmd/flux/export_source_git.go
@@ -33,6 +33,7 @@ var exportSourceGitCmd = &cobra.Command{
 
   # Export a GitRepository source including the SSH key pair or basic auth credentials
   flux export source git my-private-repo --with-credentials > source.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)),
 	RunE: exportWithSecretCommand{
 		object: gitRepositoryAdapter{&sourcev1.GitRepository{}},
 		list:   gitRepositoryListAdapter{&sourcev1.GitRepositoryList{}},
diff --git a/cmd/flux/export_source_helm.go b/cmd/flux/export_source_helm.go
index 62499987b6b8588ea9398159c3d815132a911e0d..d22153351080fb7454c31848792659aa5ba33aff 100644
--- a/cmd/flux/export_source_helm.go
+++ b/cmd/flux/export_source_helm.go
@@ -33,6 +33,7 @@ var exportSourceHelmCmd = &cobra.Command{
 
   # Export a HelmRepository source including the basic auth credentials
   flux export source helm my-private-repo --with-credentials > source.yaml`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)),
 	RunE: exportWithSecretCommand{
 		list:   helmRepositoryListAdapter{&sourcev1.HelmRepositoryList{}},
 		object: helmRepositoryAdapter{&sourcev1.HelmRepository{}},
diff --git a/cmd/flux/get_alert.go b/cmd/flux/get_alert.go
index 122d1bc6dee85b336736dec78dff7408bf322da1..126dbe569a59e76d8c005a5079589967745fce0a 100644
--- a/cmd/flux/get_alert.go
+++ b/cmd/flux/get_alert.go
@@ -34,6 +34,7 @@ var getAlertCmd = &cobra.Command{
 	Long:    "The get alert command prints the statuses of the resources.",
 	Example: `  # List all Alerts and their status
   flux get alerts`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: alertType,
diff --git a/cmd/flux/get_alertprovider.go b/cmd/flux/get_alertprovider.go
index 4c7f6105232faf6238d7560319cf419fffbc6de2..cb27973f731df841f96143078d294c856b689cdb 100644
--- a/cmd/flux/get_alertprovider.go
+++ b/cmd/flux/get_alertprovider.go
@@ -32,6 +32,7 @@ var getAlertProviderCmd = &cobra.Command{
 	Long:    "The get alert-provider command prints the statuses of the resources.",
 	Example: `  # List all Providers and their status
   flux get alert-providers`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: alertProviderType,
diff --git a/cmd/flux/get_helmrelease.go b/cmd/flux/get_helmrelease.go
index f489aa8761472d4ed75c3f41c2a2b26608a5c982..5478e29c0663ead8053312313bbe10437402bca8 100644
--- a/cmd/flux/get_helmrelease.go
+++ b/cmd/flux/get_helmrelease.go
@@ -33,6 +33,7 @@ var getHelmReleaseCmd = &cobra.Command{
 	Long:    "The get helmreleases command prints the statuses of the resources.",
 	Example: `  # List all Helm releases and their status
   flux get helmreleases`,
+	ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: helmReleaseType,
diff --git a/cmd/flux/get_image_policy.go b/cmd/flux/get_image_policy.go
index fe73118d8af821974a6be781740a52ab76faa95f..7974c380e33d597d5e5c1f6c613f6bbb0e2460bf 100644
--- a/cmd/flux/get_image_policy.go
+++ b/cmd/flux/get_image_policy.go
@@ -34,6 +34,7 @@ var getImagePolicyCmd = &cobra.Command{
 
  # List image policies from all namespaces
   flux get image policy --all-namespaces`,
+	ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: imagePolicyType,
diff --git a/cmd/flux/get_image_repository.go b/cmd/flux/get_image_repository.go
index a5b55feaa1967698b29b459ece7848c98fc70977..0878a29c01a5df86bf40c57a0df8fd12f091d1ea 100644
--- a/cmd/flux/get_image_repository.go
+++ b/cmd/flux/get_image_repository.go
@@ -37,6 +37,7 @@ var getImageRepositoryCmd = &cobra.Command{
 
  # List image repositories from all namespaces
   flux get image repository --all-namespaces`,
+	ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: imageRepositoryType,
diff --git a/cmd/flux/get_image_update.go b/cmd/flux/get_image_update.go
index 9c34f95d1cfb234cededa545b8f863898a2badde..da16c57611c494a10699403378dcfead3b83684f 100644
--- a/cmd/flux/get_image_update.go
+++ b/cmd/flux/get_image_update.go
@@ -37,6 +37,7 @@ var getImageUpdateCmd = &cobra.Command{
 
  # List image update automations from all namespaces
   flux get image update --all-namespaces`,
+	ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: imageUpdateAutomationType,
diff --git a/cmd/flux/get_kustomization.go b/cmd/flux/get_kustomization.go
index d507b2a5cb091b80f405052a80797ea4681ae4c8..3e749b2d691ac2d251eef3aa5f8fac2c4e1739d1 100644
--- a/cmd/flux/get_kustomization.go
+++ b/cmd/flux/get_kustomization.go
@@ -34,6 +34,7 @@ var getKsCmd = &cobra.Command{
 	Long:    "The get kustomizations command prints the statuses of the resources.",
 	Example: `  # List all kustomizations and their status
   flux get kustomizations`,
+	ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: kustomizationType,
diff --git a/cmd/flux/get_receiver.go b/cmd/flux/get_receiver.go
index f3da4bb4747b5f466123734bd0d04baafc58440c..d2147d1b18a557bafb5a17c244cd67cafc02e288 100644
--- a/cmd/flux/get_receiver.go
+++ b/cmd/flux/get_receiver.go
@@ -34,6 +34,7 @@ var getReceiverCmd = &cobra.Command{
 	Long:    "The get receiver command prints the statuses of the resources.",
 	Example: `  # List all Receiver and their status
   flux get receivers`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: receiverType,
diff --git a/cmd/flux/get_source_bucket.go b/cmd/flux/get_source_bucket.go
index c34ef8c271cd567ef49a619b173ffe3b3f89a5a6..963a8ed416a9cefc33891693811325ed8ebca88a 100644
--- a/cmd/flux/get_source_bucket.go
+++ b/cmd/flux/get_source_bucket.go
@@ -36,6 +36,7 @@ var getSourceBucketCmd = &cobra.Command{
 
  # List buckets from all namespaces
   flux get sources helm --all-namespaces`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: bucketType,
diff --git a/cmd/flux/get_source_chart.go b/cmd/flux/get_source_chart.go
index 3e890a5faca7a58352942a5acde4397319783141..f5401791f3405cd56f2ac76444509557fdae726b 100644
--- a/cmd/flux/get_source_chart.go
+++ b/cmd/flux/get_source_chart.go
@@ -36,6 +36,7 @@ var getSourceHelmChartCmd = &cobra.Command{
 
  # List Helm charts from all namespaces
   flux get sources chart --all-namespaces`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmChartKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: helmChartType,
diff --git a/cmd/flux/get_source_git.go b/cmd/flux/get_source_git.go
index 75639903ef020775da17753386da9a98c4b34376..31a8e5bd7da22626c3b14a518e61e65b82f7ad89 100644
--- a/cmd/flux/get_source_git.go
+++ b/cmd/flux/get_source_git.go
@@ -36,6 +36,7 @@ var getSourceGitCmd = &cobra.Command{
 
  # List Git repositories from all namespaces
   flux get sources git --all-namespaces`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: gitRepositoryType,
diff --git a/cmd/flux/get_source_helm.go b/cmd/flux/get_source_helm.go
index e0d0bb4d437a9dd646ae824b3b81f488bd62a322..cf98246b59c8ac8f1db2e243340632c7f5ecae9a 100644
--- a/cmd/flux/get_source_helm.go
+++ b/cmd/flux/get_source_helm.go
@@ -36,6 +36,7 @@ var getSourceHelmCmd = &cobra.Command{
 
  # List Helm repositories from all namespaces
   flux get sources helm --all-namespaces`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		get := getCommand{
 			apiType: helmRepositoryType,
diff --git a/cmd/flux/main.go b/cmd/flux/main.go
index 9295e83ea3ea7eb6daf56a62d46e666a44c10497..5bd8fa508a2c0eab70bf2f8561d138f13689d846 100644
--- a/cmd/flux/main.go
+++ b/cmd/flux/main.go
@@ -23,6 +23,7 @@ import (
 	"time"
 
 	"github.com/spf13/cobra"
+	corev1 "k8s.io/api/core/v1"
 	_ "k8s.io/client-go/plugin/pkg/client/auth"
 
 	"github.com/fluxcd/flux2/pkg/manifestgen/install"
@@ -108,11 +109,15 @@ var rootArgs = NewRootFlags()
 
 func init() {
 	rootCmd.PersistentFlags().StringVarP(&rootArgs.namespace, "namespace", "n", rootArgs.defaults.Namespace, "the namespace scope for this operation")
+	rootCmd.RegisterFlagCompletionFunc("namespace", resourceNamesCompletionFunc(corev1.SchemeGroupVersion.WithKind("Namespace")))
+
 	rootCmd.PersistentFlags().DurationVar(&rootArgs.timeout, "timeout", 5*time.Minute, "timeout for this operation")
 	rootCmd.PersistentFlags().BoolVar(&rootArgs.verbose, "verbose", false, "print generated objects")
 	rootCmd.PersistentFlags().StringVarP(&rootArgs.kubeconfig, "kubeconfig", "", "",
 		"absolute path to the kubeconfig file")
+
 	rootCmd.PersistentFlags().StringVarP(&rootArgs.kubecontext, "context", "", "", "kubernetes context to use")
+	rootCmd.RegisterFlagCompletionFunc("context", contextsCompletionFunc)
 
 	rootCmd.DisableAutoGenTag = true
 }
diff --git a/cmd/flux/reconcile_alert.go b/cmd/flux/reconcile_alert.go
index 2bc79c9c82874e0b33acd6534c480df557848e9b..6027da3ef435726625809134f3ace7641966f642 100644
--- a/cmd/flux/reconcile_alert.go
+++ b/cmd/flux/reconcile_alert.go
@@ -28,6 +28,7 @@ var reconcileAlertCmd = &cobra.Command{
 	Long:  `The reconcile alert command triggers a reconciliation of an Alert resource and waits for it to finish.`,
 	Example: `  # Trigger a reconciliation for an existing alert
   flux reconcile alert main`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)),
 	RunE: reconcileCommand{
 		apiType: alertType,
 		object:  alertAdapter{&notificationv1.Alert{}},
diff --git a/cmd/flux/reconcile_alertprovider.go b/cmd/flux/reconcile_alertprovider.go
index ccf68bdbd505284c16f21895fdb04bd51945354f..092e8ac90b0a0e0a6dc6fdcf55063a6c7d67507b 100644
--- a/cmd/flux/reconcile_alertprovider.go
+++ b/cmd/flux/reconcile_alertprovider.go
@@ -37,7 +37,8 @@ var reconcileAlertProviderCmd = &cobra.Command{
 	Long:  `The reconcile alert-provider command triggers a reconciliation of a Provider resource and waits for it to finish.`,
 	Example: `  # Trigger a reconciliation for an existing provider
   flux reconcile alert-provider slack`,
-	RunE: reconcileAlertProviderCmdRun,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ProviderKind)),
+	RunE:              reconcileAlertProviderCmdRun,
 }
 
 func init() {
diff --git a/cmd/flux/reconcile_helmrelease.go b/cmd/flux/reconcile_helmrelease.go
index 0262dad9c5be2bb530b12cf2c798f8bd3b5be526..38558a0fe76a9a3617b3d8562d045c82116555f0 100644
--- a/cmd/flux/reconcile_helmrelease.go
+++ b/cmd/flux/reconcile_helmrelease.go
@@ -35,6 +35,7 @@ The reconcile kustomization command triggers a reconciliation of a HelmRelease r
 
   # Trigger a reconciliation of the HelmRelease's source and apply changes
   flux reconcile hr podinfo --with-source`,
+	ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)),
 	RunE: reconcileWithSourceCommand{
 		apiType: helmReleaseType,
 		object:  helmReleaseAdapter{&helmv2.HelmRelease{}},
diff --git a/cmd/flux/reconcile_image_repository.go b/cmd/flux/reconcile_image_repository.go
index d2e4c0875ab347724a37989c800a834502b7bccf..efd89e9c570299b351870abef32cbc9d265bd97d 100644
--- a/cmd/flux/reconcile_image_repository.go
+++ b/cmd/flux/reconcile_image_repository.go
@@ -30,6 +30,7 @@ var reconcileImageRepositoryCmd = &cobra.Command{
 	Long:  `The reconcile image repository command triggers a reconciliation of an ImageRepository resource and waits for it to finish.`,
 	Example: `  # Trigger an scan for an existing image repository
   flux reconcile image repository alpine`,
+	ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImagePolicyKind)),
 	RunE: reconcileCommand{
 		apiType: imageRepositoryType,
 		object:  imageRepositoryAdapter{&imagev1.ImageRepository{}},
diff --git a/cmd/flux/reconcile_image_updateauto.go b/cmd/flux/reconcile_image_updateauto.go
index b1af0d56154d7c7fbc374484d6521b08dbdd6924..8fba13ccf4374f9197358320089d9e1a29070843 100644
--- a/cmd/flux/reconcile_image_updateauto.go
+++ b/cmd/flux/reconcile_image_updateauto.go
@@ -32,6 +32,7 @@ var reconcileImageUpdateCmd = &cobra.Command{
 	Long:  `The reconcile image update command triggers a reconciliation of an ImageUpdateAutomation resource and waits for it to finish.`,
 	Example: `  # Trigger an automation run for an existing image update automation
   flux reconcile image update latest-images`,
+	ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)),
 	RunE: reconcileCommand{
 		apiType: imageUpdateAutomationType,
 		object:  imageUpdateAutomationAdapter{&autov1.ImageUpdateAutomation{}},
diff --git a/cmd/flux/reconcile_kustomization.go b/cmd/flux/reconcile_kustomization.go
index d108bcfa0eec2d729cc8d54089883df30b3ff6ac..48b7ec2ece223e584963e2b14fd4a22cd42cbbfc 100644
--- a/cmd/flux/reconcile_kustomization.go
+++ b/cmd/flux/reconcile_kustomization.go
@@ -35,6 +35,7 @@ The reconcile kustomization command triggers a reconciliation of a Kustomization
 
   # Trigger a sync of the Kustomization's source and apply changes
   flux reconcile kustomization podinfo --with-source`,
+	ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
 	RunE: reconcileWithSourceCommand{
 		apiType: kustomizationType,
 		object:  kustomizationAdapter{&kustomizev1.Kustomization{}},
diff --git a/cmd/flux/reconcile_receiver.go b/cmd/flux/reconcile_receiver.go
index 8ec849def83b7c507d19092fa93fbd885d9034c4..9b7e7fd042f10e606fdb583411a34b98e9d8baf3 100644
--- a/cmd/flux/reconcile_receiver.go
+++ b/cmd/flux/reconcile_receiver.go
@@ -37,7 +37,8 @@ var reconcileReceiverCmd = &cobra.Command{
 	Long:  `The reconcile receiver command triggers a reconciliation of a Receiver resource and waits for it to finish.`,
 	Example: `  # Trigger a reconciliation for an existing receiver
   flux reconcile receiver main`,
-	RunE: reconcileReceiverCmdRun,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)),
+	RunE:              reconcileReceiverCmdRun,
 }
 
 func init() {
diff --git a/cmd/flux/reconcile_source_bucket.go b/cmd/flux/reconcile_source_bucket.go
index 6fa346baa69a0b7ec46edc3ec246f17fc0eec497..768071da20d010b6dca102ef25e9bdb25589466d 100644
--- a/cmd/flux/reconcile_source_bucket.go
+++ b/cmd/flux/reconcile_source_bucket.go
@@ -37,6 +37,7 @@ var reconcileSourceBucketCmd = &cobra.Command{
 	Long:  `The reconcile source command triggers a reconciliation of a Bucket resource and waits for it to finish.`,
 	Example: `  # Trigger a reconciliation for an existing source
   flux reconcile source bucket podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)),
 	RunE: reconcileCommand{
 		apiType: bucketType,
 		object:  bucketAdapter{&sourcev1.Bucket{}},
diff --git a/cmd/flux/reconcile_source_git.go b/cmd/flux/reconcile_source_git.go
index 9c01a8fce7bfcfd7b1c17dbe61ce81c592c83eb7..9b5a75be13889ed385506e619e5f0eb3fcca2c51 100644
--- a/cmd/flux/reconcile_source_git.go
+++ b/cmd/flux/reconcile_source_git.go
@@ -30,6 +30,7 @@ var reconcileSourceGitCmd = &cobra.Command{
 	Long:  `The reconcile source command triggers a reconciliation of a GitRepository resource and waits for it to finish.`,
 	Example: `  # Trigger a git pull for an existing source
   flux reconcile source git podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)),
 	RunE: reconcileCommand{
 		apiType: gitRepositoryType,
 		object:  gitRepositoryAdapter{&sourcev1.GitRepository{}},
diff --git a/cmd/flux/reconcile_source_helm.go b/cmd/flux/reconcile_source_helm.go
index 736b924548026fe41c4280e1c9992879b4fb58a0..e0836259c4a3374142d44a690413ce14c0ee9ed0 100644
--- a/cmd/flux/reconcile_source_helm.go
+++ b/cmd/flux/reconcile_source_helm.go
@@ -30,6 +30,7 @@ var reconcileSourceHelmCmd = &cobra.Command{
 	Long:  `The reconcile source command triggers a reconciliation of a HelmRepository resource and waits for it to finish.`,
 	Example: `  # Trigger a reconciliation for an existing source
   flux reconcile source helm podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)),
 	RunE: reconcileCommand{
 		apiType: helmRepositoryType,
 		object:  helmRepositoryAdapter{&sourcev1.HelmRepository{}},
diff --git a/cmd/flux/resume_alert.go b/cmd/flux/resume_alert.go
index de5a645a7b2e07b8ff15ea7a4b5b5a51554a79a2..bede1e3efaaa9f124f406045eb830916e0de3e71 100644
--- a/cmd/flux/resume_alert.go
+++ b/cmd/flux/resume_alert.go
@@ -29,6 +29,7 @@ var resumeAlertCmd = &cobra.Command{
 finish the apply.`,
 	Example: `  # Resume reconciliation for an existing Alert
   flux resume alert main`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)),
 	RunE: resumeCommand{
 		apiType: alertType,
 		object:  alertAdapter{&notificationv1.Alert{}},
diff --git a/cmd/flux/resume_helmrelease.go b/cmd/flux/resume_helmrelease.go
index 24ee8010fce798ef2e8b20dd897103c7d0907ab9..0de4fb9042004ba849841335f750e43cd0495b59 100644
--- a/cmd/flux/resume_helmrelease.go
+++ b/cmd/flux/resume_helmrelease.go
@@ -32,6 +32,7 @@ var resumeHrCmd = &cobra.Command{
 finish the apply.`,
 	Example: `  # Resume reconciliation for an existing Helm release
   flux resume hr podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)),
 	RunE: resumeCommand{
 		apiType: helmReleaseType,
 		object:  helmReleaseAdapter{&helmv2.HelmRelease{}},
diff --git a/cmd/flux/resume_image_repository.go b/cmd/flux/resume_image_repository.go
index 59349c55e08cbe6a2e5b4131e5de3560b47c8338..b0c15b189d93672e0b520abdb7873719fe7f1656 100644
--- a/cmd/flux/resume_image_repository.go
+++ b/cmd/flux/resume_image_repository.go
@@ -28,6 +28,7 @@ var resumeImageRepositoryCmd = &cobra.Command{
 	Long:  `The resume command marks a previously suspended ImageRepository resource for reconciliation and waits for it to finish.`,
 	Example: `  # Resume reconciliation for an existing ImageRepository
   flux resume image repository alpine`,
+	ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)),
 	RunE: resumeCommand{
 		apiType: imageRepositoryType,
 		object:  imageRepositoryAdapter{&imagev1.ImageRepository{}},
diff --git a/cmd/flux/resume_image_updateauto.go b/cmd/flux/resume_image_updateauto.go
index c7e45d74a80efb79264c10ec274c48029ab69086..8cc40bfc80e53c4ae728218c9e358cc962024df0 100644
--- a/cmd/flux/resume_image_updateauto.go
+++ b/cmd/flux/resume_image_updateauto.go
@@ -28,6 +28,7 @@ var resumeImageUpdateCmd = &cobra.Command{
 	Long:  `The resume command marks a previously suspended ImageUpdateAutomation resource for reconciliation and waits for it to finish.`,
 	Example: `  # Resume reconciliation for an existing ImageUpdateAutomation
   flux resume image update latest-images`,
+	ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)),
 	RunE: resumeCommand{
 		apiType: imageUpdateAutomationType,
 		object:  imageUpdateAutomationAdapter{&autov1.ImageUpdateAutomation{}},
diff --git a/cmd/flux/resume_kustomization.go b/cmd/flux/resume_kustomization.go
index 1555cc9a32b3279adf28d7871c5b3ccd1a065ba0..78bc5e6645fffec34adb04b0a552eace5c532ac9 100644
--- a/cmd/flux/resume_kustomization.go
+++ b/cmd/flux/resume_kustomization.go
@@ -32,6 +32,7 @@ var resumeKsCmd = &cobra.Command{
 finish the apply.`,
 	Example: `  # Resume reconciliation for an existing Kustomization
   flux resume ks podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
 	RunE: resumeCommand{
 		apiType: kustomizationType,
 		object:  kustomizationAdapter{&kustomizev1.Kustomization{}},
diff --git a/cmd/flux/resume_receiver.go b/cmd/flux/resume_receiver.go
index eecfe63d9fc7aee70bd87715e4d0fedc38a2dbe6..d4d3c64be099d3f42d27ef67d2fa601157cabddc 100644
--- a/cmd/flux/resume_receiver.go
+++ b/cmd/flux/resume_receiver.go
@@ -29,6 +29,7 @@ var resumeReceiverCmd = &cobra.Command{
 finish the apply.`,
 	Example: `  # Resume reconciliation for an existing Receiver
   flux resume receiver main`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)),
 	RunE: resumeCommand{
 		apiType: receiverType,
 		object:  receiverAdapter{&notificationv1.Receiver{}},
diff --git a/cmd/flux/resume_source_bucket.go b/cmd/flux/resume_source_bucket.go
index e40cef344a7628c6f12fc6f6d92045f6e43f6653..c16d20902a934d5dcdba6698d6d7fc7788a26056 100644
--- a/cmd/flux/resume_source_bucket.go
+++ b/cmd/flux/resume_source_bucket.go
@@ -28,6 +28,7 @@ var resumeSourceBucketCmd = &cobra.Command{
 	Long:  `The resume command marks a previously suspended Bucket resource for reconciliation and waits for it to finish.`,
 	Example: `  # Resume reconciliation for an existing Bucket
   flux resume source bucket podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)),
 	RunE: resumeCommand{
 		apiType: bucketType,
 		object:  &bucketAdapter{&sourcev1.Bucket{}},
diff --git a/cmd/flux/resume_source_chart.go b/cmd/flux/resume_source_chart.go
index d3525eb3c8045629dcd1b72ddc381d092b8fff5a..6da61eed8d72f52344211e3974e19db6a8012ea0 100644
--- a/cmd/flux/resume_source_chart.go
+++ b/cmd/flux/resume_source_chart.go
@@ -30,6 +30,7 @@ var resumeSourceHelmChartCmd = &cobra.Command{
 	Long:  `The resume command marks a previously suspended HelmChart resource for reconciliation and waits for it to finish.`,
 	Example: `  # Resume reconciliation for an existing HelmChart
   flux resume source chart podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmChartKind)),
 	RunE: resumeCommand{
 		apiType: helmChartType,
 		object:  &helmChartAdapter{&sourcev1.HelmChart{}},
diff --git a/cmd/flux/resume_source_git.go b/cmd/flux/resume_source_git.go
index f4aa22edad77d0f4829f85461730318814352279..3178428121612dcdb8d567db8991e73bce1b8202 100644
--- a/cmd/flux/resume_source_git.go
+++ b/cmd/flux/resume_source_git.go
@@ -28,6 +28,7 @@ var resumeSourceGitCmd = &cobra.Command{
 	Long:  `The resume command marks a previously suspended GitRepository resource for reconciliation and waits for it to finish.`,
 	Example: `  # Resume reconciliation for an existing GitRepository
   flux resume source git podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)),
 	RunE: resumeCommand{
 		apiType: gitRepositoryType,
 		object:  gitRepositoryAdapter{&sourcev1.GitRepository{}},
diff --git a/cmd/flux/resume_source_helm.go b/cmd/flux/resume_source_helm.go
index a22d73270af21d09eebe40f00a2a306d8f6a85de..674a81b1b27ff9b3254570e4ec5bfccd46c0da47 100644
--- a/cmd/flux/resume_source_helm.go
+++ b/cmd/flux/resume_source_helm.go
@@ -28,6 +28,7 @@ var resumeSourceHelmCmd = &cobra.Command{
 	Long:  `The resume command marks a previously suspended HelmRepository resource for reconciliation and waits for it to finish.`,
 	Example: `  # Resume reconciliation for an existing HelmRepository
   flux resume source helm bitnami`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)),
 	RunE: resumeCommand{
 		apiType: helmRepositoryType,
 		object:  helmRepositoryAdapter{&sourcev1.HelmRepository{}},
diff --git a/cmd/flux/suspend_alert.go b/cmd/flux/suspend_alert.go
index eb3c184f8b4d61d76f7de71228ded7885bd1aa0d..42ee60df8de3377854dda1e2cda1cf04e3a6b5e8 100644
--- a/cmd/flux/suspend_alert.go
+++ b/cmd/flux/suspend_alert.go
@@ -28,6 +28,7 @@ var suspendAlertCmd = &cobra.Command{
 	Long:  "The suspend command disables the reconciliation of a Alert resource.",
 	Example: `  # Suspend reconciliation for an existing Alert
   flux suspend alert main`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.AlertKind)),
 	RunE: suspendCommand{
 		apiType: alertType,
 		object:  &alertAdapter{&notificationv1.Alert{}},
diff --git a/cmd/flux/suspend_helmrelease.go b/cmd/flux/suspend_helmrelease.go
index d222916a02d8b39b9a3fb4651ea57457b072b5ba..5e552278769fe028580abb68f95124c26c41e214 100644
--- a/cmd/flux/suspend_helmrelease.go
+++ b/cmd/flux/suspend_helmrelease.go
@@ -29,6 +29,7 @@ var suspendHrCmd = &cobra.Command{
 	Long:    "The suspend command disables the reconciliation of a HelmRelease resource.",
 	Example: `  # Suspend reconciliation for an existing Helm release
   flux suspend hr podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)),
 	RunE: suspendCommand{
 		apiType: helmReleaseType,
 		object:  &helmReleaseAdapter{&helmv2.HelmRelease{}},
diff --git a/cmd/flux/suspend_image_repository.go b/cmd/flux/suspend_image_repository.go
index 5651b79936fec8ec74df7e014dd13e583b4674dc..826c4de4fd3327be9db4c43a5e9da827881c340b 100644
--- a/cmd/flux/suspend_image_repository.go
+++ b/cmd/flux/suspend_image_repository.go
@@ -28,6 +28,7 @@ var suspendImageRepositoryCmd = &cobra.Command{
 	Long:  "The suspend image repository command disables the reconciliation of a ImageRepository resource.",
 	Example: `  # Suspend reconciliation for an existing ImageRepository
   flux suspend image repository alpine`,
+	ValidArgsFunction: resourceNamesCompletionFunc(imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)),
 	RunE: suspendCommand{
 		apiType: imageRepositoryType,
 		object:  imageRepositoryAdapter{&imagev1.ImageRepository{}},
diff --git a/cmd/flux/suspend_image_updateauto.go b/cmd/flux/suspend_image_updateauto.go
index cc6c2ecfcaf89b7c36932e96b942e9f305acbb8f..cd6e8f3a6e7b71882f53c5fc65f40752e851c682 100644
--- a/cmd/flux/suspend_image_updateauto.go
+++ b/cmd/flux/suspend_image_updateauto.go
@@ -28,6 +28,7 @@ var suspendImageUpdateCmd = &cobra.Command{
 	Long:  "The suspend image update command disables the reconciliation of a ImageUpdateAutomation resource.",
 	Example: `  # Suspend reconciliation for an existing ImageUpdateAutomation
   flux suspend image update latest-images`,
+	ValidArgsFunction: resourceNamesCompletionFunc(autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)),
 	RunE: suspendCommand{
 		apiType: imageUpdateAutomationType,
 		object:  imageUpdateAutomationAdapter{&autov1.ImageUpdateAutomation{}},
diff --git a/cmd/flux/suspend_kustomization.go b/cmd/flux/suspend_kustomization.go
index 1d1f208b1cb4ee9b2fe69d1f531fd4b0f5ec41af..18d007644dc0c44c17adaacfaa822c00649a2e55 100644
--- a/cmd/flux/suspend_kustomization.go
+++ b/cmd/flux/suspend_kustomization.go
@@ -29,6 +29,7 @@ var suspendKsCmd = &cobra.Command{
 	Long:    "The suspend command disables the reconciliation of a Kustomization resource.",
 	Example: `  # Suspend reconciliation for an existing Kustomization
   flux suspend ks podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
 	RunE: suspendCommand{
 		apiType: kustomizationType,
 		object:  kustomizationAdapter{&kustomizev1.Kustomization{}},
diff --git a/cmd/flux/suspend_receiver.go b/cmd/flux/suspend_receiver.go
index 90ca5cf0961d63fea997a4c28176fcbacf371f05..2edf1572e841db95bf195bb17c528b7f944ed730 100644
--- a/cmd/flux/suspend_receiver.go
+++ b/cmd/flux/suspend_receiver.go
@@ -28,6 +28,7 @@ var suspendReceiverCmd = &cobra.Command{
 	Long:  "The suspend command disables the reconciliation of a Receiver resource.",
 	Example: `  # Suspend reconciliation for an existing Receiver
   flux suspend receiver main`,
+	ValidArgsFunction: resourceNamesCompletionFunc(notificationv1.GroupVersion.WithKind(notificationv1.ReceiverKind)),
 	RunE: suspendCommand{
 		apiType: receiverType,
 		object:  &receiverAdapter{&notificationv1.Receiver{}},
diff --git a/cmd/flux/suspend_source_bucket.go b/cmd/flux/suspend_source_bucket.go
index 72f1d0e3f4f63315db0a59fd8b54e4bbbd7aa8b2..e452b9dce32fa46725740eb5159dcd0b48fbac94 100644
--- a/cmd/flux/suspend_source_bucket.go
+++ b/cmd/flux/suspend_source_bucket.go
@@ -28,6 +28,7 @@ var suspendSourceBucketCmd = &cobra.Command{
 	Long:  "The suspend command disables the reconciliation of a Bucket resource.",
 	Example: `  # Suspend reconciliation for an existing Bucket
   flux suspend source bucket podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)),
 	RunE: suspendCommand{
 		apiType: bucketType,
 		object:  bucketAdapter{&sourcev1.Bucket{}},
diff --git a/cmd/flux/suspend_source_chart.go b/cmd/flux/suspend_source_chart.go
index 703e820e367cc9f417538e34968fc9b6eb62ed1d..750e65ff6b32876664288c86f8c9d4e26edb0ff9 100644
--- a/cmd/flux/suspend_source_chart.go
+++ b/cmd/flux/suspend_source_chart.go
@@ -28,6 +28,7 @@ var suspendSourceHelmChartCmd = &cobra.Command{
 	Long:  "The suspend command disables the reconciliation of a HelmChart resource.",
 	Example: `  # Suspend reconciliation for an existing HelmChart
   flux suspend source chart podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmChartKind)),
 	RunE: suspendCommand{
 		apiType: helmChartType,
 		object:  helmChartAdapter{&sourcev1.HelmChart{}},
diff --git a/cmd/flux/suspend_source_git.go b/cmd/flux/suspend_source_git.go
index bc058303ea40ea91d8dbe8615ad3ca02335a7fc9..16ebd0a637b8558c1fbb2507f80a2fbaff906b21 100644
--- a/cmd/flux/suspend_source_git.go
+++ b/cmd/flux/suspend_source_git.go
@@ -28,6 +28,7 @@ var suspendSourceGitCmd = &cobra.Command{
 	Long:  "The suspend command disables the reconciliation of a GitRepository resource.",
 	Example: `  # Suspend reconciliation for an existing GitRepository
   flux suspend source git podinfo`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)),
 	RunE: suspendCommand{
 		apiType: gitRepositoryType,
 		object:  gitRepositoryAdapter{&sourcev1.GitRepository{}},
diff --git a/cmd/flux/suspend_source_helm.go b/cmd/flux/suspend_source_helm.go
index a4a5787c9678d40c888ea453357526b77a6cac59..0b29a2dc60925cbeb940b10a65c966c5438f821a 100644
--- a/cmd/flux/suspend_source_helm.go
+++ b/cmd/flux/suspend_source_helm.go
@@ -28,6 +28,7 @@ var suspendSourceHelmCmd = &cobra.Command{
 	Long:  "The suspend command disables the reconciliation of a HelmRepository resource.",
 	Example: `  # Suspend reconciliation for an existing HelmRepository
   flux suspend source helm bitnami`,
+	ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)),
 	RunE: suspendCommand{
 		apiType: helmRepositoryType,
 		object:  helmRepositoryAdapter{&sourcev1.HelmRepository{}},
diff --git a/internal/utils/utils.go b/internal/utils/utils.go
index d06629e24c857d9a3bb9c3d0b82cdbd35af557da..1181cc0b582cf60aa522848a4864565366029a3b 100644
--- a/internal/utils/utils.go
+++ b/internal/utils/utils.go
@@ -107,7 +107,7 @@ func ExecKubectlCommand(ctx context.Context, mode ExecMode, kubeConfigPath strin
 	return "", nil
 }
 
-func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error) {
+func ClientConfig(kubeConfigPath string, kubeContext string) clientcmd.ClientConfig {
 	configFiles := SplitKubeConfigPath(kubeConfigPath)
 	configOverrides := clientcmd.ConfigOverrides{}
 
@@ -115,11 +115,14 @@ func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error)
 		configOverrides.CurrentContext = kubeContext
 	}
 
-	cfg, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
+	return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
 		&clientcmd.ClientConfigLoadingRules{Precedence: configFiles},
 		&configOverrides,
-	).ClientConfig()
+	)
+}
 
+func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error) {
+	cfg, err := ClientConfig(kubeConfigPath, kubeContext).ClientConfig()
 	if err != nil {
 		return nil, fmt.Errorf("kubernetes configuration load failed: %w", err)
 	}