Repository: GoogleCloudPlatform/kubectl-ai
File: pkg/tools/kubectl_filter.go (Go)

Code before:

	if len(args) == 0 {
		klog.Warning("analyzeCall: no arguments extracted from call")
		return "unknown"
	}

	// Check if first argument is kubectl
	firstArg := args[0]

	// Reject quoted arguments (e.g., '"/path/kubectl"')
	if (strings.HasPrefix(firstArg, "'") && strings.HasSuffix(firstArg, "'")) || (strings.HasPrefix(firstArg, "\"") && strings.HasSuffix(firstArg, "\"")) {
		klog.V(2).Infof("analyzeCall: first arg is quoted: %q", firstArg)
		return "unknown"
	}

	// Check if this is kubectl
	if !strings.Contains(firstArg, "kubectl") {
		klog.V(2).Infof("analyzeCall: first arg does not contain kubectl: %q", firstArg)
		return "unknown"
	}

	klog.V(2).Infof("analyzeCall: found kubectl: %q", firstArg)

	// Check for flags before the verb (first non-flag argument)
	verbPos := -1
	for i, arg := range args[1:] {
		if !strings.HasPrefix(arg, "-") {
			verbPos = i + 1 // +1 because we skipped args[0]
			break
		}
	}
	if verbPos > 1 {
		klog.Warningf("analyzeCall: flags found before verb in args: %v", args)
		return "unknown"
	}

	// Parse kubectl arguments to extract verb, subverb, and flags
	verb, subVerb, hasDryRun := parseKubectlArgs(args[1:])
	if verb == "" {
		klog.Warningf("analyzeCall: no verb found after kubectl in args: %v", args)
		return "unknown"
	}

	// Check standard operations - write operations first (prioritize immediate detection)
	if (writeOps[verb] || writeSubOps[verb][subVerb]) && !hasDryRun {
		klog.V(1).Infof("analyzeCall: write op for verb=%q subVerb=%q", verb, subVerb)
		return "yes"
	}

	// Check read-only operations or dry-run write operations
	if (readOnlyOps[verb] || readOnlySubOps[verb][subVerb]) || ((writeOps[verb] || writeSubOps[verb][subVerb]) && hasDryRun) {

Review comment (suggestion):
It is safe to assume the verbs and subVerbs to not contain `=`

basically, if an arg starts with `-` and also contains `=`, we can skip.

Code after:

	if len(args) == 0 {
		klog.Warning("analyzeCall: no arguments extracted from call")
		return "unknown"
	}

	// Check if first argument is kubectl
	firstArg := args[0]

	// Reject quoted arguments (e.g., '"/path/kubectl"')
	if (strings.HasPrefix(firstArg, "'") && strings.HasSuffix(firstArg, "'")) || (strings.HasPrefix(firstArg, "\"") && strings.HasSuffix(firstArg, "\"")) {
		klog.V(2).Infof("analyzeCall: first arg is quoted: %q", firstArg)
		return "unknown"
	}

	// Check if this is kubectl
	if !strings.Contains(firstArg, "kubectl") {
		klog.V(2).Infof("analyzeCall: first arg does not contain kubectl: %q", firstArg)
		return "unknown"
	}

	klog.V(2).Infof("analyzeCall: found kubectl: %q", firstArg)

	// Check for boolean or spaced key-value flags before the verb
	for _, arg := range args[1:] {
		if !strings.HasPrefix(arg, "-") {
			break
		}
		// If flag does not contain '=', it's boolean or spaced key-value
		if !strings.Contains(arg, "=") {
			klog.Warningf("analyzeCall: boolean or spaced key-value flag before verb: %q", arg)
			return "unknown"
		}
	}

	// Parse kubectl arguments to extract verb, subverb, and flags
	verb, subVerb, hasDryRun := parseKubectlArgs(args[1:])
	if verb == "" {
		klog.Warningf("analyzeCall: no verb found after kubectl in args: %v", args)
		return "unknown"
	}

	// Check standard operations - write operations first (prioritize immediate detection)
	if (writeOps[verb] || writeSubOps[verb][subVerb]) && !hasDryRun {
		klog.V(1).Infof("analyzeCall: write op for verb=%q subVerb=%q", verb, subVerb)
		return "yes"
	}

	// Check read-only operations or dry-run write operations
	if (readOnlyOps[verb] || readOnlySubOps[verb][subVerb]) || ((writeOps[verb] || writeSubOps[verb][subVerb]) && hasDryRun) {
		klog.V(1).Infof("analyzeCall: read op for verb=%q subVerb=%q (dry-run=%v)", verb, subVerb, hasDryRun)