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

toolkit

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package toolkit holds the platform-agnostic building blocks an MCP server built on mcp-server-core shares: argument coercion, result constructors, the assertion algebra, protected-path guards, the evidence sink, the planner contract and the dependency-injection plumbing that puts a server's dependencies on the request context.

Tool handlers retrieve their dependencies from the request context (injected once at startup, or per request for an HTTP transport) via InjectDepsMiddleware and MustDepsFromContext, mirroring github-mcp-server's dependency-injection design. The dependency type is a server-specific interface — it embeds ToolDependencies and adds whatever platform engine the server drives — which is why the accessors are generic.

Index

Constants

View Source
const (
	SubjectScreenText         = "screen.text"
	SubjectWindowTitle        = "window.title"
	SubjectWindow             = "window"
	SubjectElement            = "element"
	SubjectElementName        = "element.name"
	SubjectElementValue       = "element.value"
	SubjectElementControlType = "element.control_type"
	SubjectElementEnabled     = "element.enabled"
	SubjectElementChecked     = "element.checked"
	SubjectElementSelected    = "element.selected"
	SubjectElementFocused     = "element.focused"
	SubjectElementCount       = "element.count"
	SubjectResultText         = "result.text"
)

Assertion subjects. The set is closed and matches the journey vocabulary.

View Source
const (
	OpIs             = "is"
	OpIsNot          = "is_not"
	OpContains       = "contains"
	OpDoesNotContain = "does_not_contain"
	OpStartsWith     = "starts_with"
	OpEndsWith       = "ends_with"
	OpMatches        = "matches"
	OpDoesNotMatch   = "does_not_match"
	OpIsEmpty        = "is_empty"
	OpIsNotEmpty     = "is_not_empty"
	OpIsOneOf        = "is_one_of"
	OpIsNotOneOf     = "is_not_one_of"
	OpIsTrue         = "is_true"
	OpIsFalse        = "is_false"
	OpExists         = "exists"
	OpDoesNotExist   = "does_not_exist"
	OpGreaterThan    = "greater_than"
	OpGreaterOrEqual = "greater_or_equal"
	OpLessThan       = "less_than"
	OpLessOrEqual    = "less_or_equal"
)

Assertion operators.

Variables

View Source
var (
	ErrScrapeScheme           = errors.New("only http and https are allowed")
	ErrScrapeNoHost           = errors.New("missing host")
	ErrScrapeLocalhost        = errors.New("localhost is not allowed")
	ErrScrapeForbiddenAddress = errors.New("address is not allowed")
	ErrScrapeNoAddresses      = errors.New("host resolves to no addresses")
	ErrScrapeTooManyRedirects = errors.New("too many redirects")
	ErrScrapeStatus           = errors.New("unexpected HTTP status")
)

Errors the Scrape tool reports. Static so a caller can match them.

AssertOperators is every operator the Assert tool evaluates, for its schema enum.

AssertSubjects is every subject the Assert tool evaluates, for its schema enum.

View Source
var ErrAssertionShape = fmt.Errorf("the assertion cannot be evaluated as written")

ErrAssertionShape reports an assertion that cannot be evaluated as written — an operator that does not apply to the subject, or a missing or mistyped expected value. It is distinct from a failed assertion: the first is a broken document, the second is a broken application.

View Source
var ErrDepsNotInContext = errors.New("tool dependencies not found in context; use ContextWithDeps to inject")

ErrDepsNotInContext is returned/panicked when dependencies are missing from the context.

View Source
var ErrPlaintextHTTP = errors.New("plaintext http:// is blocked by Enforce HTTPS")

ErrPlaintextHTTP is returned when Enforce HTTPS is on and a plaintext http:// target is requested.

Functions

func ApplyTool

func ApplyTool[D any](toolset inventory.ToolsetMetadata) inventory.ServerTool

ApplyTool builds the Apply tool for the given toolset. It executes a plan previously returned by Plan, by its id: it re-checks posture, then runs the steps in order, stopping at the first that fails or is refused. It is destructive: it performs the plan's actions.

func ArgsMap

func ArgsMap(req *mcp.CallToolRequest) (map[string]any, error)

ArgsMap unmarshals a tool call's raw arguments into a generic map. Tools that need the Python-parity coercions below (bool-or-string, list-or-string) use this rather than a typed struct, because some MCP clients (notably Claude Desktop) strip anyOf schemas and send booleans and arrays as JSON strings.

