pipeline

package
v1.0.63 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FuzzyMatchFlag added in v1.0.56

func FuzzyMatchFlag(argument string, known map[string]bool, candidates []string) (string, bool)

FuzzyMatchFlag returns the unique closest real long flag within the conservative edit-distance threshold used by ParamNameHandler.

func NormalizeFlagToken added in v1.0.56

func NormalizeFlagToken(argument string, known map[string]bool) (string, bool)

NormalizeFlagToken folds a long flag's morphological spelling and returns a canonical token only when the folded name is a real flag. Both the normal PreParse handler chain and Cobra command traversal use this primitive so a spelling accepted after a command is also recognised before it.

func RunPreParse

func RunPreParse(root *cobra.Command, engine *Engine) error

RunPreParse resolves the target command from the raw args, extracts flag names from the Cobra command tree, and runs all PreParse handlers. The corrected args are set back on the root command via SetArgs so that Cobra's subsequent ExecuteC uses the corrected values.

Explicit +shortcut tokens and groups whose typed GroupPolicy enables recovery are validated before flag parsing so an unknown command cannot be misreported as an unknown flag on its nearest parent. Other unresolved paths remain Cobra's responsibility.

Types

type BoolValueConflictError added in v1.0.56

type BoolValueConflictError struct {
	Command string
	Flag    string
	Values  []string
}

BoolValueConflictError is returned when one canonical boolean flag receives both true and false in the same argv. Rejecting contradictory values keeps the outcome independent of argument order while allowing repeated identical spellings to retain Cobra's native behaviour.

func (*BoolValueConflictError) Error added in v1.0.56

func (e *BoolValueConflictError) Error() string

type CommandPathFallback added in v1.0.58

type CommandPathFallback struct {
	From       string
	Mode       string
	To         string
	Candidates []string
}

CommandPathFallback is the pipeline-local projection of one generated recovery record. The app injects the cli lookup so pipeline stays independent from the authored/generator package and can be tested with small fixtures.

type CommandPathFallbackLookup added in v1.0.58

type CommandPathFallbackLookup func(path string) (CommandPathFallback, bool)

CommandPathFallbackLookup resolves an exact normalized path.

type Context

type Context struct {
	// Args is the raw argv slice (available from PreParse onward).
	// PreParse handlers may rewrite this in place.
	Args []string

	// Command identifies the resolved command. RunPreParse fills it with
	// Cobra's raw CommandPath() (e.g. "dws chat message send-by-bot") so
	// PreParse handlers can key per-command tables; the PostParse pipeline
	// fills it with the resolved product.tool canonical path. The two phases
	// use independent Context instances, so the differing forms never mix.
	Command string

	// Params holds structured key→value parameters after Cobra
	// parsing (available from PostParse onward). Handlers may
	// mutate values or add/remove keys.
	Params map[string]any

	// Schema is the JSON Schema for the resolved tool's input
	// (available from PostParse onward). Handlers must treat this
	// as read-only.
	Schema map[string]any

	// Payload is the merged, validated payload ready to be sent
	// over the wire (available from PreRequest onward).
	Payload map[string]any

	// Response is the JSON-RPC result returned by the server
	// (available from PostResponse onward). Handlers may mutate
	// the response before it is written to stdout.
	Response map[string]any

	// FlagSpecs provides the list of known flag names for the
	// current tool, derived from the input schema. PreParse
	// handlers use this to match against raw argv tokens.
	FlagSpecs []FlagInfo

	// ProtectedFlags carries reviewed semantic guard decisions across the
	// complete PreParse chain. Keys are morphed flag names. Sticky and fuzzy
	// handlers must not reinterpret a name classified as blocked or ambiguous
	// by the semantic alias table.
	ProtectedFlags map[string]FlagProtection

	// Corrections records every correction applied by handlers,
	// enabling downstream logging and debugging.
	Corrections []Correction
}

Context carries mutable state through the handler chain. Each phase populates additional fields; earlier-phase fields remain available in later phases so that handlers can correlate raw input with structured parameters.

func RunPreParseArgs added in v1.0.56

func RunPreParseArgs(root *cobra.Command, engine *Engine, rawArgs []string) (*Context, error)

RunPreParseArgs is the testable form of RunPreParse. Production passes os.Args[1:]; end-to-end tests can pass an isolated argv while exercising the exact same command traversal, FlagInfo extraction, handler chain, and root.SetArgs delivery path.

func (*Context) AddCorrection

func (c *Context) AddCorrection(handler string, phase Phase, field, original, corrected, kind string)

AddCorrection appends a correction record to the context.

func (*Context) IsFlagProtected added in v1.0.56

func (c *Context) IsFlagProtected(morphed string) bool

IsFlagProtected reports whether a morphed flag name is guarded from further automatic interpretation.

func (*Context) ProtectFlag added in v1.0.56

func (c *Context) ProtectFlag(morphed string, protection FlagProtection)

ProtectFlag records a reviewed no-touch decision for the remainder of the current pipeline context.

type Correction

type Correction struct {
	// Handler is the name of the handler that applied the correction.
	Handler string

	// Phase is the pipeline phase in which the correction occurred.
	Phase Phase

	// Field identifies the affected flag or parameter name.
	Field string

	// Original is the value before correction.
	Original string

	// Corrected is the value after correction.
	Corrected string

	// Kind classifies the correction (e.g. "alias", "sticky", "case").
	Kind string
}

Correction records a single input correction applied by a handler.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine manages handler registration and executes the pipeline chain. Handlers are grouped by phase and executed in registration order within each phase. The engine is safe to use concurrently for reads after all handlers have been registered; registration itself is not concurrent-safe and should be done at startup.

func NewEngine

func NewEngine() *Engine

NewEngine creates a pipeline engine with no registered handlers.

func (*Engine) HandlerCount

func (e *Engine) HandlerCount() int

HandlerCount returns the total number of registered handlers across all phases.

func (*Engine) Handlers

func (e *Engine) Handlers(phase Phase) []Handler

Handlers returns the registered handlers for a given phase, in registration order. The returned slice must not be modified.

func (*Engine) HasHandlers

func (e *Engine) HasHandlers(phase Phase) bool

HasHandlers reports whether at least one handler is registered for the given phase.

func (*Engine) Register

func (e *Engine) Register(h Handler)

Register adds a handler to its declared phase. Handlers within the same phase execute in registration order.

func (*Engine) RegisterAll

func (e *Engine) RegisterAll(handlers ...Handler)

RegisterAll registers multiple handlers at once.

func (*Engine) Run

func (e *Engine) Run(ctx *Context) error

Run executes all phases in order: Register → PreParse → PostParse → PreRequest → PostResponse. Each phase runs its handler chain completely before the next phase begins.

Callers typically do not use Run directly — the CLI integration calls RunPhase at each stage of the execution flow. Run is provided for testing and for cases where the full pipeline must be exercised in one shot.

func (*Engine) RunPhase

func (e *Engine) RunPhase(phase Phase, ctx *Context) error

RunPhase executes all handlers registered for the given phase in chain order. If any handler returns an error, execution stops immediately and the error is returned with the handler name as context.

func (*Engine) SetCommandPathFallbackLookup added in v1.0.58

func (e *Engine) SetCommandPathFallbackLookup(lookup CommandPathFallbackLookup)

SetCommandPathFallbackLookup installs the build-time generated command-path recovery lookup. It must be configured before the engine is used.

type FlagConflictError added in v1.0.56

type FlagConflictError struct {
	Command   string
	Canonical string
	Spellings []string
}

FlagConflictError is returned when multiple distinct spellings that reduce to one scalar canonical flag are present in the same argv. Rejecting the command makes the outcome independent of argument order.

func (*FlagConflictError) Error added in v1.0.56

func (e *FlagConflictError) Error() string

type FlagInfo

type FlagInfo struct {
	// Name is the canonical kebab-case flag name (e.g. "user-id").
	Name string

	// Shorthand is the optional single-character pflag shorthand (e.g. "y"
	// for --yes). PreParse uses exact shorthand tokens when normalising
	// explicit boolean values; shorthand clusters retain native pflag syntax.
	Shorthand string

	// PropertyName is the original schema property key (e.g. "userId").
	PropertyName string

	// Type is the JSON Schema / pflag type ("string", "integer",
	// "bool", "stringSlice", "duration", etc.).
	Type string

	// Format carries the JSON Schema "format" hint when present —
	// e.g. "date", "date-time", "duration", "email", "uri", "ipv4".
	// PreParse handlers use this to decide whether a suffix in a
	// glued token (e.g. "--starttime1") looks like a plausible value.
	Format string

	// Enum carries the JSON Schema "enum" string values when present.
	// PreParse handlers use this for sticky-split validation: a glued
	// suffix is accepted only if it matches one of the enum entries.
	Enum []string
}

