cmdutil

package
v1.0.29 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package cmdutil provides reusable CLI helper functions for Cobra commands. Both the open-source CLI and private overlays import this package to avoid duplicating flag validation, time parsing, and UX helpers.

Index

Constants

View Source
const OverridePriorityAnnotation = "dws.override-priority"

OverridePriorityAnnotation is the cobra.Command.Annotations key used to declare a command's merge-time override priority. Higher values win when same-named leaves collide during merge. Exported so overlays and helpers can reference the same key as the core merge logic without spelling drift.

View Source
const SourceAnnotation = "dws.source"

SourceAnnotation is the cobra.Command.Annotations key used to record where a top-level command came from. Edition overlays (e.g. wukong) read this annotation to distinguish envelope-authored dynamic commands from helper-fallback commands that merely happen to share a name. Keeping the key and value literals in one place prevents spelling drift between the core (which sets the annotation) and overlays (which read it).

View Source
const SourceEnvelope = "envelope"

SourceEnvelope marks a command as authored by the discovery envelope and therefore authoritative at runtime. Only commands built from a market.ServerDescriptor / CLIOverlay should carry this value. Helper fallbacks and other sources must leave the annotation unset.

Variables

View Source
var CommonFlagAliases = map[string]string{
	"json":            "format json",
	"output":          "format",
	"out":             "format",
	"o":               "format",
	"silent":          "quiet",
	"dry":             "dry-run",
	"force":           "yes",
	"f":               "yes",
	"timeout-seconds": "timeout",
	"device-flow":     "device",
	"deviceflow":      "device",
}

CommonFlagAliases maps commonly misused flag names to their correct equivalents.

View Source
var FlexTimeLayouts = []string{
	time.RFC3339,
	"2006-01-02T15:04:05Z",
	"2006-01-02T15:04:05-07:00",
	"2006-01-02T15:04:05",
	"2006-01-02 15:04:05",
	"2006-01-02T15:04",
	"2006-01-02 15:04",
	"2006-01-02",
	"2006/01/02 15:04:05",
	"2006/01/02",
	"20060102",
}

FlexTimeLayouts is the ordered list of time formats tried by ParseISOTimeToMillis.

Functions

func ConfirmDelete

func ConfirmDelete(cmd *cobra.Command, resourceType, resourceName string) bool

ConfirmDelete asks for interactive confirmation before destructive operations. Returns true if --yes/-y flag is set or the user types "yes"/"y".

func DetectNumericTypeError

func DetectNumericTypeError(err error) (flagName, badValue string, ok bool)

DetectNumericTypeError checks if err is a Cobra/pflag numeric type validation error. Returns the flag name and the bad value if detected.

func FlagOrFallback

func FlagOrFallback(cmd *cobra.Command, primary string, aliases ...string) string

FlagOrFallback reads the primary flag; if empty, falls back through alias flags in order, returning the first non-empty value.

func GroupRunE

func GroupRunE(cmd *cobra.Command, args []string) error

GroupRunE is a reusable RunE for parent (group) commands that have no business logic of their own. With args it returns an error listing available subcommands; without args it shows help.

func HintSubCmd

func HintSubCmd(use, hint string) *cobra.Command

HintSubCmd creates a hidden subcommand that only prints a disambiguation hint.

func IsEnvelopeSourced added in v1.0.16

func IsEnvelopeSourced(cmd *cobra.Command) bool

IsEnvelopeSourced reports whether cmd carries the envelope provenance annotation. Commands without the annotation are treated as non-authoritative (helper fallbacks, overlay-injected stubs, etc.).

func IsLeafCmd added in v1.0.16

func IsLeafCmd(cmd *cobra.Command) bool

IsLeafCmd reports whether a command has no subcommands. Leaves carry a RunE and are invocation targets; groups merely organise subcommands.

func LevenshteinDist

func LevenshteinDist(a, b string) int

LevenshteinDist returns the edit distance between two strings.

func LevenshteinThreshold

func LevenshteinThreshold(nameLen int) int

LevenshteinThreshold returns the max edit distance allowed based on string length.

func MarkEnvelopeSource added in v1.0.16

func MarkEnvelopeSource(cmd *cobra.Command)

MarkEnvelopeSource stamps the envelope provenance annotation on cmd. Safe to call on commands that may not have an Annotations map yet. Callers in core code are the only ones that should invoke this — overlays read the annotation but must not fabricate envelope provenance.

func MergeHardcodedLeaves added in v1.0.16

func MergeHardcodedLeaves(dynamicRoot, hardcodedRoot *cobra.Command) *cobra.Command

MergeHardcodedLeaves grafts leaves from hardcodedRoot onto dynamicRoot when the same-named path does not already exist. Groups recurse. On leaf conflicts the dynamic side wins by default, because the discovery envelope is the runtime authority — hardcoded commands are retained only as a leaf-level fallback for behaviour the envelope explicitly does not declare. See _docs/discovery-overlay-authority.md.

Explicit opt-in override: a hardcoded leaf may promote itself over a same-named dynamic leaf by carrying a strictly higher OverridePriority (see SetOverridePriority / OverridePriority). This exists for the narrow case where the envelope exposes one dispatch path but the hardcoded leaf needs richer flag-based routing (e.g. `chat message send` fanning out to multiple MCP tools depending on --group vs --user), which the envelope cannot currently express. Helpers without the annotation still lose to the envelope, so the default authority contract is preserved.