func ClampInt

func ClampInt(v, lo, hi int) int

ClampInt bounds v to the inclusive range [lo, hi]. It is how tools keep a caller-supplied count or window from becoming an absurd query.

func ContextWithDeps

func ContextWithDeps(ctx context.Context, deps any) context.Context

ContextWithDeps returns a copy of ctx carrying the given dependencies.

func DefaultNormalizePath

func DefaultNormalizePath(path string) string

DefaultNormalizePath is the platform-neutral normaliser: trimmed, cleaned and lower-cased. Servers on case-sensitive filesystems may still use it — it is merely over-protective there — but a server with platform aliases (extended prefixes, data streams, /private folds) must supply its own.

func DepsFromContext

func DepsFromContext[D any](ctx context.Context) (D, bool)

DepsFromContext retrieves the dependencies from ctx as D, reporting whether they were present and of that type.

func EnforceHTTPSScheme

func EnforceHTTPSScheme(u *url.URL, enforceHTTPS bool) error

EnforceHTTPSScheme rejects a plaintext http:// URL when Enforce HTTPS is on.

The scheme is compared case-insensitively because url.Parse preserves the case the caller wrote and "HTTP://example.com" is a valid, equivalent URL — a case-sensitive check would be trivially bypassable.

The message is written for the model rather than the operator: it says what to do next (retry over https) so the agent can self-correct instead of retrying the same blocked call.

func EvalAssertion

func EvalAssertion(operator string, obs Observation, expected any, opts CompareOptions) (bool, error)

EvalAssertion decides whether an observation satisfies operator/expected.

It returns an error only for an assertion that is malformed; a condition that simply does not hold returns (false, nil). An absent subject never satisfies anything except does_not_exist, and never errors — the control not having a toggle state is a fact about the application, which is what the run is testing.

func InjectDepsMiddleware

func InjectDepsMiddleware(deps any) mcp.Middleware

InjectDepsMiddleware returns MCP receiving middleware that injects the given dependencies into the context of every request, so tool handlers can read them via MustDepsFromContext instead of capturing them in closures.

func MustDepsFromContext

func MustDepsFromContext[D any](ctx context.Context) D

MustDepsFromContext retrieves the dependencies from ctx as D, panicking if absent. Use it in handlers where dependencies are required.

func NewTool

func NewTool[D any, In any, Out any](
	toolset inventory.ToolsetMetadata,
	tool mcp.Tool,
	handler func(ctx context.Context, deps D, req *mcp.CallToolRequest, args In) (*mcp.CallToolResult, Out, error),
) inventory.ServerTool

NewTool creates a ServerTool whose typed handler receives dependencies pulled from the request context. This avoids allocating a closure per tool at registration time. Ensure InjectDepsMiddleware is installed so deps are present when handlers run.

func NewToolFromHandler

func NewToolFromHandler[D any](
	toolset inventory.ToolsetMetadata,
	tool mcp.Tool,
	handler func(ctx context.Context, deps D, req *mcp.CallToolRequest) (*mcp.CallToolResult, error),
) inventory.ServerTool

NewToolFromHandler creates a ServerTool from a raw handler that receives dependencies from context. Use it when the handler needs the raw request rather than typed, pre-unmarshaled arguments.

func NewToolResultError

func NewToolResultError(text string) *mcp.CallToolResult

NewToolResultError returns a tool-level error result (IsError set). Per the MCP convention, expected/user-facing errors are returned this way — with a nil Go error — so the model can see the message and self-correct. Reserve a real Go error for infrastructure failures.

func NewToolResultErrorFromErr

func NewToolResultErrorFromErr(msg string, err error) *mcp.CallToolResult

NewToolResultErrorFromErr returns a tool-level error result combining a message and an underlying error.

func NewToolResultErrorf

func NewToolResultErrorf(format string, a ...any) *mcp.CallToolResult

NewToolResultErrorf is NewToolResultError with fmt formatting.

func NewToolResultImage

func NewToolResultImage(text string, pngData []byte, mimeType string) *mcp.CallToolResult

NewToolResultImage returns a successful tool result carrying a PNG (or other) image plus an optional leading text block. Pass empty text to omit it.

