Documentation
¶
Index ¶
- Constants
- Variables
- func Files() []string
- func PluginFiles() []string
- func Read(name string) ([]byte, error)
- func SortModules(metas []ModuleMeta)
- type BuiltinFlags
- type CommandSpec
- type CompletionSeqStep
- type CompletionSpec
- type EndpointSpec
- type FieldDef
- type Flag
- type HandlerType
- type MigrateFlag
- type ModuleMeta
- type NounDef
- type PagingSpec
- type TableColumn
- type TableSpec
- type UICommand
- type VerbInfo
Constants ¶
const ( ConfirmNone = "" ConfirmPrompt = "prompt" ConfirmID = "confirm_id" )
Valid confirm_mode values for CommandSpec.
const ( UpdateStrategyGetThenPut = "get-then-put" UpdateStrategyGetThenPutKV = "get-then-put-kv" UpdateStrategyGetThenPatch = "get-then-patch" )
Valid update_strategy values for EndpointSpec.
const ( FileBodyNone = "" // no file body support FileBodyOptional = "optional" // -f accepted; falls back to other strategy if omitted FileBodyRequired = "required" // -f is mandatory; error if omitted )
Valid file_body values for EndpointSpec and CommandSpec.
const ( PagingStrategyPageIndex = "page_index" // API accepts pageIndex + pageSize; response has totalItems, content, empty PagingStrategyPageHeader = "page_header" // v1 API: bare array body; total/page info in X-Total-Elements / X-Page-Number / X-Page-Size response headers PagingStrategyFlatList = "flat_list" // API returns all items in one shot; offset/limit applied client-side PagingStrategyNone = "none" // API returns everything; offset/limit applied client-side PagingStrategyCursor = "cursor" // token-based iteration; no random access, not countable (not yet implemented) PagingStrategyOffsetLimit = "offset_limit" // API accepts offset (items to skip) + limit; response has totalCount )
Valid paging_strategy values for PagingSpec.
const ( MigratePresenceRequired = "required" // flag is registered and must be provided MigratePresenceOptional = "optional" // flag is registered; may be omitted (default) MigratePresenceNone = "none" // flag is not registered at all )
Valid presence values for MigrateFlag.
const ( ModuleTypeBuiltin = "builtin" // compiled into the binary, always enabled ModuleTypePlugin = "plugin" // dispatches to a separately installed binary // ModuleTypeHidden marks a module as not enabled by default: invisible in // list/get module and no commands registered until something enables it. // It replaces module_type: builtin (not module_type: plugin) — a hidden // module is still compiled into the binary, just opt-in. ModuleTypeHidden = "hidden" )
Valid module_type values for a spec file's top-level module_type field.
const ( UICommandText = "text" UICommandLink = "link" UICommandView = "view" // UICommandUp jumps to another noun's get detail using an id derived from // fields on the current item's own data (via UpIdExpr), not the current // item's id or its ParentId. Must be declared explicitly per noun — there // is no implicit "go up" navigation stack. UICommandUp = "up" )
UICommandType values for UICommand.UICommandType.
const (
CreateStrategySetFields = "set-fields"
)
Valid create_strategy values for EndpointSpec.
Variables ¶
var ModuleOrder = []string{"core", "platform", "pipeline", "cd", "fme"}
ModuleOrder defines the preferred display order for known modules. Modules not listed here appear after these, in alphabetical order.
Functions ¶
func Files ¶
func Files() []string
Files returns the names of all embedded builtin *.spec.yaml files (everything except pluginSpecFiles).
func PluginFiles ¶
func PluginFiles() []string
PluginFiles returns the names of embedded specs for plugin modules.
func SortModules ¶
func SortModules(metas []ModuleMeta)
SortModules sorts metas by moduleOrder, with unlisted modules appended alphabetically.
Types ¶
type BuiltinFlags ¶
type BuiltinFlags struct {
Page bool `yaml:"page,omitempty"` // --page N (1-indexed); exposed in expr as integer flags.page = N-1
Set bool `yaml:"set,omitempty"` // Enables --set, --del, and --add; handlers decide which operations are valid.
Del bool `yaml:"del,omitempty"` // Retained for commands that only enable --del.
UI bool `yaml:"ui,omitempty"` // --ui launch interactive TUI (requires both stdin and stdout to be a TTY)
}
BuiltinFlags enables predefined system flags that have fixed registration and dispatch behavior.
type CommandSpec ¶
type CommandSpec struct {
// Command is the full command name ("verb noun:variant", or just "verb" for noun-less commands).
// Redundant — always equals Verb+" "+FullNoun() — but declared first in every spec entry so
// any command can be found with a single grep: grep "command: list pipeline" *.spec.yaml
Command string `yaml:"command"`
Verb string `yaml:"verb"`
Noun string `yaml:"noun,omitempty"` // base noun; empty for management exceptions
NounVariant string `yaml:"noun_variant,omitempty"` // optional variant suffix; produces "noun:variant" cobra subcommand
NounTo string `yaml:"noun_to,omitempty"` // second noun of a pair verb (migrate/convert); mutually exclusive with NounVariant
MigrateFrom *MigrateFlag `yaml:"migrate_from,omitempty"` // pair verbs only: customizes --from
MigrateTo *MigrateFlag `yaml:"migrate_to,omitempty"` // pair verbs only: customizes --to
Short string `yaml:"short,omitempty"`
Long string `yaml:"long,omitempty"`
RequiresId bool `yaml:"requires_id,omitempty"` // positional [id] is mandatory for this command
NoId bool `yaml:"no_id,omitempty"` // opt out of the verb's default RequiresId (e.g. singleton get commands)
AllowsId bool `yaml:"allows_id,omitempty"` // when set (with no_id), still populate ctx.Id if a positional arg is given
IdLabel string `yaml:"id_label,omitempty"` // overrides "<id>" in the Usage line (e.g. "<registry/path>")
ArgsLabel string `yaml:"args_label,omitempty"` // appended to Usage after the id label (e.g. "<local-file>"); only used when has_args is true
IdParts int `yaml:"id_parts,omitempty"` // when > 1, id must contain exactly (id_parts-1) "/" separators; parts available as {ctx:id_part:0}, {ctx:id_part:1}, ...
IdAllowSlash bool `yaml:"id_allow_slash,omitempty"` // skip the slash-count validation on id (use when the id format has variable segments)
RequiresParentId bool `yaml:"requires_parentid,omitempty"` // list commands only: makes the [parentid] arg mandatory
ParentIdLabel string `yaml:"parentid_label,omitempty"` // overrides "[parentid]" in the Usage line for list commands (e.g. "<registry/name>")
Hidden bool `yaml:"hidden,omitempty"`
DevOnly bool `yaml:"dev_only,omitempty"` // skipped at registration time when not a dev build
NoAuth bool `yaml:"no_auth,omitempty"` // set to true to skip auth resolution (auth subcommands, version)
BuiltinFlags BuiltinFlags `yaml:"flags_builtin,omitempty"`
HasArgs bool `yaml:"has_args,omitempty"` // accepts extra positional args beyond [id]; parsed into ctx.Args
HandlerType HandlerType `yaml:"handler_type"`
VerbHandler string `yaml:"verb_handler,omitempty"` // overrides verb for behavioral dispatch (flag binding, ctx.Verb); leave unset to use verb
ConfirmMode string `yaml:"confirm_mode,omitempty"` // not allowed on list or get; see ConfirmNone/ConfirmPrompt/ConfirmID
WorkflowID string `yaml:"workflow_id,omitempty"` // set when HandlerType == HandlerWorkflow
ItemFn string `yaml:"item_fn,omitempty"` // optional: workflow-backed get's item resolver, used for TUI drilldown rendering
FollowFn string `yaml:"follow_fn,omitempty"` // optional: called after a successful endpoint command when --follow is set
Flags []Flag `yaml:"flags,omitempty"` // custom flags for workflow commands
Endpoint *EndpointSpec `yaml:"endpoint,omitempty"` // set when HandlerType == HandlerEndpoint
FieldsNoun string `yaml:"fields_noun,omitempty"` // override noun used for field lookup when the command's shape differs from its noun
CompletionNoun string `yaml:"completion_noun,omitempty"` // override noun used to find the list spec for <id> completion
CompletionSeq []CompletionSeqStep `yaml:"completion_seq,omitempty"` // slash-delimited multi-part ID completion; overrides completion_noun when set
Module string `yaml:"-"` // set at registration time by ModuleRegistrar; drives workflow/formatter namespacing
SpecFile string `yaml:"-"` // spec filename, set at load time; used in error messages
External bool `yaml:"-"` // set at registration time on the main binary when the module dispatches to a plugin binary; never in spec YAML
}
CommandSpec fully describes one CLI command.
Exception verbs (version, auth, …) have an empty Noun and appear at root level. Core verbs always have a Noun and nest as "harness <verb> <noun>".
func (*CommandSpec) FullNoun ¶
func (cs *CommandSpec) FullNoun() string
FullNoun returns "noun:variant" when NounVariant is set, "noun:noun_to" when NounTo is set, otherwise just Noun. Use this wherever the cobra subcommand name or command identity is needed. Use Noun directly when looking up field definitions or completion sources (base noun only).
func (*CommandSpec) UsageLine ¶
func (cs *CommandSpec) UsageLine() string
UsageLine returns the grammar portion of Short (after the first ": "), prefixed with "\nusage: ". Returns empty string when Short is not set.
type CompletionSeqStep ¶
type CompletionSeqStep struct {
CompletionNoun string `yaml:"completion_noun"`
StaticValues []string `yaml:"static_values,omitempty"` // fixed completion list for this step (mutually exclusive with completion_noun)
KeepOrder bool `yaml:"keep_order,omitempty"`
}
CompletionSeqStep describes one segment of a slash-delimited multi-part ID completion. Index 0 completes the first segment (e.g. registry), index 1 completes the second (e.g. artifact), and so on. The already-typed segments are joined and passed as ParentId when calling the list endpoint, so parentIdParts resolves correctly in path templates.
type CompletionSpec ¶
type CompletionSpec struct {
IdExpr string `yaml:"id_expr"`
NameExpr string `yaml:"name_expr"`
NoSearchInject bool `yaml:"no_search_inject,omitempty"`
}
CompletionSpec drives dynamic tab-completion for the <id> positional argument. IdExpr and NameExpr are expr-lang expressions evaluated against each item; "it" is bound to the item.
type EndpointSpec ¶
type EndpointSpec struct {
// Path is the API path template, e.g. "/v1/orgs/{org}/projects/{project}/pipelines"
Path string `yaml:"path"`
// Method is the HTTP method. Defaults to "GET" if empty.
Method string `yaml:"method,omitempty"`
// PathParams maps flag-name → placeholder in Path.
PathParams map[string]string `yaml:"path_params,omitempty"`
// QueryParams maps query param name → expr-lang expression. The param is omitted
// when the expression returns empty. Flags are available as flags.<name>.
QueryParams map[string]string `yaml:"query_params,omitempty"`
// BodyParams maps dot-path in the JSON body → expr-lang expression.
// Supports nested paths: {"config.type": "flags.type"} sets body["config"]["type"].
// Expressions have access to ctx, auth, flags, coalesce(), formatTags(), etc.
// An expression returning nil contributes no key at all.
// On the get-then-* update strategies these are merged into the body after
// update_body_pick and update_body_wrap, which is how a write-only field is declared:
// one the API accepts on write but never returns, so the pick cannot source it.
BodyParams map[string]string `yaml:"body_params,omitempty"`
// RequestHeaders maps HTTP header name → expr-lang expression.
// Headers are evaluated against the command context (auth, flags, ctx) and injected
// into the request. Useful for APIs that require custom headers, e.g. x-tenant-id.
// Example: {"x-tenant-id": "auth.account"}
RequestHeaders map[string]string `yaml:"request_headers,omitempty"`
// FieldExtract, when non-empty, extracts this top-level string field from the
// JSON response object and prints it as a raw string instead of JSON.
FieldExtract string `yaml:"field_extract,omitempty"`
// ItemsExpr is an expr-lang expression that resolves to the []any of items in a
// list response. Required for all VerbList commands; not allowed on any other verb.
// Use "it" for bare arrays. "it" is bound to the full response; ctx, auth, flags,
// and helpers are also available.
ItemsExpr string `yaml:"items_expr,omitempty"`
// ItemItemExpr, when non-empty, is evaluated against each list item to unwrap it to a
// canonical shape (e.g. "it.project" unwraps {project:{...}} to the project object).
// This lets list and get share field definitions when the get item_expr produces the
// same shape as the unwrapped list item.
ItemItemExpr string `yaml:"item_item_expr,omitempty"`
// ItemExpr is an expr-lang expression that resolves to the single item in a get
// response. Required for all VerbGet commands. Use "it" for bare item responses.
// "it" is bound to the full response; ctx, auth, flags, and helpers are also available.
ItemExpr string `yaml:"item_expr,omitempty"`
// YamlPickExpr, when non-empty, enables --format yaml on get commands and defines which
// subtree of the raw API response to emit. Evaluated from root ("it" = full response).
// Should produce an object that round-trips cleanly with the corresponding update -f.
YamlPickExpr string `yaml:"yaml_pick_expr,omitempty"`
// YamlExclude lists top-level keys to strip from the yaml_pick_expr result before emitting.
// Use to remove server-managed read-only fields so the output round-trips cleanly with create/update.
YamlExclude []string `yaml:"yaml_exclude,omitempty"`
// GetIdExpr, when non-empty, is an expr-lang expression evaluated against each list
// item to produce the composite id suitable for passing to the corresponding get command.
// "it" is bound to the item; parentId/parentIdParts are also available.
// When absent, the feature is disabled for this command.
GetIdExpr string `yaml:"get_id_expr,omitempty"`
// Completion, when non-nil, enables dynamic tab-completion for list commands.
// IdExpr and NameExpr are expr-lang expressions into each item from ItemsExpr.
Completion *CompletionSpec `yaml:"completion,omitempty"`
// NoFields, when true, suppresses all field rendering (noun fields and fields_extra).
// Use with text_header/text_footer for commands whose response has no displayable fields.
NoFields bool `yaml:"no_fields,omitempty"`
// NoAccountID, when true, omits the accountIdentifier query param that is otherwise
// set on every request. Use for endpoints that reject or don't expect it.
NoAccountID bool `yaml:"no_account_id,omitempty"`
// FieldsSubset lists field IDs from the noun that this command's API actually returns.
// When set, --list-columns only advertises these IDs.
FieldsSubset []string `yaml:"fields_subset,omitempty"`
// FieldsExtra declares additional fields available only on this command (e.g. list-only
// computed columns like sparklines). Appended after the noun's fields (or fields_subset).
FieldsExtra []FieldDef `yaml:"fields_extra,omitempty"`
// Columns lists field IDs (from fields: or fields_from:) to display by default in table output.
// When omitted and fields are defined, all fields are shown. Enables --format table|tsv|json.
Columns []string `yaml:"columns,omitempty"`
// FileBody controls whether -f/--file is added to the command.
// "optional": accepted, falls back to other strategy if omitted.
// "required": -f is mandatory; error if omitted.
FileBody string `yaml:"file_body,omitempty"`
// ContentType overrides the default wire Content-Type header for the request.
// Only used when FileBody is set; defaults to "application/json". Does NOT
// describe the format of the -f file itself — see FileBodyContentType for that.
ContentType string `yaml:"content_type,omitempty"`
// FileBodyContentType overrides the format the -f file is validated/normalized
// against (independent of the wire ContentType). Only used when FileBody is set.
// Defaults to ContentType's value when unset. Required whenever FileBodyWrapAsString
// is set and the -f format differs from the wire Content-Type (e.g. a JSON API that
// wraps a raw YAML string).
FileBodyContentType string `yaml:"file_body_content_type,omitempty"`
// FileBodyWrapAsString embeds the raw, unparsed -f file contents as a string value
// under this key, sent as a JSON object on the wire regardless of ContentType or
// FileBodyContentType. Used by APIs that expect { "<key>": "<file contents as a
// string>" } (e.g. the v1 template API's template_yaml envelope).
FileBodyWrapAsString string `yaml:"file_body_wrap_as_string,omitempty"`
// FileBodyYamlEnvelope wraps the -f file into a Harness CD-style DTO envelope:
// lifts identity fields (identifier/name/orgIdentifier/projectIdentifier/type/
// environmentRef) to the top level and embeds the full resource YAML under a
// "yaml" string field. The value is the inner wrapper key (e.g. "service",
// "environment", "infrastructureDefinition") used to detect/re-wrap the resource
// when the -f file is given in unwrapped or flat form. If the -f file already
// has a top-level "yaml" string field, it is passed through as-is (only missing
// org/project scope is defaulted).
FileBodyYamlEnvelope string `yaml:"file_body_yaml_envelope,omitempty"`
// TextFormatter names a registered TextFormatterFn used when --format text.
TextFormatter string `yaml:"text_formatter,omitempty"`
// TextHeader and TextFooter are optional {{expr}}-interpolated strings printed
// before and after the fields block. Rendered only when non-empty after interpolation.
TextHeader string `yaml:"text_header,omitempty"`
// BodyFn names a registered CreateBodyFn that builds the POST body instead of the
// default body_params / body construction. Qualified by module at registration time.
BodyFn string `yaml:"body_fn,omitempty"`
// QueryParamsFn names a registered QueryParamsFn whose returned map is merged into
// the request query params after CEL query_params are evaluated. Use when a query
// param requires Go logic (e.g. a pre-fetch to resolve an ID) that cannot be expressed
// in CEL. Only applies to GET and list requests; not called for update/create strategies.
// Qualified by module at registration time.
QueryParamsFn string `yaml:"query_params_fn,omitempty"`
// ValidatorsEndpoint lists registered EndpointValidatorFn IDs to run after the
// request is built but before it is sent. Each fn receives ctx and the materialized
// request; return a non-nil error to abort. Qualified by module at registration time.
ValidatorsEndpoint []string `yaml:"validators_endpoint,omitempty"`
// Paging, when non-nil, enables framework-managed paging for list commands.
// Not allowed on any other verb. Exposes --offset, --limit, --all, and (when countable) --count.
Paging *PagingSpec `yaml:"paging,omitempty"`
// UpdateStrategy declares how update commands mutate the resource.
// "get-then-put": GET the resource first, apply --set/--del mutations locally, then PUT.
// "get-then-put-kv": GET a [{key,value}] array, apply --set/--del by key, then PUT the full array.
// Only valid when method is PUT.
UpdateStrategy string `yaml:"update_strategy,omitempty"`
// UpdateBodyPick is an expr evaluated against the raw GET response root ("it" = full
// response) to extract the mutable subtree before mutation and re-wrap. e.g. "it.data.project".
// Should match yaml_pick_expr on the corresponding get command (they describe the same subtree).
UpdateBodyPick string `yaml:"update_body_pick,omitempty"`
// UpdateBodyWrap is the key name used to re-wrap the picked subtree in the PUT body.
// e.g. "project" → PUT body becomes {"project": <mutated subtree>}
UpdateBodyWrap string `yaml:"update_body_wrap,omitempty"`
// GetPath overrides path for the GET leg of get-then-put and get-then-put-kv.
// Use when the GET and PUT endpoints have different paths (e.g. PUT /connectors, GET /connectors/{id}).
// When absent, path is used for both legs.
GetPath string `yaml:"get_path,omitempty"`
// GetQueryParams overrides query_params for the GET leg of get-then-put-kv.
// Use when the GET and PUT endpoints require different query parameters.
GetQueryParams map[string]string `yaml:"get_query_params,omitempty"`
// CreateStrategy declares how create commands build the POST body from --set args.
// "set-fields": seed from create_body_init, apply --set mutations, wrap under create_body_wrap, then POST.
// Enables --set / positional key=value args and --list-fields on create commands.
CreateStrategy string `yaml:"create_strategy,omitempty"`
// CreateBodyInit is a map of dot-path → expr-lang expression used to seed the
// initial object before --set mutations are applied. Used to inject required fields
// like identifier and name defaults. e.g. {"identifier": "ctx.id", "name": "coalesce(setArgs.name, ctx.id)"}
CreateBodyInit map[string]string `yaml:"create_body_init,omitempty"`
// CreateBodyWrap is the key name used to wrap the body before POST.
// e.g. "project" → POST body becomes {"project": <mutated object>}
CreateBodyWrap string `yaml:"create_body_wrap,omitempty"`
// FetchFn names a registered FetchFn used instead of the default HTTP paging
// machinery. Used for in-memory or config-file backed list commands (e.g. "list noun").
// When empty, HTTPFetchFn is used.
FetchFn string `yaml:"fetch_fn,omitempty"`
// ListTransformFn names a registered ListTransformFn that converts this command's
// get/execute response into a list for rendering via the standard list pipeline
// (columns/table/csv/tsv/jsonl), instead of FormatSingleOutput's json/text/yaml.
// Qualified by module at registration time. Not allowed on VerbList commands
// (they already have items_expr for this).
ListTransformFn string `yaml:"list_transform_fn,omitempty"`
}
EndpointSpec describes a single Harness API call.
Path is a template with {placeholders}. PathParams maps flag names to placeholder names. QueryParams maps flag names to query param names — the framework resolves org/project/account automatically from auth; only resource-specific params go here.
type FieldDef ¶
type FieldDef struct {
// ID is required: the slug used in columns:, fields_subset:, fields_extra:, and --columns flag.
// Must be lowercase with underscores (e.g. "last_run_by").
ID string `yaml:"id"`
// Label is the human-readable column header / text label.
// When omitted, auto-derived from ID by replacing underscores with spaces and title-casing.
Label string `yaml:"label,omitempty"`
// Expr is a required expr-lang expression evaluated against the item ("it") for display.
Expr string `yaml:"expr,omitempty"`
// MutablePath is the dot-path relative to the update_body_pick subtree (e.g. "name",
// "spec.value"). Must not start with "it.". Its presence marks the field as writable
// and should match update_body_pick on the corresponding update command.
MutablePath string `yaml:"mutable_path,omitempty"`
// FieldType optionally changes how the value is rendered or updated.
// Supported: "multiline_text" (renders raw block below other fields), "yaml" (alias for multiline_text, use for actual YAML content),
// "tags" (tag-map handling), "set" (string-set handling), "ts" (epoch-ms timestamp).
FieldType string `yaml:"field_type,omitempty"`
// Align controls horizontal alignment in the table renderer.
// Supported: "right". Empty means left (default).
Align string `yaml:"align,omitempty"`
// WidthMax caps the column width in characters; the renderer wraps longer values.
// Zero means unconstrained.
WidthMax int `yaml:"width_max,omitempty"`
}
FieldDef defines a named, reusable field for a noun. Fields declared here can be referenced by ID in fields_subset, fields_extra, and table columns lists.
Two mutually exclusive forms:
- Read-only: set Expr. Value is derived by evaluating Expr against the item.
- Editable: set Path. Path is the dot-path to the value in the item (e.g. "it.project.name"). FormatExpr may optionally override display formatting; when absent, Path is used as the display expression. Editable fields participate in "update" commands.
type Flag ¶
type Flag struct {
Name string `yaml:"name"`
Short string `yaml:"short,omitempty"` // single-char shorthand; use sparingly — prefer reserving shorthands for core flags
Default string `yaml:"default,omitempty"`
Description string `yaml:"description,omitempty"`
Required bool `yaml:"required,omitempty"` // if true, command errors if flag is not provided
IsBool bool `yaml:"is_bool,omitempty"` // if true, declares a bool flag instead of a string flag
IsArray bool `yaml:"is_array,omitempty"` // if true, value is parsed as []string: comma-separated or JSON array syntax
IsMulti bool `yaml:"is_multi,omitempty"` // if true, registers as StringArray (repeatable: --flag v1 --flag v2)
Hidden bool `yaml:"hidden,omitempty"` // if true, flag is registered but not shown in --help output
CompletionNoun string `yaml:"completion_noun,omitempty"` // list noun to call for dynamic tab-completion
CompletionFn string `yaml:"completion_fn,omitempty"` // registered FlagCompletionFn name (overrides completion_noun)
CompletionValues []string `yaml:"completion_values,omitempty"` // static list of completion values (overrides completion_noun/fn)
ParentFromArg int `yaml:"parent_from_arg,omitempty"` // positional arg index to use as parentId when calling completion_noun list endpoint
FlagResolveFn string `yaml:"flag_resolve_fn,omitempty"` // registered FlagResolveFn name; transforms the raw flag string value before CEL evaluation
}
Flag declares a command-specific flag surfaced in --help and validated before dispatch.
type HandlerType ¶
type HandlerType string
HandlerType identifies how a command is dispatched.
const ( HandlerWorkflow HandlerType = "workflow" HandlerEndpoint HandlerType = "endpoint" )
type MigrateFlag ¶
type MigrateFlag struct {
// Label overrides the flag's --help text (e.g. "GitHub organization to migrate").
Label string `yaml:"label,omitempty"`
// IdLabel overrides the "<id>" value placeholder shown after the flag in usage
// lines (e.g. "<bundle-folder-or-zip>", "<folder>").
IdLabel string `yaml:"id_label,omitempty"`
// Presence controls flag registration. See MigratePresence* consts.
Presence string `yaml:"presence,omitempty"`
}
MigrateFlag customizes the --from / --to flag of a pair verb (migrate) command. Both fields are optional: an absent block behaves as presence: optional with the generic label.
func (*MigrateFlag) EffectiveIdLabel ¶
func (m *MigrateFlag) EffectiveIdLabel() string
EffectiveIdLabel returns the declared value placeholder, defaulting to "<id>".
func (*MigrateFlag) EffectiveLabel ¶
func (m *MigrateFlag) EffectiveLabel(fallback string) string
EffectiveLabel returns the declared label, or fallback when none is declared.
func (*MigrateFlag) EffectivePresence ¶
func (m *MigrateFlag) EffectivePresence() string
EffectivePresence returns the declared presence, defaulting to optional for an absent block or an empty field.
func (*MigrateFlag) UsageFragment ¶
func (m *MigrateFlag) UsageFragment(name string) string
UsageFragment renders this flag for a usage line: " --name <label>" when required, " [--name <label>]" when optional, "" when the flag is not registered. name is the flag name ("from" or "to").
type ModuleMeta ¶
type ModuleMeta struct {
Name string
Type string // ModuleTypeBuiltin, ModuleTypePlugin, or ModuleTypeHidden
Desc string
Core bool // true for CLI-internal modules (auth, mgmt) that are hidden from "list module"
HelpText string // contents of <module>.help.txt, empty if none
NounOrder []string // noun names in spec-file declaration order, for conceptual ordering
// FromSpecDir is true when this module was loaded from ~/.harness/spec (a
// dynamically-installed plugin) rather than compiled into the binary. It is
// the authoritative builtin-vs-installed signal — set at load time, not
// inferred from dispatch fields.
FromSpecDir bool
// Provenance fields — host-owned, populated only for plugins installed to
// ~/.harness/spec. Empty for builtin (embedded) modules.
Version string // plugin --version captured at install/update time (no "v" prefix)
BinaryPath string // path to the plugin binary to dispatch to (may contain ~)
Source string // url-or-origin the tarball was installed from
InstalledAt string // when this plugin was installed (RFC3339)
}
ModuleMeta holds metadata declared at the top level of a spec file.
func (ModuleMeta) IsPlugin ¶
func (m ModuleMeta) IsPlugin() bool
IsPlugin reports whether commands in this module dispatch to a separately installed binary rather than running in-process. Plugins reach the host only through ~/.harness/spec, so a binary_path in the provenance block is the signal.
type NounDef ¶
type NounDef struct {
Noun string `yaml:"noun"`
ShortDesc string `yaml:"short_desc,omitempty"`
Fields []FieldDef `yaml:"fields"`
// UrlPath is an optional UI URL template using the same {{expr}} syntax as endpoint paths.
// "it" is bound to the response item, so column exprs can call url(it) to get a
// clickable link to the resource in the Harness UI. Returns "" when empty.
UrlPath string `yaml:"url_path,omitempty"`
// MultiLevel indicates the noun can exist at account, org, or project scope.
// Set explicitly in the spec YAML on nouns that support --level.
MultiLevel bool `yaml:"multi_level,omitempty"`
// NounAliases lists alternate names for this noun (e.g. "org", "orgs" for "organization").
// Alias commands are wired up as hidden cobra commands and do not appear in help output.
NounAliases []string `yaml:"noun_aliases,omitempty"`
// UICommands declares the hotkeys the --ui detail overlay offers for this noun:
// alternate shapes to render in place (text), navigation to a related noun (link),
// or a full-takeover custom TUI (view). Optional; absent means unchanged behavior.
UICommands []UICommand `yaml:"ui_commands,omitempty"`
}
NounDef defines the canonical field vocabulary for a noun. Declared at the top level of a spec file; commands look up their fields by noun name.
type PagingSpec ¶
type PagingSpec struct {
// PagingStrategy identifies the paging style. See PagingStrategy* consts.
PagingStrategy string `yaml:"paging_strategy"`
// Countable indicates whether the API returns a total item count in its response.
// When true, --count is supported. When false, --count returns an error.
// PagingStrategyNone always supports --count (client-side length). PagingStrategyCursor never does.
Countable bool `yaml:"countable,omitempty"`
// page_index model fields
PageIndexParam string `yaml:"page_index_param,omitempty"` // query param name, e.g. "pageIndex"
PageSizeParam string `yaml:"page_size_param,omitempty"` // query param name, e.g. "pageSize"
PageSizeDefault int `yaml:"page_size_default,omitempty"` // default page size (e.g. 50)
PageSizeMax int `yaml:"page_size_max,omitempty"` // max page size the API accepts (e.g. 100)
// TotalExpr is an expression evaluated against the raw response (with "it" bound to the response root).
// Resolves to the total item count, e.g. "it.data.totalItems". Required for page_index model.
TotalExpr string `yaml:"total_expr,omitempty"`
// PageBase is added to every page number sent to the API. Default 0 (0-based).
// Set to 1 for APIs that require page >= 1. page_index model only.
PageBase int `yaml:"page_base,omitempty"`
// page_header model fields
// TotalHeader is the response header name to read for the total item count. Default "X-Total-Elements".
TotalHeader string `yaml:"total_header,omitempty"`
}
PagingSpec declares the paging model for a list endpoint. The framework uses this to implement --offset, --limit, --all, and --count transparently across different API paging styles.
func (*PagingSpec) IsCountable ¶
func (p *PagingSpec) IsCountable() bool
IsCountable reports whether --count is supported for this paging spec. flat_list always supports it (total is the client-side length); other strategies require countable: true in the spec.
type TableColumn ¶
TableColumn is one column in a TableSpec.
type TableSpec ¶
type TableSpec struct {
Columns []TableColumn
}
TableSpec is a declarative table definition used internally by the rendering layer. Not exposed in spec YAML — use fields: + columns: instead.
type UICommand ¶
type UICommand struct {
UICommandType string `yaml:"ui_command_type"`
Key string `yaml:"key"`
// Label overrides the hotkey hint text shown in the detail overlay's status
// line. When empty, the hint is derived from the resolved noun/handler.
Label string `yaml:"label,omitempty"`
// Default marks the text entry rendered when the detail pane first opens.
// Only valid on text entries; exactly one text entry per noun must set it.
Default bool `yaml:"default,omitempty"`
// Noun is a full "noun[:variant]" string resolved via GetSpec(VerbGet, ...)
// for text entries, or GetSpec(Verb, ...) for link/up entries.
Noun string `yaml:"noun,omitempty"`
// Verb is the link target's verb: "list" or "get". Required for link;
// for up it's optional and defaults to "get".
Verb string `yaml:"verb,omitempty"`
// UIHandlerFn is the registered workflow id to hand off to. View only.
UIHandlerFn string `yaml:"ui_handler_fn,omitempty"`
// UpIdExpr is an expr-lang expression evaluated against the current
// item ("it") to derive the target id for an "up" jump, e.g.
// "it.check.payload.data.execution_id". Up only, required.
UpIdExpr string `yaml:"up_id_expr,omitempty"`
}
UICommand is a single hotkey offered by a noun's --ui detail overlay. One flat struct for all ui_command_types, matching how CommandSpec/EndpointSpec already mix fields that only apply to some verbs/shapes — checks.go enforces which fields are required/forbidden for which type.