Documentation
¶
Index ¶
- Constants
- Variables
- func ApplyFlagAnnotation(fs *FlagSchema, ann FlagAnnotation)
- func CheckConventions(commandNames, flagNames []string, w io.Writer) int
- type AgentError
- type ArgumentMetadata
- type Capabilities
- type CommandSchema
- type Conventions
- type DescribeCommandSchema
- type DescribeOutput
- type Example
- type FlagAnnotation
- type FlagSchema
- type Logger
- type Metadata
- type OutputFormat
- type ProgressEvent
- type ReturnSchema
- type SubcommandSchema
- type Writer
- func (w *Writer) Flush()
- func (w *Writer) Format() OutputFormat
- func (w *Writer) IsTTY() bool
- func (w *Writer) Log(msg string)
- func (w *Writer) Progress(msg string)
- func (w *Writer) ProtocolVersion() string
- func (w *Writer) WriteError(err *AgentError)
- func (w *Writer) WriteEvent(v any)
- func (w *Writer) WriteProgress(evt ProgressEvent)
- func (w *Writer) WriteSuccess(humanText string, jsonPayload any)
- type WriterOption
Constants ¶
const ( ExitOK = 0 // Success ExitUserError = 1 // Bad input or arguments ExitToolError = 2 // Environment/internal failure ExitPartial = 3 // Some operations succeeded, some failed )
Exit codes 0–3: table-stakes (present since v0.1).
const ( ExitTimeout = 4 // Operation timed out; retry may succeed ExitNotFound = 5 // Requested resource does not exist ExitPermission = 6 // Caller lacks permission; not retryable without auth change ExitConflict = 7 // State conflict (e.g. resource already exists) ExitRateLimited = 8 // Rate limit hit; retry after RetryAfterMs ExitCancelled = 9 // Operation cancelled by signal or context )
Exit codes 4–9: extended taxonomy (v0.2).
const SchemaVersion = "0.2"
SchemaVersion is the murli envelope schema version. Frozen at "1.0" once v1.0 ships; incrementing requires a documented migration.
Variables ¶
var ExitFunc = os.Exit
ExitFunc is swapped out in tests to capture exit codes without terminating.
var ToolVersion = ""
ToolVersion is the version of the CLI tool using murli. Set this in your main() using a version variable injected at build time:
murli.ToolVersion = version // where `version` is set via -ldflags "-X main.version=1.2.3"
Or inject directly at build time:
-ldflags "-X github.com/allank/murli.ToolVersion=1.2.3"
var ValidOutputFormats = []string{"json", "ndjson", "yaml", "text"}
ValidOutputFormats lists the accepted --output values.
var ValidProtocolVersions = []string{"0.1", "0.2"}
ValidProtocolVersions lists the accepted --protocol-version values.
Functions ¶
func ApplyFlagAnnotation ¶ added in v0.3.0
func ApplyFlagAnnotation(fs *FlagSchema, ann FlagAnnotation)
ApplyFlagAnnotation merges a FlagAnnotation onto a FlagSchema in place. Boolean fields (Sensitive, Persistent) are one-way: they can be set to true but not cleared to false. This is intentional — ApplyFlagAnnotation is applied to a zero-value FlagSchema, so false is the default and only needs to be set once. Slice fields (MutuallyExclusiveWith, Enum) are deep-copied to prevent aliasing.
func CheckConventions ¶ added in v0.3.0
CheckConventions checks command names and flag names against the murli conventional vocabulary. Advisory warnings are written to w. Returns the number of warnings emitted. Never panics; suppressed output is safe (pass io.Discard).
Types ¶
type AgentError ¶
type AgentError struct {
Code int `json:"code"`
ErrorType string `json:"error"`
Message string `json:"message"`
Suggestion string `json:"suggestion,omitempty"`
Recoverable bool `json:"recoverable"`
ValidValues []string `json:"valid_values,omitempty"`
RetryAfterMs int `json:"retry_after_ms,omitempty"`
DocURL string `json:"doc_url,omitempty"`
Field string `json:"field,omitempty"`
SchemaVersion string `json:"schema_version,omitempty"`
ToolVersion string `json:"tool_version,omitempty"`
}
AgentError is the structured error envelope written to stderr. Fields are serialised as JSON in agent mode; SchemaVersion and ToolVersion are auto-populated by WriteError — do not set them manually.
func NewToolError ¶
func NewToolError(message string) *AgentError
NewToolError returns a non-recoverable AgentError for internal/environment failures. Use when the fault is in the environment (network, filesystem, dependency) not the caller.
func NewUserError ¶
func NewUserError(message, suggestion string) *AgentError
NewUserError returns a recoverable AgentError for bad input. Use when the caller supplied invalid arguments or configuration.
func (*AgentError) Error ¶
func (e *AgentError) Error() string
Error implements the standard Go error interface.
type ArgumentMetadata ¶
type ArgumentMetadata struct {
Name string `json:"name"`
Type string `json:"type"`
Required bool `json:"required"`
Description string `json:"description"`
}
ArgumentMetadata documents a single positional argument.
type Capabilities ¶ added in v0.3.0
type Capabilities struct {
Streaming bool `json:"streaming"`
DryRun bool `json:"dry_run"`
OutputFormats []string `json:"output_formats,omitempty"`
SchemaVersion string `json:"schema_version"`
ToolVersion string `json:"tool_version,omitempty"`
ProtocolVersion string `json:"protocol_version,omitempty"`
}
Capabilities describes what the binary supports, auto-populated by murli in describe output.
func DefaultCapabilities ¶ added in v0.3.0
func DefaultCapabilities() Capabilities
DefaultCapabilities returns the Capabilities block reflecting the current murli build.
type CommandSchema ¶
type CommandSchema struct {
Name string `json:"name"`
Summary string `json:"summary"`
WhenToUse string `json:"when_to_use,omitempty"`
AgentDescription string `json:"agent_description,omitempty"`
Idempotent bool `json:"idempotent"`
Mutating bool `json:"mutating,omitempty"`
Arguments []ArgumentMetadata `json:"arguments,omitempty"`
Flags []FlagSchema `json:"flags,omitempty"`
Returns *ReturnSchema `json:"returns,omitempty"`
Examples []Example `json:"examples,omitempty"`
Subcommands []SubcommandSchema `json:"subcommands,omitempty"`
}
CommandSchema is the JSON payload emitted by --schema.
type Conventions ¶ added in v0.3.0
Conventions carries the recommended CLI vocabulary; included in describe output.
func ConventionalVocabulary ¶ added in v0.3.0
func ConventionalVocabulary() *Conventions
ConventionalVocabulary returns the recommended verb and flag vocabulary as a Conventions value suitable for inclusion in describe output.
type DescribeCommandSchema ¶ added in v0.3.0
type DescribeCommandSchema struct {
Name string `json:"name"`
Summary string `json:"summary"`
WhenToUse string `json:"when_to_use,omitempty"`
AgentDescription string `json:"agent_description,omitempty"`
Idempotent bool `json:"idempotent"`
Mutating bool `json:"mutating,omitempty"`
Arguments []ArgumentMetadata `json:"arguments,omitempty"`
Flags []FlagSchema `json:"flags,omitempty"`
Returns *ReturnSchema `json:"returns,omitempty"`
Examples []Example `json:"examples,omitempty"`
Subcommands []DescribeCommandSchema `json:"subcommands,omitempty"`
}
DescribeCommandSchema is the full recursive schema used in describe output. Unlike CommandSchema (for --schema), Subcommands here carry full recursive data.
type DescribeOutput ¶ added in v0.3.0
type DescribeOutput struct {
Name string `json:"name"`
Summary string `json:"summary"`
SchemaVersion string `json:"schema_version"`
ToolVersion string `json:"tool_version,omitempty"`
Capabilities Capabilities `json:"capabilities"`
Conventions *Conventions `json:"conventions,omitempty"`
Commands []DescribeCommandSchema `json:"commands,omitempty"`
}
DescribeOutput is emitted by the auto-mounted `describe` subcommand. Commands lists the root-level commands of the tool. Each DescribeCommandSchema within Commands has its own Subcommands field for nested commands, creating a recursive tree. The top-level field is named "commands" (not "subcommands") to distinguish root commands from nested subcommands.
type Example ¶ added in v0.3.0
type Example struct {
Command string `json:"command"`
Description string `json:"description,omitempty"`
ExpectedExitCode int `json:"expected_exit_code,omitempty"` // 0 = success; omitted
}
Example is a concrete usage example for a command, used in Metadata.Examples.
type FlagAnnotation ¶ added in v0.3.0
type FlagAnnotation struct {
Env string `json:"env,omitempty"`
Sensitive bool `json:"sensitive,omitempty"`
Persistent bool `json:"persistent,omitempty"`
MutuallyExclusiveWith []string `json:"mutually_exclusive_with,omitempty"`
Enum []string `json:"enum,omitempty"`
Pattern string `json:"pattern,omitempty"`
}
FlagAnnotation provides extended metadata for a single flag, keyed by flag name in Metadata.FlagAnnotations. None of these fields can be auto-detected from the CLI framework; all must be supplied by the engineer via Annotate().
type FlagSchema ¶
type FlagSchema struct {
Name string `json:"name"`
Type string `json:"type"`
Default any `json:"default"`
Description string `json:"description"`
Env string `json:"env,omitempty"`
Sensitive bool `json:"sensitive,omitempty"`
Persistent bool `json:"persistent,omitempty"`
MutuallyExclusiveWith []string `json:"mutually_exclusive_with,omitempty"`
Enum []string `json:"enum,omitempty"`
Pattern string `json:"pattern,omitempty"`
}
FlagSchema represents a single CLI flag in the JSON schema. Basic fields (Name, Type, Default, Description) are auto-populated by the adapter. Extended fields (Env, Sensitive, Persistent, MutuallyExclusiveWith, Enum, Pattern) are populated from Metadata.FlagAnnotations[flagName] by the adapter schema emitters (see cobra/schema.go, cli/v2/schema.go, cli/v3/schema.go).
type Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
Logger writes diagnostic messages to stderr. TTY mode: human-readable plain text. Agent mode: one NDJSON object per line {ts, level, msg}; consecutive duplicates are collapsed into a single entry with a "repeated" count.
func (*Logger) Log ¶
Log writes a message. In TTY mode: plain text. In agent mode: NDJSON with deduplication. ANSI escape codes are stripped in agent mode.
func (*Logger) LogProgress ¶
LogProgress writes a progress message. TTY: overwrites current line with carriage return. Agent: NDJSON with level "progress" and deduplication. ANSI codes stripped.
type Metadata ¶
type Metadata struct {
// AgentDescription is a detailed description of the command's scope.
AgentDescription string `json:"agent_description"`
// WhenToUse specifies when an agent should select this command.
WhenToUse string `json:"when_to_use"`
// Idempotent specifies if the command is safe to re-run on failure.
Idempotent bool `json:"idempotent"`
// Mutating marks commands that write, delete, or otherwise change state.
// When true and the output is not a TTY, the adapter rejects the command with a
// confirmation_required error to prevent accidental mutation in non-interactive mode.
// A bypass flag (--force / --yes) will be added in a future release.
Mutating bool `json:"mutating,omitempty"`
// Arguments defines explicit positional argument documentation.
Arguments []ArgumentMetadata `json:"arguments,omitempty"`
// Returns defines the expected output format on success.
Returns *ReturnSchema `json:"returns,omitempty"`
// Examples contains concrete shell invocations for agent in-context learning.
// Changed from []string to []Example in v0.3.
Examples []Example `json:"examples,omitempty"`
// FlagAnnotations provides extended metadata keyed by flag name, for fields that
// cannot be auto-detected from the CLI framework (env var binding, enum values, etc.).
FlagAnnotations map[string]FlagAnnotation `json:"flag_annotations,omitempty"`
}
Metadata provides LLM-specific parameters to supplement standard CLI command definitions.
type OutputFormat ¶ added in v0.3.0
type OutputFormat string
OutputFormat controls the serialization format of WriteSuccess.
const ( // OutputFormatDefault is unset — format is determined by TTY detection. OutputFormatDefault OutputFormat = "" // OutputFormatJSON writes a pretty-printed JSON envelope to stdout. OutputFormatJSON OutputFormat = "json" // OutputFormatNDJSON writes a minified single-line JSON envelope to stdout. OutputFormatNDJSON OutputFormat = "ndjson" // OutputFormatYAML writes a YAML-encoded envelope to stdout. OutputFormatYAML OutputFormat = "yaml" // OutputFormatText writes human-readable plain text to stdout (same as TTY mode). OutputFormatText OutputFormat = "text" )
type ProgressEvent ¶
type ProgressEvent struct {
Stage string `json:"stage,omitempty"`
Current int `json:"current,omitempty"`
Total int `json:"total,omitempty"`
Percent float64 `json:"percent,omitempty"`
EtaMs int64 `json:"eta_ms,omitempty"`
Message string `json:"message,omitempty"`
}
ProgressEvent carries typed progress state for long-running operations. All fields are optional — populate what is meaningful for the operation.
type ReturnSchema ¶
type ReturnSchema struct {
Type string `json:"type"`
Description string `json:"description"`
Shape map[string]any `json:"shape,omitempty"`
// OutputSchema carries a raw JSON Schema (draft-2020-12) blob when the engineer
// provides it via Annotate(). murli serialises it as-is into --schema and describe output.
OutputSchema json.RawMessage `json:"output_schema,omitempty"`
}
ReturnSchema describes the shape of successful command output.
type SubcommandSchema ¶
SubcommandSchema represents a registered subcommand in --schema output (brief listing).
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer handles dynamic output routing based on terminal presence, agent flags, explicit output format, and negotiated protocol version.
func NewWriter ¶
func NewWriter(stdout, stderr io.Writer, agentMode bool, opts ...WriterOption) *Writer
NewWriter returns a configured output writer. Set agentMode true to force JSON output regardless of TTY state. Pass WriterOption values to set OutputFormat or ProtocolVersion.
func (*Writer) Format ¶ added in v0.3.0
func (w *Writer) Format() OutputFormat
Format returns the explicit output format (may be OutputFormatDefault).
func (*Writer) Log ¶
Log writes a message to stderr, deduplicating consecutive duplicates in agent mode.
func (*Writer) Progress ¶
Progress writes a progress update; overwrites current line in TTY, collapses in agent mode.
func (*Writer) ProtocolVersion ¶ added in v0.3.0
ProtocolVersion returns the negotiated protocol version (empty string = "0.2").
func (*Writer) WriteError ¶
func (w *Writer) WriteError(err *AgentError)
WriteError writes the structured error to stderr and exits with the error's exit code. In TTY mode: human-readable. In agent mode: JSON envelope with schema_version and tool_version.
func (*Writer) WriteEvent ¶
WriteEvent writes a single minified JSON object to stdout on one line. It is safe to call WriteEvent concurrently from multiple goroutines. However, WriteSuccess and WriteError are not mutex-protected — call them only after all WriteEvent goroutines have completed (e.g., after a sync.WaitGroup.Wait()). In TTY mode WriteEvent is a no-op (events are machine-only).
func (*Writer) WriteProgress ¶
func (w *Writer) WriteProgress(evt ProgressEvent)
WriteProgress emits a structured progress event to stderr. Agent mode: minified JSON on one line (consistent with WriteEvent). TTY mode: formatted human-readable line with carriage return to overwrite.
func (*Writer) WriteSuccess ¶
WriteSuccess writes to stdout. Format depends on outputFormat and isTTY:
- TTY or OutputFormatText: humanText plain line
- OutputFormatNDJSON: single minified JSON line
- OutputFormatYAML: YAML-encoded envelope
- OutputFormatJSON or default agent mode: pretty-printed JSON envelope
type WriterOption ¶ added in v0.3.0
type WriterOption func(*Writer)
WriterOption is a functional option for NewWriter.
func WithOutputFormat ¶ added in v0.3.0
func WithOutputFormat(f OutputFormat) WriterOption
WithOutputFormat sets the explicit output format, overriding TTY auto-detection.
func WithProtocolVersion ¶ added in v0.3.0
func WithProtocolVersion(v string) WriterOption
WithProtocolVersion sets the protocol version for envelope shaping. Valid values: "0.1", "0.2". Empty string defaults to "0.2" (current).