func NewToolResultText

func NewToolResultText(text string) *mcp.CallToolResult

NewToolResultText returns a successful tool result carrying a single text block.

func NewToolResultTextf

func NewToolResultTextf(format string, a ...any) *mcp.CallToolResult

NewToolResultTextf is NewToolResultText with fmt formatting.

func OptionalBool

func OptionalBool(args map[string]any, key string, fallback bool) bool

OptionalBool returns a bool argument or the fallback. It accepts real JSON booleans and the strings "true"/"false" (case-insensitive), matching how some MCP clients encode booleans.

func OptionalFloat

func OptionalFloat(args map[string]any, key string, fallback float64) (float64, error)

OptionalFloat returns a float argument or the fallback. It accepts JSON numbers and numeric strings, for the same reason OptionalInt does: some MCP clients stringify numbers.

Timeouts are fractional (a 0.4-second poll interval is the default), so they cannot go through OptionalInt without silently truncating to zero.

func OptionalInt

func OptionalInt(args map[string]any, key string, fallback int) (int, error)

OptionalInt returns an int argument or the fallback. It accepts JSON numbers and numeric strings.

func OptionalIntSlice

func OptionalIntSlice(args map[string]any, key string) ([]int, error)

OptionalIntSlice returns an []int argument. It accepts a JSON array of numbers or a JSON string containing such an array (e.g. "[10, 20]"), matching clients that stringify array parameters.

func OptionalString

func OptionalString(args map[string]any, key, fallback string) string

OptionalString returns a string argument or the fallback when absent.

func OptionalStringEnum

func OptionalStringEnum(args map[string]any, key, fallback string, allowed ...string) (string, error)

OptionalStringEnum returns a string argument constrained to allowed values, falling back when absent. It errors on a present-but-invalid value.

func PlanTool

func PlanTool[D any](toolset inventory.ToolsetMetadata) inventory.ServerTool

PlanTool builds the Plan tool for the given toolset. It proposes a sequence of tool calls for whole-plan adjudication and changes nothing: it validates the plan, evaluates the whole thing against current posture, and returns a change manifest and a plan id to apply.

D is the server's dependency interface; the handler only needs it to satisfy PlannerProvider, so any type works.

func RequiredString

func RequiredString(args map[string]any, key string) (string, error)

RequiredString returns a required string argument.

func ScrapeTool

func ScrapeTool[D ToolDependencies](toolset inventory.ToolsetMetadata, userAgent string) inventory.ServerTool

ScrapeTool builds the Scrape tool for the given toolset. It fetches a web page and extracts its readable text. userAgent names the server in the request; D is the server's dependency interface (it must satisfy ToolDependencies for the Enforce-HTTPS and egress-proxy settings).

func SubjectNeedsTarget

func SubjectNeedsTarget(subject string) bool

SubjectNeedsTarget reports whether a subject reads a particular element or window and therefore needs a selector.

func URLSchemeIfURL

func URLSchemeIfURL(s string) (scheme string, ok bool)

URLSchemeIfURL reports the lower-cased scheme when s is a URL with an explicit http or https scheme, and ok=false otherwise.

It exists because tools accept values that are *usually* not URLs — App's "name" is normally something like "textedit" — but which the platform will happily treat as one. launching a URL opens the default browser, so a URL-shaped app name is a navigation, and Enforce HTTPS has to see it.

Types

type AssertionRecord

type AssertionRecord struct {
	Subject  string
	Operator string
	Expected string
	Observed string
	Passed   bool
	// Polls is how many times the condition was evaluated: 1 when not waited. A
	// step that passed on its fifteenth poll of a fifteen-second budget is a
	// different fact from one that passed immediately, and it is the one that
	// predicts a suite about to become flaky.
	Polls   int
	Timeout float64
}

AssertionRecord is what an assertion actually did: the comparison it made and the value it read. It exists so a run record can carry the observed value — the thing a text log never carried, and the difference between knowing a test broke and knowing why.

type AssertionRegister

type AssertionRegister interface {
	RecordAssertion(AssertionRecord)
	LastAssertion() (AssertionRecord, bool)
}

AssertionRegister is the optional interface a dependency set implements to carry the most recent assertion's outcome.

It is a side channel rather than something on the tool result on purpose: the alternative is putting it in the result's structured content or _meta, which would change the Assert tool's wire output and put it under the protocol's schema obligations, for information the model already has in the text.

type BaseDeps

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

BaseDeps is the platform-agnostic half of a server's dependency set. A server embeds it (by pointer) in its own struct, adds the platform engine, and gets every shared capability — the registers, the evidence sink, the planner hook, the protected paths — for free.

func NewBaseDeps

func NewBaseDeps(logger *slog.Logger, featureChecker inventory.FeatureFlagChecker) *BaseDeps

NewBaseDeps constructs a BaseDeps.

func (*BaseDeps) CapturedEvidence

func (d *BaseDeps) CapturedEvidence() []EvidenceArtifact

CapturedEvidence implements EvidenceSink.

func (*BaseDeps) Credentials

func (d *BaseDeps) Credentials() []CredentialInfo

Credentials implements ToolDependencies.

func (*BaseDeps) EgressProxy

func (d *BaseDeps) EgressProxy() string

EgressProxy implements ToolDependencies.

func (*BaseDeps) EnforceHTTPS

func (d *BaseDeps) EnforceHTTPS() bool

EnforceHTTPS implements ToolDependencies.

func (*BaseDeps) IsFeatureEnabled

func (d *BaseDeps) IsFeatureEnabled(ctx context.Context, flagName string) bool

IsFeatureEnabled implements ToolDependencies.

func (*BaseDeps) LastAssertion

func (d *BaseDeps) LastAssertion() (AssertionRecord, bool)

LastAssertion implements AssertionRegister.

func (*BaseDeps) LastRead

func (d *BaseDeps) LastRead() (string, bool)

LastRead implements ReadRegister.

func (*BaseDeps) Logger

func (d *BaseDeps) Logger(_ context.Context) *slog.Logger

Logger implements ToolDependencies.

func (*BaseDeps) Planner

func (d *BaseDeps) Planner() Planner

Planner implements PlannerProvider. It returns nil when plan-and-apply is not wired, which the Plan/Apply tools treat as "planning not available".

func (*BaseDeps) ProtectedPathViolation

func (d *BaseDeps) ProtectedPathViolation(absPath string, write bool) (string, bool)

ProtectedPathViolation reports whether accessing absPath (for write when write is true, otherwise read) would touch a protected guardrail path, and a reason suitable for a tool error. It implements ProtectedPathChecker.

func (*BaseDeps) RecordAssertion

func (d *BaseDeps) RecordAssertion(r AssertionRecord)

RecordAssertion implements AssertionRegister.

func (*BaseDeps) SetLastRead

func (d *BaseDeps) SetLastRead(text string)

SetLastRead implements ReadRegister, recording what a read step returned.

func (*BaseDeps) WithCredentials

func (d *BaseDeps) WithCredentials(creds []CredentialInfo) *BaseDeps

WithCredentials records the credentials installed at init, so the Credentials tool can list what is available. Returns the receiver for chaining.

func (*BaseDeps) WithEgressProxy

func (d *BaseDeps) WithEgressProxy(addr string) *BaseDeps

WithEgressProxy records the loopback egress proxy address outbound HTTP must route through. Returns the receiver for chaining.

func (*BaseDeps) WithEnforceHTTPS

func (d *BaseDeps) WithEnforceHTTPS(on bool) *BaseDeps

WithEnforceHTTPS turns the Enforce HTTPS setting on for tools that reach a URL. Returns the receiver for chaining.

func (*BaseDeps) WithEvidenceDir

func (d *BaseDeps) WithEvidenceDir(dir string) *BaseDeps

WithEvidenceDir turns on screenshot persistence. Returns the receiver for chaining.

func (*BaseDeps) WithPathNormalizer

func (d *BaseDeps) WithPathNormalizer(n PathNormalizer) *BaseDeps

WithPathNormalizer sets the normaliser ProtectedPathViolation applies to the path it is asked about. It must be the same one the protected paths were built with. Returns the receiver for chaining.

func (*BaseDeps) WithPlanner

func (d *BaseDeps) WithPlanner(p Planner) *BaseDeps

WithPlanner wires the plan-and-apply engine, so the Plan and Apply tools can reach it. Returns the receiver for chaining.

func (*BaseDeps) WithProtectedPaths

func (d *BaseDeps) WithProtectedPaths(paths []ProtectedPath) *BaseDeps

WithProtectedPaths records the guardrail paths the file tool must not touch. Returns the receiver for chaining.

func (*BaseDeps) WriteEvidence

func (d *BaseDeps) WriteEvidence(label string, png []byte, width, height int) (EvidenceArtifact, bool, error)

WriteEvidence implements EvidenceSink.

type CompareOptions

type CompareOptions struct {
	IgnoreCase         bool
	Trim               bool
	CollapseWhitespace bool
}

CompareOptions are the text-comparison modifiers, all defaulting off so behaviour is never implicit. The behaviour they replace folded case for window titles and for nothing else, and said so nowhere.

type CredentialInfo

type CredentialInfo struct {
	Name     string `json:"name"`
	Target   string `json:"target"`
	Username string `json:"username,omitempty"`
	Type     string `json:"type"`
	Persist  string `json:"persist"`
	Present  bool   `json:"present"`
	// Injectable is false for credential classes the platform store will not
	// read back.
	Injectable bool `json:"injectable"`
	// AllowUnmaskedTarget lets this credential be injected into a control that
	// does not report itself as masked. It defaults to false, so injection
	// normally requires a confirmed password field. It is an operator decision,
	// declared per credential in the credentials document, because it trades the
	// never-read guarantee for reach into destinations that cannot report
	// themselves as secure text fields.
	AllowUnmaskedTarget bool `json:"allow_unmasked_target"`
}

CredentialInfo describes an installed credential without its secret. It is what the Credentials tool lists and what completion offers; there is no field that could carry a value, by construction.

type EvidenceArtifact

type EvidenceArtifact struct {
	// Label is the caption from the journey document. It is what expected_evidence
	// is matched against after a run.
	Label string
	// Path is relative to the evidence directory, and is also the path the artifact
	// takes inside an evidence bundle.
	Path   string
	SHA256 string
	Width  int
	Height int
}

EvidenceArtifact is one captured image on disk.

type EvidenceSink

type EvidenceSink interface {
	// WriteEvidence persists one capture and returns what was written. It reports
	// ok=false when no evidence directory is configured, which is not an error.
	WriteEvidence(label string, png []byte, width, height int) (EvidenceArtifact, bool, error)
	// CapturedEvidence returns everything written this run, in capture order.
	CapturedEvidence() []EvidenceArtifact
}

EvidenceSink is the optional interface a dependency set implements to persist captured evidence. It is an optional interface for the same reason ReadRegister is: adding to ToolDependencies would break every other implementation.

type Observation

type Observation struct {
	Kind   ValueKind
	Text   string
	Number float64
	Bool   bool
	Exists bool

	Absent bool
	// AbsentReason explains what was missing, and is what the failure reports.
	AbsentReason string
}

Observation is what was actually read from the desktop. Absent marks a subject that could not be read at all — a toggle state on a control that has none — so a failure can say that rather than reporting a misleading false.

func (Observation) Render

func (o Observation) Render() string

Render renders the observed value for a failure message and for the run record's journey.assertion.observed attribute. It is the thing a text log never carried: a failure that reports only the condition name says a test broke, one that reports what was on screen usually says why.

type PathNormalizer

type PathNormalizer func(path string) string

PathNormalizer renders a path in the one form protected-path matching compares, so the same file cannot be reached under a different spelling. Each platform supplies its own: the spellings a filesystem folds together are a property of that filesystem.

type PlanApplication

type PlanApplication struct {
	PlanID string
	Report string
	// Completed, Failed and Skipped count the steps by outcome. They let a caller —
	// the journey runner — decide pass/fail without parsing Report. A plan passes
	// cleanly when Failed and Skipped are both zero.
	Completed int
	Failed    int
	Skipped   int
}

PlanApplication is the result of applying a plan.

type PlanProposal

type PlanProposal struct {
	PlanID   string
	Allowed  bool
	Severity string
	Manifest string
}

PlanProposal is the result of proposing a plan.

type Planner

type Planner interface {
	// Propose validates and adjudicates a submitted plan document (raw JSON),
	// stores it under a content hash, and returns the change manifest and plan id.
	Propose(ctx context.Context, rawPlan []byte) (PlanProposal, error)
	// Apply executes a previously proposed plan by id, re-checking posture first
	// and stopping at the first step that fails or is refused.
	Apply(ctx context.Context, planID string) (PlanApplication, error)
}

