Documentation
¶
Overview ¶
Package kit turns one declaration of an operation into three surfaces: a CLI subcommand, an HTTP route, and an MCP tool. A domain describes what its verbs do and how their inputs and outputs are shaped; kit builds the command tree, the flag parser, the JSON-over-HTTP server, and the MCP server from that one description.
The model ¶
An operation is a typed handler with surface-neutral metadata. The handler takes a context, a typed input struct, and an emit callback; it streams zero or more records to emit and returns an error. kit reflects the input struct once to learn its arguments and flags, and the output struct to learn the record's collection name and primary key. The same operation then renders as a CLI subcommand, answers an HTTP request, and exposes an MCP tool, with no per-surface code in the domain.
type searchIn struct {
Query string `kit:"arg" help:"URL or prefix to search"`
Limit int `kit:"flag" default:"20" help:"max captures"`
Client *crawl.Client `kit:"inject"`
}
type Capture struct {
URL string `json:"url" kit:"id"`
Status int `json:"status"`
}
kit.Handle(app, kit.OpMeta{
Name: "search",
Group: "read",
Summary: "Find captures for a URL or prefix",
}, func(ctx context.Context, in searchIn, emit func(Capture) error) error {
return in.Client.Search(ctx, in.Query, in.Limit, emit)
})
Input fields ¶
A field's kit tag says how kit fills it:
kit:"arg" a positional argument, in declaration order kit:"flag" a named flag / query parameter / tool argument (the default) kit:"inject" filled by kit with the domain client or record store
Options after the kind refine the binding:
name=foo override the derived snake_case name short=q single-letter CLI shorthand (-q) variadic an arg that takes the rest of the positionals; a slice flag inherit bind to a framework-global flag of the same name (e.g. limit)
Sibling tags describe the value: help for the one-line description, default for the unset value, and enum for a comma-separated set of allowed values.
An output field tagged kit:"id" (or named id) is the record's primary key, used to upsert into the record store when --db is set.
Building an app ¶
A domain builds one App, registers its operations, sets a client factory, and hands the App to Run:
func main() {
app := kit.New(kit.Identity{
Binary: "ccrawl",
Short: "A command line for Common Crawl",
Version: version,
})
app.SetClient(func(ctx context.Context, c kit.Config) (any, error) {
return crawl.New(c), nil
})
registerOps(app)
kit.Main(app)
}
New derives the baseline Config (XDG paths, env prefix, rate, retries, timeout, workers) from the binary name; WithDefaults overlays the domain's own values. SetClient registers the factory kit calls once per run; its result is injected into handler fields tagged kit:"inject" by assignability. GlobalFlags registers persistent flags that are not part of the baseline, and the domain reads them when building its client.
Escape hatches ¶
Some verbs do not fit the emit-records shape: a byte stream, an interactive shell, a bulk download, or a parent that only groups subcommands. A domain declares those as a Command, a small struct of metadata wired to named functions, without naming the underlying cobra and pflag types:
app.AddCommand(kit.Command{
Use: "get <url>",
Short: "Print the bytes Common Crawl captured",
Args: kit.ExactArgs(1),
Flags: c.flags,
Run: c.run,
})
Command.Flags binds flags through a FlagSet, whose method set mirrors pflag (StringVar, StringVarP, IntVar, BoolVar, and so on). Command.Args validates the positionals with one of ExactArgs, MinimumNArgs, MaximumNArgs, RangeArgs, or NoArgs. A run handler reaches the run's resolved config, client, and record store with MustClient (or Client when building can fail), the typed companions to FromContext and State.Client. Escape-hatch commands appear on the CLI only; the HTTP and MCP surfaces expose registered operations.
Surfaces ¶
The default invocation runs the CLI. The serve subcommand starts the HTTP server, mcp starts the MCP server over stdio, and each exposes the same operations. Run returns a process exit code derived from the error: the github.com/tamnd/any-cli/kit/errs taxonomy maps a usage error to 2, an empty result to 3, a missing credential to 4, a rate limit to 5, and so on, so the same failure yields the same code on every surface.
Index ¶
- func Client[T any](ctx context.Context) (T, error)
- func Domains() []string
- func Handle[In, Out any](app *App, meta OpMeta, fn func(context.Context, In, func(Out) error) error)
- func IsReservedKind(scheme string) bool
- func Main(app *App)
- func MustClient[T any](ctx context.Context) T
- func NoArgs(args []string) error
- func Register(dom Domain)
- func Run(ctx context.Context, app *App) int
- func WithState(ctx context.Context, st *State) context.Context
- type App
- func (a *App) AddCommand(cmd Command)
- func (a *App) AddCommandUnder(parent string, cmd Command)
- func (a *App) CommandGroup(name, summary string)
- func (a *App) Config() Config
- func (a *App) Finalize(fn func(*Config))
- func (a *App) GlobalFlags(fn func(*FlagSet))
- func (a *App) Identity() Identity
- func (a *App) Ops() []Operation
- func (a *App) SetClient(fn func(context.Context, Config) (any, error))
- type Arg
- type Args
- type Command
- type Config
- type Domain
- type DomainInfo
- type Envelope
- type FlagSet
- func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string)
- func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string)
- func (f *FlagSet) CountVar(p *int, name, usage string)
- func (f *FlagSet) CountVarP(p *int, name, shorthand, usage string)
- func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string)
- func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string)
- func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string)
- func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string)
- func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string)
- func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string)
- func (f *FlagSet) IntVar(p *int, name string, value int, usage string)
- func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string)
- func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string)
- func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string)
- func (f *FlagSet) StringVar(p *string, name, value, usage string)
- func (f *FlagSet) StringVarP(p *string, name, shorthand, value, usage string)
- type Globals
- type Host
- func (h *Host) Body(rec any) (string, bool)
- func (h *Host) Domain(scheme string) (DomainInfo, bool)
- func (h *Host) Domains() []string
- func (h *Host) Get(ctx context.Context, u URI) (any, error)
- func (h *Host) Links(rec any) []URI
- func (h *Host) List(ctx context.Context, u URI, limit int) ([]any, error)
- func (h *Host) Locate(u URI) (string, error)
- func (h *Host) Mint(rec any) (URI, error)
- func (h *Host) Resolve(input string) (URI, error)
- func (h *Host) ResolveOn(scheme, input string) (URI, error)
- func (h *Host) Search(ctx context.Context, scheme, query string, limit int) ([]any, error)
- func (h *Host) Searchable(scheme string) bool
- func (h *Host) Wrap(rec any, fetched time.Time) (Envelope, error)
- type HostOption
- type Identity
- type Input
- type OpMeta
- type Operation
- type Option
- type OutputOptions
- type ParamKind
- type ParamSpec
- type ParamType
- type Resolver
- type RunContext
- type Sink
- type State
- type URI
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Client ¶
Client returns the run's domain client typed as T. It is the typed companion to State.Client: an escape-hatch command that wants the concrete app it registered with SetClient calls Client[*MyApp](ctx) instead of fetching the state and asserting the any itself.
It returns an error when there is no run state on the context, when building the client failed, or when the client is not a T.
func Domains ¶ added in v0.2.0
func Domains() []string
Domains returns the canonical schemes of all registered domains, sorted. It is the analogue of sql.Drivers().
func Handle ¶
func Handle[In, Out any](app *App, meta OpMeta, fn func(context.Context, In, func(Out) error) error)
Handle registers a typed handler. It is the only registration call a domain makes. It reflects In to build the parameter set once, and Out to learn the record's collection name and primary key for the store tee.
func IsReservedKind ¶ added in v0.2.0
IsReservedKind reports whether scheme is one of the cross-site kind schemes.
func Main ¶
func Main(app *App)
Main is a convenience wrapper that runs the app with a cancellable context and calls os.Exit with the resulting code.
func MustClient ¶
MustClient is Client for clients that cannot fail to build. When a command's client factory is infallible (it only assembles config and shared handles), a missing or mistyped client is a wiring bug, not a runtime condition, so MustClient panics rather than making every command thread an impossible error. This mirrors template.Must and regexp.MustCompile.
func Register ¶ added in v0.2.0
func Register(dom Domain)
Register makes a Domain available to every host in the process. It is meant to be called from a domain package's init(). It panics — like sql.Register — if dom is nil, if its scheme is empty or malformed, if the scheme shadows a reserved kind (host/pages/feed/search/data), or if the scheme or any alias collides with an already-registered domain.
func Run ¶
Run is the single entrypoint a generated main calls. It builds the CLI tree from the registry, wraps it in fang for help, completion, and error rendering, and executes. The default invocation is the CLI; the serve, mcp, and tui subcommands switch surfaces. Run returns the process exit code.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is the registry every surface drives. A domain builds one with New, registers operations with Handle, sets its client factory, and hands the App to Run. The App holds no surface state of its own; each surface reads the operation list and the config to build itself.
func New ¶
New builds an App from its identity. It derives the baseline config from the binary name, then applies any options.
func (*App) AddCommand ¶
AddCommand is the escape hatch for an operation that does not fit the emit-records shape (an interactive shell, a DuckDB analytical console, a binary download). The command joins the CLI tree as-is. It is absent from the API and MCP surfaces, which expose only registered operations.
func (*App) AddCommandUnder ¶
AddCommandUnder attaches an escape-hatch command beneath a parent command, the same parent a nested operation declares with OpMeta.Parent. It lets a domain mix generated operations and hand-rolled commands under one group, so "crawls list" (an op) and "crawls info" (an escape hatch) sit side by side.
func (*App) CommandGroup ¶
CommandGroup sets the help summary for a parent command, whether that parent hosts operations, escape-hatch commands, or both. Without it a parent shows a generated one-line summary.
func (*App) Config ¶
Config returns the resolved baseline config, for a domain that needs to read a default while wiring its client factory.
func (*App) Finalize ¶
Finalize registers a hook kit calls after folding the framework globals onto the config, so a domain can apply its own global flags to the resolved Config (for instance copying a --data-dir-derived path into a domain field).
func (*App) GlobalFlags ¶
GlobalFlags lets a domain register its own persistent flags on the root, for settings that are not part of the framework baseline (for ccrawl: --crawl, --source, --library). The domain binds them to its own variables and reads those when building its client and its escape-hatch commands.
type Args ¶
Args validates a command's positional arguments. The constructors below cover the common cases; any function with this signature works, and returning an errs.Usage error keeps the exit code consistent with the rest of kit.
func MaximumNArgs ¶
MaximumNArgs allows at most n positional arguments.
func MinimumNArgs ¶
MinimumNArgs requires at least n positional arguments.
type Command ¶
type Command struct {
Use string // usage line, e.g. "paths <kind>"
Short string // one-line summary
Long string // multi-paragraph help
Aliases []string // alternate names
Group string // help group ID, matching an operation's Group
Args Args // positional-argument check; nil accepts any
Flags func(*FlagSet) // binds this command's flags; nil for none
Run func(context.Context, []string) error // handler; nil for a parent
Sub []Command // subcommands
Write bool // marks a mutating command (annotated for surfaces)
}
Command is a hand-written escape-hatch command, declared without naming the underlying cobra/pflag types. A domain reaches for it when a verb does not fit the emit-records shape of an operation: a byte stream, an interactive shell, a bulk download, or a parent that only groups subcommands.
The function-typed fields take named methods or functions, not closures, so a command reads as a small struct of metadata wired to package-level behaviour:
func newPathsCmd() kit.Command {
c := &pathsCmd{}
return kit.Command{
Use: "paths <kind>",
Short: "List the archive file paths for a crawl",
Args: kit.MaximumNArgs(1),
Flags: c.flags,
Run: c.run,
}
}
Escape-hatch commands appear on the CLI only; the HTTP and MCP surfaces expose registered operations.
type Config ¶
type Config struct {
Binary string // the binary name, e.g. "ccrawl"
EnvPrefix string // env var prefix, e.g. "CCRAWL"
DataDir string // root for cache, store, sessions
CacheDir string // on-disk content cache
ConfigDir string // config file directory
Profile string // selected profile name
Rate time.Duration // minimum delay between requests
Retries int // retry attempts on 429/5xx
Timeout time.Duration // per-request timeout
Workers int // bulk concurrency
NoCache bool // bypass caches
Color string // auto|always|never
UserAgent string // descriptive default UA
DB string // --db DSN for the record store (empty = no store)
Verbose int // verbosity level
Quiet bool // suppress progress
DryRun bool // print actions, do not perform them
Extra map[string]string
}
Config is the resolved runtime configuration kit hands a domain when it builds the client. The common fields live here so a domain does not re-derive XDG paths, rate, retries, and the like; a domain adds only its own extra settings (carried in Extra or read from its own env). Precedence is applied by the CLI surface: flags over env over the config file over these defaults.
func DefaultConfig ¶
DefaultConfig builds the baseline config for a binary, deriving the XDG paths and env prefix from the name. A domain overlays its own defaults on top.
type Domain ¶ added in v0.2.0
type Domain interface {
// Info returns the domain's identity and URI-scheme metadata.
Info() DomainInfo
// Register installs this domain's operations, client factory, and any
// domain-global flags onto app. It must be deterministic and do no I/O.
Register(app *App)
}
Domain is the driver for one site's data and its URI scheme. A site's library package registers an implementation from its init() with Register, so a blank import is enough to enable the domain — exactly as a database/sql program enables a driver with `import _ "github.com/lib/pq"`. The same Domain also builds the site's single binary (App), so the binary and a multi-domain host (ant) share one source of truth per site.
type DomainInfo ¶ added in v0.2.0
type DomainInfo struct {
Scheme string // canonical URI scheme and binary slug, e.g. "goodreads"
Aliases []string // alternate schemes that canonicalize to Scheme, e.g. {"ytb"}
Hosts []string // hostnames this domain owns, e.g. {"goodreads.com"}; used to resolve a pasted https URL to this domain
Identity Identity // reused by the single-site main to seed help/version
}
DomainInfo is the static descriptor of a domain.
type Envelope ¶ added in v0.2.0
type Envelope struct {
ID string `json:"@id"`
Type string `json:"@type"`
Fetched string `json:"@fetched,omitempty"`
Links map[string][]string `json:"@links,omitempty"`
Data any `json:"data"`
}
Envelope is the self-describing form a record takes when it is written to the data surface (8000_uri §6): the record's own fields under Data, wrapped with the URI that names it (@id), its type (@type), when it was fetched (@fetched), and its outbound graph edges as URIs (@links). A tree of these is walkable without the domain code that produced them, because every name is a URI.
type FlagSet ¶
type FlagSet struct {
// contains filtered or unexported fields
}
FlagSet binds a command's flags to a domain's own variables, the way a flag.FlagSet does, but without exposing the cobra/pflag types to the domain. The method set mirrors pflag one-for-one: each Var binds a long flag, and the matching VarP variant adds a single-letter shorthand. A domain that needs a flag type not listed here can request one; the set covers the common cases.
func (*FlagSet) CountVarP ¶
CountVarP binds a repeatable counting flag with a shorthand (e.g. -vvv).
func (*FlagSet) DurationVar ¶
DurationVar binds a time.Duration flag (e.g. --timeout 30s).
func (*FlagSet) DurationVarP ¶
func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string)
DurationVarP binds a time.Duration flag with a shorthand.
func (*FlagSet) Float64Var ¶
Float64Var binds a float64 flag.
func (*FlagSet) Float64VarP ¶
Float64VarP binds a float64 flag with a shorthand.
func (*FlagSet) StringSliceVar ¶
StringSliceVar binds a repeatable string flag, collected into a slice.
func (*FlagSet) StringSliceVarP ¶
func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string)
StringSliceVarP binds a repeatable string flag with a shorthand.
func (*FlagSet) StringVarP ¶
StringVarP binds a string flag with a shorthand.
type Globals ¶
type Globals struct {
Limit int // --limit / -n; 0 means no limit
}
Globals holds the framework-wide flags shared by every operation. They are parsed once by the surface and threaded through to Invoke.
type Host ¶ added in v0.2.0
type Host struct {
// contains filtered or unexported fields
}
Host is a multi-domain resolver: it mounts every registered Domain behind its URI scheme and dereferences a resource URI to a record by routing to that domain's operations. It is the runtime ant drives, and the analogue of an *sql.DB that can talk to every registered driver at once. A Host is safe for concurrent use; clients are built lazily and cached per domain.
func Open ¶ added in v0.2.0
func Open(opts ...HostOption) (*Host, error)
Open mounts every registered domain and returns a ready Host. It builds each domain's App once (so op metadata and client factories are resolved up front) but defers building clients until a URI actually routes to that domain. It is the analogue of sql.Open, except the data source is the whole registry rather than one named driver.
func (*Host) Body ¶ added in v0.2.0
Body returns the record's long-text body (the kit:"body" field) and whether it has one, so `ant cat` and the Markdown export can print the human-readable text without knowing which field holds it. It is pure reflection over the tag.
func (*Host) Domain ¶ added in v0.2.0
func (h *Host) Domain(scheme string) (DomainInfo, bool)
Domain returns the descriptor of a mounted domain by scheme or alias.
func (*Host) Domains ¶ added in v0.2.0
Domains returns the canonical schemes this host serves, sorted.
func (*Host) Get ¶ added in v0.2.0
Get dereferences a URI to its record by routing to the domain op that mints that authority's type and passing the id as the op's argument. It returns the single record the op emits.
func (*Host) Links ¶ added in v0.2.0
Links returns the outbound graph edges of a record: one URI per kit:"link" field value, with multi-valued and optional fields handled. It is pure reflection over the record's tags, so it needs no network and no host lookup beyond canonicalizing each link's scheme.
func (*Host) List ¶ added in v0.2.0
List returns the member records of a collection URI by routing to the domain's list op for that authority and passing the parent id. limit caps the result (0 means the op's own default).
func (*Host) Locate ¶ added in v0.2.0
Locate returns the live https location of a URI, the inverse of Resolve. It asks the owning domain's Resolver; a domain without one cannot be located.
func (*Host) Mint ¶ added in v0.2.0
Mint returns the URI that names a record, derived from the type the record was emitted as (which fixes its scheme and authority) and its id field. It is the inverse of Get and the canonical name a data export writes under @id.
func (*Host) Resolve ¶ added in v0.2.0
Resolve turns any input into a canonical URI. It accepts a string that is already a resource URI (canonicalizing its scheme), or an https URL whose host a mounted domain claims (handing it to that domain's Classify). A bare id or @handle is ambiguous without a scheme; use ResolveOn for that.
func (*Host) ResolveOn ¶ added in v0.2.0
ResolveOn turns an input into a URI within a named domain, the home of bare ids and @handles. It reuses the domain's own Classify parser, so it accepts every form that domain's CLI accepts.
func (*Host) Search ¶ added in v0.3.3
Search runs a domain's free-text search op for a query and returns the records it emits, each still the domain's own type (so a caller can Wrap or Mint the hits that are URI-addressable). limit caps the result (0 means the op's own default). It is the query counterpart to Get and List: where those dereference a name, Search discovers names from text.
func (*Host) Searchable ¶ added in v0.3.3
Searchable reports whether a domain (by scheme or alias) registered a free-text search op, so a host such as ant can decide to offer a search box.
func (*Host) Wrap ¶ added in v0.2.0
Wrap builds the Envelope for a record: it mints the record's URI, reads its link fields as URIs, and stamps the fetch time (zero time omits @fetched). Links are grouped by the record field they came from, so a consumer can tell a book's author edge from its similar-books edges.
type HostOption ¶ added in v0.2.0
type HostOption func(*hostConfig)
HostOption customizes a Host at Open.
func Tune ¶ added in v0.2.0
func Tune(scheme string, fn func(*Config)) HostOption
Tune overlays extra config onto one domain before its client is built, keyed by canonical scheme. It is how a host points a domain at a shared data dir or flips a domain-specific Extra setting without reaching into the driver.
func WithStore ¶ added in v0.2.0
func WithStore(st store.Store) HostOption
WithStore tees every dereferenced record into st, so a walk of the graph fills a local store as a side effect, exactly as a single-site read does with --db.
type Identity ¶
type Identity struct {
Binary string // binary and command name, e.g. "ccrawl"
Short string // one-line description
Long string // multi-paragraph description for help
Version string // semantic version, set by the build
Site string // the upstream site or service this CLI targets
Repo string // source repository URL
}
Identity is the fixed description of a CLI: its name, what it does, and where it lives. It seeds help text, the API title, the MCP server name, and the default env prefix.
type Input ¶
type Input struct {
Args []string // positional arguments in order
Flags map[string]any // named parameters, already typed where possible
Globals Globals // resolved framework globals
}
Input is the surface-neutral request a surface hands to Operation.Invoke. The CLI fills Args from positional tokens and Flags from parsed flags; the API fills them from the path and query; MCP fills Flags from the tool arguments object. Globals carries the resolved framework-global flags.
type OpMeta ¶
type OpMeta struct {
Name string // the verb: CLI subcommand, MCP tool suffix, route leaf
Parent string // optional parent command for a nested verb (e.g. "rank" for "rank domain")
Group string // grouping for help (e.g. "read", "data", "meta")
Summary string // one line, shown in help, OpenAPI summary, MCP description
Long string // optional multi-line help
Aliases []string // alternate names
Args []Arg // positional argument schema (names line up with In arg fields)
Write bool // a state-changing op; gated and annotated on every surface
Single bool // emits at most one record (no "no results" on empty stream)
// URI metadata (8000_uri, 8000_uri_drivers). These make an op addressable by
// resource URI in a multi-domain host such as ant. They are inert on a
// single-site binary, so a domain can adopt them with no behavior change.
URIType string // the URI authority this op dereferences, e.g. "status" for x's tweet; defaults to the lower-cased Out type name
Resolver bool // canonical dereferencer for URIType when several ops share it
List bool // member-lister for a parent resource: `ant ls` / feed:// resolve here
}
OpMeta is the surface-neutral description of one operation. The same metadata drives the CLI subcommand, the HTTP route, and the MCP tool.
type Operation ¶
type Operation interface {
Meta() OpMeta
Params() []ParamSpec
InputSchema() map[string]any
OutputSchema() map[string]any
// Invoke binds the surface-neutral Input to the typed In, runs the handler,
// and routes each emitted record to the sink, applying the store tee and the
// limit. rt carries the injected handles.
Invoke(ctx context.Context, in Input, rt RunContext, sink Sink) error
// OutType is the record type the op emits (struct, pointer stripped), or nil
// when the op emits no struct. A multi-domain host indexes ops by it so a
// resource URI's authority can select the op that mints that record type.
OutType() reflect.Type
}
Operation is what the registry stores and every surface drives. The concrete implementation is the generic op[In, Out] built by Handle.
type Option ¶
type Option func(*App)
Option customizes an App at construction.
func WithDefaults ¶
WithDefaults lets a domain overlay its own config defaults (rate, retries, workers, user agent) onto the framework baseline.
type OutputOptions ¶
type OutputOptions struct {
Format string
Fields []string
NoHeader bool
Template string
IsTTY bool
Color bool
Width int
}
OutputOptions are the resolved rendering settings an escape-hatch command reuses so its structured output matches every operation's: same --output format, --fields projection, --no-header, and --template.
type ParamSpec ¶
type ParamSpec struct {
Name string
Kind ParamKind
Type ParamType
Short string
Help string
Default string
Enum []string
Variadic bool
Inherit bool // bind to a framework-global flag of the same name
}
ParamSpec is the external description of one bound parameter, used to build CLI flags, query params, and JSON Schema properties.
type Resolver ¶ added in v0.2.0
type Resolver interface {
// Classify turns any accepted input — a bare id, an @handle, a messy https
// URL — into the canonical (uriType, id). A bare id with no type hint
// resolves to the domain's default type.
Classify(input string) (uriType, id string, err error)
// Locate is the inverse for one resource: the live https location for a
// (uriType, id).
Locate(uriType, id string) (url string, err error)
}
Resolver is the optional capability a Domain implements to support `ant resolve` and `ant url`. It is the home of the domain's existing idOrURL parser (Classify) and XxxURL helper (Locate); both are pure string functions, so the URI-native verbs touch no network. A Domain that omits Resolver is still fully addressable for inputs that are already canonical URIs.
type RunContext ¶
RunContext carries the injected handles an operation may receive: the domain client, the optional record store, and the resolved limit. A handler reaches these only through KindInject fields, never directly.
type Sink ¶
Sink is where an operation's records go. Each surface supplies its own: the CLI sink renders to the terminal, the API sink streams an HTTP response, the MCP sink accumulates structured tool content. A handler only ever calls emit(record); swapping the sink swaps the surface with no change to domain code.
type State ¶
type State struct {
Config Config
Globals Globals
Output OutputOptions // resolved rendering settings, for escape-hatch commands
// contains filtered or unexported fields
}
State is the per-run context kit resolves once and shares with every command, whether a registered operation or an escape-hatch command added with AddCommand. It carries the resolved config, the lazily built domain client, and the optional record store. An escape-hatch command reaches it with FromContext(cmd.Context()).
func FromContext ¶
FromContext returns the run State stored on the context, or nil if absent. An escape-hatch command calls this to reach the resolved config, client, and store that kit built for the run.
func (*State) Client ¶
Client builds the domain client on first use and caches it (and any error) for the rest of the run. It returns nil when the app registered no client factory.
type URI ¶ added in v0.2.0
type URI struct {
Scheme string
Authority string
Path []string
Query map[string]string
Fragment string
}
URI is a parsed resource URI (8000_uri §5.2): a name for a record, not a location. The scheme is a site slug ("goodreads") or a cross-site kind ("host", "pages", "feed", "search", "data"); for a site scheme the authority is the record type and the path is the id, while for host/pages the authority is a real hostname.
func ParseURI ¶ added in v0.2.0
ParseURI parses a canonical-shaped resource URI. It is deliberately strict: it does not normalize messy https URLs or bare ids (that is Host.Resolve's job, which reuses a domain's parser); it only reads an already-URI-shaped string into its parts. The scheme and authority are lower-cased; path segments keep their case, since some domains have case-sensitive ids.
func (URI) DataPath ¶ added in v0.2.0
DataPath is the on-disk path for this URI under the data root, without an extension: <scheme>/<authority>/<id...>. It is the single rule of 8000_uri §6.1 — the file path is the URI — so a tree of these is self-describing.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package errs defines the typed error taxonomy shared by every kit-based CLI and its one true mapping to CLI exit codes, HTTP status codes, and MCP error objects.
|
Package errs defines the typed error taxonomy shared by every kit-based CLI and its one true mapping to CLI exit codes, HTTP status codes, and MCP error objects. |
|
Package render turns a stream of record structs into one of the output formats the kit CLI supports: table, markdown, json, jsonl, csv, tsv, url, raw, and a Go text/template.
|
Package render turns a stream of record structs into one of the output formats the kit CLI supports: table, markdown, json, jsonl, csv, tsv, url, raw, and a Go text/template. |
|
Package store defines the pluggable record-store SPI that lets any kit read double as a crawl: with --db set, every emitted record is upserted into a local store before it reaches the output.
|
Package store defines the pluggable record-store SPI that lets any kit read double as a crawl: with --db set, every emitted record is upserted into a local store before it reaches the output. |
|
sqlitestore
Package sqlitestore is the built-in default store backend.
|
Package sqlitestore is the built-in default store backend. |