FlagInfo describes a single CLI flag derived from a tool's input schema. PreParse handlers use this to recognise valid flag names when performing fuzzy matching or alias resolution.

func FlagInfoFromCommand

func FlagInfoFromCommand(cmd *cobra.Command) []FlagInfo

FlagInfoFromCommand extracts FlagInfo entries from a Cobra command's registered flags (both local and inherited).

JSON Schema "format" and "enum" hints injected via pflag annotations (x-cli-format / x-cli-enum, see internal/compat/dynamic_commands.go) are surfaced on FlagInfo so PreParse handlers can validate sticky-split candidates against the actual schema, not just the pflag type.

type FlagProtection added in v1.0.56

type FlagProtection string

FlagProtection identifies why an emitted flag name must not be automatically rewritten.

const (
	FlagProtectionBlocked   FlagProtection = "blocked"
	FlagProtectionAmbiguous FlagProtection = "ambiguous"
)

type FlagProtectionResolver added in v1.0.60

type FlagProtectionResolver interface {
	ResolveFlagProtection(rawCommandPath, morphedFlag string) (FlagProtection, bool)
}

FlagProtectionResolver exposes reviewed blocked/ambiguous flag names to command traversal. A PreParse handler that owns those decisions implements this optional interface so traversal and the handler chain use one semantic source instead of independently guessing whether an unknown flag may carry a value.

type Handler

type Handler interface {
	// Name returns a short, unique identifier for the handler
	// (e.g. "sticky", "alias", "date-normalise"). Used in
	// correction records and log output.
	Name() string

	// Phase returns the pipeline phase this handler belongs to.
	Phase() Phase

	// Handle processes the context and returns an error to abort
	// the chain, or nil to continue.
	Handle(ctx *Context) error
}

Handler is the core abstraction for pipeline extensions. Each handler declares the phase it belongs to and provides a Handle method that receives a mutable context. Handlers are executed in registration order within a phase; each handler's output becomes the next handler's input.

A handler that returns a non-nil error aborts the chain — no further handlers in the same phase (or subsequent phases) will run.

type HandlerError added in v1.0.56

type HandlerError struct {
	Phase   Phase
	Handler string
	Cause   error
}

HandlerError preserves the pipeline location of a handler failure for logs and diagnostics while keeping the underlying domain error available to user-facing adapters through Unwrap.

func (*HandlerError) Error added in v1.0.56

func (e *HandlerError) Error() string

func (*HandlerError) Unwrap added in v1.0.56

func (e *HandlerError) Unwrap() error

type Phase

type Phase int

Phase represents a named stage in the CLI execution pipeline. Handlers are grouped by phase and executed in chain order within each phase. Phases themselves execute in a fixed order defined by the engine.

const (
	// Register runs at CLI startup when the Cobra command tree is
	// being built. Handlers can add, remove, or modify commands.
	Register Phase = iota

	// PreParse runs before Cobra parses the raw argv. Handlers
	// receive the raw argument slice and can rewrite it — for
	// example to fix flag-name typos or split glued values.
	PreParse

	// PostParse runs after Cobra has successfully parsed flags and
	// args. Handlers receive structured parameters plus the tool
	// schema, enabling value-level corrections such as date format
	// normalisation.
	PostParse

	// PreRequest runs after validation, just before the JSON-RPC
	// call is dispatched. Handlers can inspect or mutate the final
	// payload.
	PreRequest

	// PostResponse runs after the transport returns a result and
	// before the output is written to stdout.
	PostResponse
)

func (Phase) String

func (p Phase) String() string

String returns the human-readable name of the phase.

type StickyFlagPair added in v1.0.56

type StickyFlagPair struct {
	Flag   string
	Value  string
	Inline bool
}

StickyFlagPair is the canonical flag and value resolved from one glued long-flag token. Inline is required for boolean flags because pflag treats a bare boolean as true without consuming the following argv token.

func SplitStickyFlag added in v1.0.56

func SplitStickyFlag(argument string, specByName map[string]FlagInfo) (StickyFlagPair, bool)

SplitStickyFlag splits a safely recognisable glued flag/value token. The suffix must satisfy the real flag's type/format/enum contract, preventing a typo from being reinterpreted as data.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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