PRECONDITION: dynamicRoot must be envelope-sourced (carry the SourceAnnotation=SourceEnvelope marker set by BuildDynamicCommands via MarkEnvelopeSource). Callers that might otherwise pass a helper-fallback root with the same name are responsible for evicting it upstream — otherwise the "envelope is authority" rule silently promotes helper leaves over same-named hardcoded leaves and the overlay loses its ability to override routing. The wukong overlay's RegisterProducts gates this call on IsEnvelopeSourced(dynamicRoot); new callers must do the same.

Conflict resolution table:

dynamic  hardcoded                          →  action
-------  ---------------------------------  -----------------------------
absent   anything                              graft hardcoded subtree
leaf     leaf (hc priority ≤ dyn)              dynamic wins (no-op)
leaf     leaf (hc priority > dyn)              hardcoded replaces dynamic
group    group                                 recurse
leaf     group (hc priority > dyn)             hardcoded group replaces dyn leaf
leaf     group (hc priority ≤ dyn)             dynamic wins, warn
group    leaf                                  dynamic wins, warn

The "leaf vs group" priority promotion path (added for issue #164) covers the case where the envelope exposes a single tool at a CLI path but the hardcoded helper restructures that path into a group of richer subcommands (e.g. `chat group members` published as a leaf for `get_group_members`, but the helper provides `list / add / remove / add-bot` siblings). Without this path the helper subtree is silently dropped on every release, which is exactly the regression the OverridePriority annotation exists to prevent for leaf-vs-leaf — extending it to leaf-vs-group keeps the contract honest.

MergeHardcodedLeaves mutates dynamicRoot in place and returns it so callers can chain. hardcodedRoot is treated as a donor: grafted children are detached from it so their cobra parent pointer points at the new parent.

func MustFlagOrFallback

func MustFlagOrFallback(cmd *cobra.Command, primary string, aliases ...string) (string, error)

MustFlagOrFallback works like FlagOrFallback but returns an error when all flags are empty.

func MustFlagWithHint

func MustFlagWithHint(cmd *cobra.Command, name, example string) (string, error)

MustFlagWithHint returns an error with an explicit usage example when the flag is empty.

func MustGetFlag

func MustGetFlag(cmd *cobra.Command, name string) string

MustGetFlag retrieves a string flag value, checking both local and inherited flags.

func OverridePriority added in v1.0.16

func OverridePriority(cmd *cobra.Command) int

OverridePriority returns the override priority annotation value on cmd, or 0 if the annotation is absent or malformed.

func ParseISOTimeToMillis

func ParseISOTimeToMillis(flagName, value string) (int64, error)

ParseISOTimeToMillis parses a time string into a millisecond Unix timestamp. Supports RFC3339, UTC Z, timezone-less, space-separated, date-only, and more. When the input lacks an explicit timezone, Asia/Shanghai is assumed.

func SetOverridePriority added in v1.0.16

func SetOverridePriority(cmd *cobra.Command, priority int)

SetOverridePriority stamps the override priority annotation on cmd. A positive value asks the merge layer to promote this command over a same-named leaf with a lower (or unset) priority.

func SuffixLooksLikeValue added in v1.0.27

func SuffixLooksLikeValue(suffix, typ, format string, enum []string) bool

SuffixLooksLikeValue decides whether a candidate suffix from a glued "--flagsuffix" token plausibly represents a value for a flag's declared type/format/enum. Shared by StickyHandler (PreParse) and SuggestFlagFix (unknown-flag recovery).

typ is a pflag value type string (e.g. "int", "bool", "string"); format is JSON Schema "format" when present (e.g. "date-time"); enum is the schema enum list when present.

func ValidateRequiredFlagWithAliases

func ValidateRequiredFlagWithAliases(cmd *cobra.Command, primary string, aliases ...string) error

ValidateRequiredFlagWithAliases checks that at least one of the primary flag or its aliases is non-empty.

func ValidateRequiredFlags

func ValidateRequiredFlags(cmd *cobra.Command, names ...string) error

ValidateRequiredFlags checks that all named string flags are non-empty. Returns a formatted error listing all missing flags, or nil.

func ValidateTimeRange

func ValidateTimeRange(startMs, endMs int64) error

ValidateTimeRange checks that endMs is strictly after startMs.

func VisibleFlagNames added in v1.0.27

func VisibleFlagNames(cmd *cobra.Command) []string

VisibleFlagNames returns sorted candidate flag names for cmd.Flags() using flagFixCandidate. Intended for agent-facing error recovery (available_flags).

Types

type FlagFixResult

type FlagFixResult struct {
	Suggestion   string
	AutoFixFlag  string
	AutoFixValue string
}

FlagFixResult holds the result of SuggestFlagFix analysis.

func SuggestFlagFix

func SuggestFlagFix(cmd *cobra.Command, flagErr error) FlagFixResult

SuggestFlagFix detects flag-value concatenation errors, common flag aliases, and Levenshtein-close typos.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL