Help us shape the future of Go! Take the 2026 Go Developer Survey

module

package
v0.3.3 Latest Latest
Warning

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

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

README

core/module

How an AutoDoc feature offers verbs (ADR 1791719881). A feature's core package has a module.go that implements module.Module:

func (m *Manager) Name() string { return "todos" }

func (m *Manager) Verbs() []module.Verb {
	return []module.Verb{
		module.Handle(module.Contract{Verb: "todos.get", Since: 20, Audience: module.AudienceAgent,
			Result: "task", Errors: []int64{CodeNotFound}, Doc: "One task, with its rev and body."},
			m.get),
	}
}

func (m *Manager) Errors() []module.PublicError {
	return []module.PublicError{{Err: ErrNotFound, Code: CodeNotFound, Name: "todos.not_found",
		Message: "no such task", Next: "list the tasks again"}}
}
  • Params come from the handler's type. Handle[P, R] reads P's exported fields in order: param:"name" names one, param:"name,optional" makes a trailing one optional, doc:"…" documents it. A field may be string, bool, int/int64, []byte, []string, map[string]any, any, a struct decoded from a map by its json tags, or a type whose pointer implements Decoder.
  • Results are json-tagged values. The host carries them with Wire.
  • Errors carry their code once. The code is the wire identity. Name and Next appear in autodoc --contracts and AGENTS.md. A module's codes must sit in its range (codes.go).
  • Events. Contract.Event names the kind and the params holding the workspace and the detail. Verb.Events resolves them itself when they are inside a param or in the result.
  • No I/O in Name, Verbs or Errors. autodoc --contracts builds every Module with no dependencies, to list them without a daemon.

The host (rpc) resolves ScopeWorkspace and puts the workspace, the session's protocol and its client token in the handler's context: WorkspaceFrom, ProtocolFrom and ClientFrom.

Documentation

Overview

Package module is how an AutoDoc feature offers verbs: a Module declares each verb's contract and handler, and the public errors its verbs may answer. A host registers them — rpc for the daemon's socket, the TUI's script engine for Lua — and everything a client is told about a verb (its protocol, its params, the event it logs, the errors it answers, --contracts and AGENTS.md) is derived from the contract, so it is said once.

The package is data and context keys only: it depends on the standard library and golib's errs, so any core package may import it and no host is imported back.

Concurrency: Contracts, Verbs and PublicErrors are values, read concurrently once built. A Verb's Call is safe for concurrent use when the handler it wraps is.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidParams = errs.Sentinel(errs.ErrInvalidArgument, "module: invalid params")

ErrInvalidParams is a call whose params do not fit its contract. The host answers it as invalid params, with the ParamError's text: it names a param and a type, never a value.

Functions

func CheckCodes

func CheckCodes(m Module) error

CheckCodes reports a public error of m whose code is neither shared nor in m's range, or any unshared code when m has no range: the host refuses such a module at start.

func ClientFrom

func ClientFrom(ctx context.Context) string

ClientFrom is the caller's client token ("autodoc-tui#1a2b3c4d"); "" when no host set one.

func ProtocolFrom

func ProtocolFrom(ctx context.Context) int64

ProtocolFrom is the protocol the caller's session declared; 0 when no host set one.

func Shared

func Shared(code int64) bool

Shared reports whether code is one of the daemon's shared codes (-32060 to -32070: no such workspace, not found, conflict …), which any module may answer for the same condition, with the meaning rpc gives it.

func Wire

func Wire(v any) (any, error)

Wire is v as a host encodes it: the values msgpack and JSON both carry — nil, bool, integers, floats, string, []byte, []any and map[string]any. A struct becomes a map by its json tags (omitempty and "-" honoured), a time its RFC 3339 text. Anything else is an error: a handler's result type is a bug, never a client's.

func WithClient

func WithClient(ctx context.Context, token string) context.Context

WithClient is ctx carrying the caller's client token; only a host calls it.

func WithProtocol

func WithProtocol(ctx context.Context, p int64) context.Context

WithProtocol is ctx carrying the session's declared protocol; only a host calls it.

func WithWorkspace

func WithWorkspace(ctx context.Context, w Workspace) context.Context

WithWorkspace is ctx carrying the resolved workspace; only a host calls it.

Types

type Audience

type Audience int

Audience is who a verb is for: agents are told about it, and Lua binds every verb but the protocol's own.

const (
	// AudienceAgent is for agents and people's tools: --call, Lua, autodoc.nvim.
	AudienceAgent Audience = iota
	// AudienceUser is for people's tools and Lua, and not advertised to agents.
	AudienceUser
	// AudienceInternal is the protocol's own (sys.hello, sys.shutdown): never bound to Lua.
	AudienceInternal
)

func (Audience) String

func (a Audience) String() string

type Contract

type Contract struct {
	Verb     string     `json:"verb"`  // "todos.get"
	Since    int64      `json:"since"` // the protocol it arrived in; a session below it gets "unknown method"
	Scope    Scope      `json:"-"`
	Audience Audience   `json:"-"`
	Effect   Effect     `json:"-"`
	Params   []Param    `json:"params"`
	Result   string     `json:"result,omitempty"` // the result's shape, for people: "{tasks[], malformed[]}"
	Errors   []int64    `json:"errors,omitempty"` // the public codes it may answer, beyond invalid params
	Event    *EventSpec `json:"event,omitempty"`  // a success logs an event in sys.events; nil for none
	Doc      string     `json:"doc,omitempty"`
}

Contract is a verb as every surface sees it. It is pure data: --contracts prints it with no daemon running.

func (Contract) Check

func (c Contract) Check() error

Check reports what is wrong with c as a host would register it: no name, an optional param before a required one, or an event naming a param c does not have. A host refuses such a verb at start.

func (Contract) Required

func (c Contract) Required() int

Required is how many of the params a call must pass: those before the first optional one.

type Decoder

type Decoder interface {
	DecodeParam(v any) error
	ParamType() string
}

Decoder is a param type that decodes itself from its wire value: one param that may be a string or a map, say. ParamType is what its contract shows. The method set is the pointer's.

type Effect added in v0.1.49

type Effect int

Effect is what a verb does to the store: what a gated Lua script's capability must cover to call it (ADR 1792004705 §4.1). Every contract names one; EffectUnset is a contract that forgot.

const (
	// EffectUnset is no effect named: TestEveryContractHasAnEffect fails on it, and a gated script
	// treats it as EffectSettings.
	EffectUnset Effect = iota
	// EffectRead reads only: search, a document, an outline, a listing, a status.
	EffectRead
	// EffectWrite creates, changes or removes documents and tasks.
	EffectWrite
	// EffectSettings changes the daemon's own configuration: workspaces, models, rankers,
	// preferences, which store it writes.
	EffectSettings
)

func (Effect) String added in v0.1.49

func (e Effect) String() string

type Event

type Event struct{ Kind, Workspace, Detail string }

Event is one entry a verb's success logs.

type EventSpec

type EventSpec struct {
	Kind      string `json:"kind"`
	Workspace string `json:"workspace,omitempty"` // the param naming the workspace
	Detail    string `json:"detail,omitempty"`    // the param whose value is the detail
}

EventSpec is what a verb's success logs: the kind, and which params' values are the event's workspace and detail ("" for none).

type Module

type Module interface {
	Name() string
	Verbs() []Verb
	Errors() []PublicError
}

Module is one feature's verbs and errors. Name, Verbs and Errors do no I/O and work on a Module built with no dependencies, so a host can list them without a daemon.

type Param

type Param struct {
	Name     string `json:"name"`
	Type     string `json:"type"` // "string", "int", "bool", "bytes", "[]string", "map", "any", or a Decoder's own
	Optional bool   `json:"optional,omitempty"`
	Doc      string `json:"doc,omitempty"`
}

Param is one positional parameter, as AGENTS.md names it.

type ParamError

type ParamError struct {
	Verb, Param, Want string
}

ParamError is one param that does not fit.

func (*ParamError) Error

func (e *ParamError) Error() string

func (*ParamError) Unwrap

func (e *ParamError) Unwrap() error

type PublicError

type PublicError struct {
	Err     error  `json:"-"`
	Code    int64  `json:"code"`
	Name    string `json:"name"` // "todos.stale"
	Message string `json:"message"`
	Next    string `json:"next,omitempty"` // what the client does next
}

PublicError is an error a client may see. The code is its identity on the wire and the message is all of it that crosses; Name and Next are for people, in --contracts and AGENTS.md. errors.Is decides, and the first match in a module's list wins.

type Scope

type Scope int

Scope is what a verb's first param names, and so what the host resolves before the handler runs.

const (
	// ScopeGlobal names no workspace.
	ScopeGlobal Scope = iota
	// ScopeWorkspace takes a workspace name first; the host resolves it (WorkspaceFrom).
	ScopeWorkspace
	// ScopeLocalPeer is for a peer on the unix socket only: a path on the daemon's own disk.
	ScopeLocalPeer
)

func (Scope) String

func (s Scope) String() string

type Verb

type Verb struct {
	Contract
	Call func(ctx context.Context, params []any) (any, error)
	// Events, when set, are the events a success logs, in place of the one Event's params name: for
	// a verb whose workspace or detail is inside a param or in its result, or that logs several.
	Events func(ctx context.Context, params []any, result any) []Event
}

Verb is a Contract and its handler. params are the call's positional params as the wire decoded them; the result is what the host encodes (Wire).

func Handle

func Handle[P, R any](c Contract, fn func(context.Context, P) (R, error)) Verb

Handle makes a typed Verb. P is a struct whose exported fields, in order, are the positional params: a `param:"name"` tag names one (`param:"name,optional"` for a trailing optional one), a `doc:"…"` tag documents it, and its Go type gives its Param.Type. c.Params must be empty: Handle derives them, so the contract cannot drift from the decoder. A P that cannot be expressed panics, at registration.

func (Verb) EventsOf

func (v Verb) EventsOf(ctx context.Context, params []any, result any) []Event

EventsOf are the events a success of v with params and result logs: Events', or the one Event names; none when v logs none.

func (Verb) Logs

func (v Verb) Logs() bool

Logs reports whether a success of v logs anything.

type Workspace

type Workspace struct{ Name, Root string }

Workspace is the workspace a ScopeWorkspace verb named, as the host resolved it.

func WorkspaceFrom

func WorkspaceFrom(ctx context.Context) (Workspace, bool)

WorkspaceFrom is the workspace a ScopeWorkspace verb named; false for any other verb.

Jump to

Keyboard shortcuts

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