Planner is the plan-and-apply engine: it adjudicates a whole proposed plan before any of it runs, and later executes an approved one. The runtime package implements it with the policy engine, the audit log and the tool registry; the Plan and Apply tools are thin wrappers, so plan-and-apply composes with the same middleware, toolset filtering and policy the rest of the surface does.

func PlannerFrom

func PlannerFrom(deps any) (Planner, bool)

PlannerFrom extracts the planner from a dependency set, reporting false when planning is not wired.

type PlannerProvider

type PlannerProvider interface {
	Planner() Planner
}

PlannerProvider is the optional capability a dependency set exposes when plan-and-apply is wired in. The Plan and Apply tools degrade to an error result when it is absent, so a dependency stand-in without a planner simply cannot plan.

type ProtectedPath

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

ProtectedPath marks a filesystem location a file tool must not touch, so the agent cannot use it to reach the guardrail state that governs it — read the credentials file back, or write over the audit log or the policy document. It is a guardrail, not a sandbox: matching is by normalised path, so a hard link still reaches the file under another name.

func NewProtectedPath

func NewProtectedPath(normalize PathNormalizer, path, label string, tree, denyRead, denyWrite bool) ProtectedPath

NewProtectedPath builds a ProtectedPath, normalising the path for matching.

func (ProtectedPath) Covers

func (p ProtectedPath) Covers(target string) bool

Covers reports whether target (already normalised) falls under this protected path: exact match, or anywhere below it when it protects a tree.

func (ProtectedPath) Label

func (p ProtectedPath) Label() string

Label is the human name used in refusal messages.

type ProtectedPathChecker

type ProtectedPathChecker interface {
	ProtectedPathViolation(absPath string, write bool) (reason string, violated bool)
}

ProtectedPathChecker is the optional interface a dependency set implements when it carries protected paths. File tools check for it.

type ReadRegister

type ReadRegister interface {
	LastRead() (string, bool)
	SetLastRead(text string)
}

ReadRegister is the optional interface a dependency set implements to carry the run-scoped result register: what the most recent read returned, which a result.text assertion compares against.

It is an optional interface rather than a method on ToolDependencies for the reason ProtectedPathViolation is: adding to the interface would break every other implementation, including the fakes the tool tests are built on.

The register is supplied to an assertion as *environment*. It is deliberately never spliced into the assertion's arguments: a plan runs verbatim from the stored, approved document and its argument digest is what the audit chain records, so rewriting arguments at execution time would break both.

type ToolDependencies

type ToolDependencies interface {
	// Logger returns the structured logger, optionally enriched with
	// request-scoped fields from ctx.
	Logger(ctx context.Context) *slog.Logger

	// IsFeatureEnabled reports whether a named feature flag is enabled.
	IsFeatureEnabled(ctx context.Context, flagName string) bool

	// Credentials returns the non-secret registry of credentials installed at
	// init: names, targets, usernames, and classes. It deliberately cannot expose
	// a secret — the plaintext never leaves the platform engine, so no tool
	// handler is able to return one.
	Credentials() []CredentialInfo

	// EnforceHTTPS reports whether the Enforce HTTPS setting is on. Tools that
	// fetch or navigate to a URL must refuse plaintext http:// when it is.
	EnforceHTTPS() bool

	// EgressProxy returns the loopback egress proxy address ("host:port") this
	// session's outbound HTTP must route through, or "" when no proxy is
	// provisioned. Tools that fetch a URL honor it, so the server's own
	// reaching-out is governed by the same allowlist as everything else's.
	EgressProxy() string
}

ToolDependencies is the platform-agnostic surface every server's dependency set provides. A server declares its own interface embedding this one and adding its engine accessor, so handlers written against the server's type still satisfy everything the shared runtime needs.

type ValueKind

type ValueKind string

ValueKind is the type of value a subject reads.

const (
	KindText      ValueKind = "text"
	KindNumber    ValueKind = "number"
	KindBoolean   ValueKind = "boolean"
	KindExistence ValueKind = "existence"
)

func SubjectKind

func SubjectKind(subject string) (ValueKind, bool)

SubjectKind returns the value type a subject reads, and whether the subject is one this build evaluates.

Jump to

Keyboard shortcuts

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