smplkit

package module
v3.0.155 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: MIT Imports: 33 Imported by: 0

README

smplkit Go SDK

Go Reference Build Coverage License Docs

The official Go SDK for smplkit — simple application infrastructure that just works.

Installation

go get github.com/smplkit/go-sdk/v3

Requirements

  • Go 1.24+

Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    smplkit "github.com/smplkit/go-sdk/v3"
)

func main() {
    ctx := context.Background()

    // APIKey, Environment, Service may also come from SMPLKIT_* env vars
    // or ~/.smplkit; explicit Config fields take precedence.
    client, err := smplkit.NewClient(smplkit.Config{
        APIKey:      "sk_api_...",
        Environment: "production",
        Service:     "my-service",
    })
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    // ── Runtime: resolve config values ──────────────────────────────────
    // Get returns a LiveConfig proxy; reads always reflect the latest
    // values pushed by the WebSocket.
    cfg, err := client.Config().Get(ctx, "user_service")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(cfg.Value()["timeout"])

    // Or unmarshal directly into a typed struct.
    type ServiceConfig struct {
        Timeout int `json:"timeout"`
        Retries int `json:"retries"`
    }
    var sc ServiceConfig
    if err := client.Config().GetInto(ctx, "user_service", &sc); err != nil {
        log.Fatal(err)
    }
    fmt.Println(sc.Timeout)

    // ── Management: CRUD operations ──────────────────────────────────────
    mgmt := client.Manage().Config()

    configs, err := mgmt.List(ctx)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(len(configs))

    fetched, err := mgmt.Get(ctx, "user_service")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(fetched.ID)

    newConfig := mgmt.New("my_service", smplkit.WithConfigName("My Service"))
    newConfig.SetNumber("timeout", 30, "")
    newConfig.SetNumber("retries", 3, "")
    if err := newConfig.Save(ctx); err != nil {
        log.Fatal(err)
    }

    if err := mgmt.Delete(ctx, "my_service"); err != nil {
        log.Fatal(err)
    }
}

client.Manage() exposes the eight management namespaces (Config(), Flags(), Loggers(), LogGroups(), Contexts(), ContextTypes(), Environments(), AccountSettings()). For setup scripts and CI jobs that don't need the runtime, construct a management-only client with no side effects via smplkit.NewManagementClient(smplkit.ManagementConfig{...}).

Configuration

All settings are resolved from four sources, in order of precedence:

  1. Constructor arguments — explicit Config fields, highest priority.
  2. Environment variables — e.g. SMPLKIT_API_KEY, SMPLKIT_ENVIRONMENT.
  3. Configuration file (~/.smplkit) — INI-format with profile support.
  4. Defaults — built-in SDK defaults.
Configuration File

The ~/.smplkit file supports a [common] section (applied to all profiles) and named profiles:

[common]
environment = production
service = my-app

[default]
api_key = sk_api_abc123

[local]
base_domain = localhost
scheme = http
api_key = sk_api_local_xyz
environment = development
debug = true
Constructor Examples
// Use a named profile
client, err := smplkit.NewClient(smplkit.Config{Profile: "local"})

// Or configure explicitly
client, err := smplkit.NewClient(smplkit.Config{
    APIKey:      "sk_api_...",
    Environment: "production",
    Service:     "my-service",
})

For the complete configuration reference, see the Configuration Guide.

Error Handling

All SDK errors extend *smplkit.Error and support errors.Is() / errors.As():

import "errors"

cfg, err := client.Manage().Config().Get(ctx, "nonexistent")
if err != nil {
    var notFound *smplkit.NotFoundError
    if errors.As(err, &notFound) {
        fmt.Println("Not found:", notFound.Base.Message)
    } else {
        fmt.Println("Error:", err)
    }
}
Error Cause
NotFoundError HTTP 404 — resource not found
ConflictError HTTP 409 — conflict
ValidationError HTTP 422 — validation error
TimeoutError Request timed out
ConnectionError Network connectivity issue
Error Any other SDK error

Smpl-prefixed aliases (SmplError, SmplNotFoundError, etc.) exist for cross-SDK familiarity but the unprefixed names are canonical.

Feature Flags

Full management + runtime client with real-time WebSocket updates and a typed-handle evaluation API.

Management API
ctx := context.Background()
mgmt := client.Manage().Flags()

// Create a flag using typed factories
flag := mgmt.NewBooleanFlag("checkout-v2", false,
    smplkit.WithFlagName("Checkout V2"),
    smplkit.WithFlagDescription("Controls rollout of the new checkout experience."),
)
if err := flag.Save(ctx); err != nil {
    log.Fatal(err)
}

// Per-environment defaults and rules — env="" targets the base default,
// non-empty scopes to that environment.
flag.SetDefault(true, "staging")
if err := flag.AddRule(smplkit.NewRule("Enable for enterprise").
    Environment("staging").
    When("user.plan", "==", "enterprise").
    Serve(true).
    Build()); err != nil {
    log.Fatal(err)
}
if err := flag.Save(ctx); err != nil {
    log.Fatal(err)
}

// List / get / delete
allFlags, _ := mgmt.List(ctx)
fetched, _ := mgmt.Get(ctx, "checkout-v2")
_ = allFlags
_ = fetched
_ = mgmt.Delete(ctx, "checkout-v2")
Runtime Evaluation
flags := client.Flags()

// Typed flag handles (no Connect step — runtime initializes lazily on
// first Get and opens the live-updates WebSocket in the background).
checkout := flags.BooleanFlag("checkout-v2", false)
banner   := flags.StringFlag("banner-color", "red")
retries  := flags.NumberFlag("max-retries", 3)

// Ambient context: a provider runs on every evaluation that doesn't
// pass an explicit context.
flags.SetContextProvider(func(ctx context.Context) []smplkit.Context {
    return []smplkit.Context{
        smplkit.NewContext("user", "user-42", map[string]interface{}{
            "plan": "enterprise",
        }),
    }
})

// Evaluate — uses provider context, caches results.
isV2 := checkout.Get(ctx)            // true (rule matched)
color := banner.Get(ctx)             // "blue"
maxR := retries.Get(ctx)             // 5
_ = color
_ = maxR

// Per-call context override.
basicUser := smplkit.NewContext("user", "u-1", map[string]interface{}{"plan": "free"})
isV2 = checkout.Get(ctx, basicUser)  // false

// Live-update listeners.
flags.OnChange(func(evt *smplkit.FlagChangeEvent) {
    fmt.Println("flag changed:", evt.ID)
})
checkout.OnChange(func(evt *smplkit.FlagChangeEvent) {
    fmt.Println("checkout-v2 specifically changed")
})

// Manual re-fetch (bypasses the WebSocket — useful in short-lived scripts).
if err := flags.Refresh(ctx); err != nil {
    log.Fatal(err)
}

// Cache stats.
stats := flags.Stats()
fmt.Printf("hits=%d misses=%d\n", stats.CacheHits, stats.CacheMisses)

// Cleanup is handled by client.Close(); call flags.Disconnect(ctx) to
// stop the runtime sub-client without tearing down the rest.

If you need on-change listeners to receive events for writes that happen immediately after construction (e.g. in showcases or tests), call client.WaitUntilReady(ctx, 0) once after NewClient to block until the WebSocket subscription has been registered server-side.

Flag Types
Constant Value
FlagTypeBoolean "BOOLEAN"
FlagTypeString "STRING"
FlagTypeNumeric "NUMERIC"
FlagTypeJSON "JSON"

Logging

Centrally manage log levels per service+environment from the smplkit platform; the SDK pushes resolved levels onto whichever logging framework you wrap.

Adapters

The SDK ships two adapters as separate Go modules so you only pay for the framework you use:

  • github.com/smplkit/go-sdk/logging/adapters/slog — Go's standard log/slog.
  • github.com/smplkit/go-sdk/logging/adapters/zapgo.uber.org/zap.
go get github.com/smplkit/go-sdk/logging/adapters/slog
Runtime: slog
import (
    "log/slog"

    smplkit "github.com/smplkit/go-sdk/v3"
    slogadapter "github.com/smplkit/go-sdk/logging/adapters/slog"
)

adapter := slogadapter.New()

// Wrap and replace the global slog default. Every package that uses
// slog.Info / slog.Warn / slog.Error / slog.Debug now routes through
// the SDK's level-controlled wrapper. Use WrapHandler explicitly if
// you want to keep your own slog.NewJSONHandler / custom destination.
adapter.InstallDefault()

client.Logging().RegisterAdapter(adapter)
if err := client.Logging().Install(ctx); err != nil {
    log.Fatal(err)
}

// Force a re-fetch of managed levels without waiting for the WebSocket.
if err := client.Logging().Refresh(ctx); err != nil {
    log.Fatal(err)
}

// Listen for level changes from the platform.
client.Logging().OnChange(func(evt *smplkit.LoggerChangeEvent) {
    fmt.Println("logger changed:", evt.ID, "level:", evt.Level, "source:", evt.Source)
})

Why InstallDefault replaces (rather than wraps) the existing default: Go's log/slog has no global registry of loggers, so the SDK can only manage handlers it sits in front of. Wrapping slog.Default()'s pre-existing handler causes a recursion deadlock through log.Default(); installing a fresh TextHandler to stderr avoids the cycle. To attach smplkit control to a non-default handler, use adapter.WrapHandler(yourHandler) and call slog.SetDefault yourself.

Runtime: zap
import (
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"

    zapadapter "github.com/smplkit/go-sdk/logging/adapters/zap"
)

adapter := zapadapter.New()
core := adapter.WrapCore(zapcore.NewCore(
    zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
    zapcore.AddSync(os.Stderr),
    zapcore.DebugLevel,
))
logger := zap.New(core)

client.Logging().RegisterAdapter(adapter)
_ = client.Logging().Install(ctx)
logger.Info("hello from zap")
Management API
mgmt := client.Manage().Loggers()

// Create or update a logger entry on the platform. PUT is upsert.
logger := mgmt.New("acme.app")
logger.SetLevel(smplkit.LogLevelInfo, "")          // base level
logger.SetLevel(smplkit.LogLevelDebug, "staging")  // env override
if err := logger.Save(ctx); err != nil {
    log.Fatal(err)
}

// Read paths.
fetched, _ := mgmt.Get(ctx, "acme.app")
all, _    := mgmt.List(ctx)
_ = fetched
_ = all

// Force the discovery buffer to send any pending registrations now
// (the runtime drains it on a 5s ticker by default).
if err := mgmt.Flush(ctx); err != nil {
    log.Fatal(err)
}

// Log groups have their own namespace; see client.Manage().LogGroups().
groups := client.Manage().LogGroups()
group := groups.New("infra", smplkit.WithLogGroupName("Infra"))
group.SetLevel(smplkit.LogLevelWarn)
if err := group.Save(ctx); err != nil {
    log.Fatal(err)
}
Log Levels
Constant Value
LogLevelTrace "TRACE"
LogLevelDebug "DEBUG"
LogLevelInfo "INFO"
LogLevelWarn "WARN"
LogLevelError "ERROR"
LogLevelFatal "FATAL"
LogLevelSilent "SILENT"

Debug Logging

Set SMPLKIT_DEBUG=1 to enable verbose diagnostic output to stderr. This is useful for troubleshooting real-time level changes, WebSocket connectivity, and SDK initialization. Debug output bypasses the managed logging framework and writes directly to stderr.

SMPLKIT_DEBUG=1 ./my-app

Accepted values: 1, true, yes (case-insensitive). Any other value (or unset) disables debug output.

Documentation

License

MIT

Documentation

Overview

Package smplkit — Smpl Jobs SDK client (client.Jobs() on SmplClient, or standalone JobsClient).

Smpl Jobs runs an HTTP call — on a schedule (a 5-field cron expression, a one-off datetime, or "now") or on demand (a manual job with no schedule) — and records the history of each fire: the request sent, the response received, timing, and outcome. It is reachable two ways:

client.Jobs().* on SmplClient
directly — NewJobsClient(...) — for callers that only need jobs.

A Job is an active record: build it with JobsClient.NewRecurringJob, NewManualJob, or Schedule, set fields, and call Save(ctx) (create when new, full-replace update when it already exists) or Delete(ctx). Runs are read-only views; run actions live on client.Jobs().Runs().

Package smplkit provides a Go client for the smplkit platform.

Quick start:

client, err := smplkit.NewClient(smplkit.Config{
    APIKey:      "sk_api_...",
    Environment: "production",
    Service:     "my-service",
})
cfg, err := client.Config().Get(ctx, "my-service")
if err != nil {
    var notFound *smplkit.NotFoundError
    if errors.As(err, &notFound) {
        // handle not found
    }
    return err
}
fmt.Println(cfg.Name)

Index

Constants

View Source
const (
	JobHttpMethodDelete = JobHttpMethod("DELETE")
	JobHttpMethodGet    = JobHttpMethod("GET")
	JobHttpMethodPatch  = JobHttpMethod("PATCH")
	JobHttpMethodPost   = JobHttpMethod("POST")
	JobHttpMethodPut    = JobHttpMethod("PUT")
)

Supported JobHttpMethod values, alphabetical.

View Source
const (
	JobKindManual    = JobKind("manual")
	JobKindOneOff    = JobKind("one_off")
	JobKindRecurring = JobKind("recurring")
)

JobKind values.

View Source
const (
	RunTriggerManual   = RunTrigger("MANUAL")
	RunTriggerRerun    = RunTrigger("RERUN")
	RunTriggerRetry    = RunTrigger("RETRY")
	RunTriggerSchedule = RunTrigger("SCHEDULE")
)

RunTrigger values.

View Source
const (
	BackoffExponential = Backoff("exponential")
	BackoffFixed       = Backoff("fixed")
)

Backoff values.

Variables

ForwarderTypes enumerates every supported ForwarderType value. Useful for `<select>`-style menus or membership checks on free-form input.

HttpMethods enumerates every supported HttpMethod value.

Functions

func NormalizeLoggerName

func NormalizeLoggerName(name string) string

NormalizeLoggerName normalizes a logger name.

  • Replace "/" with "."
  • Replace ":" with "."
  • Lowercase everything

Types

type AccountClient added in v3.0.126

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

AccountClient is the Smpl Account client.

Exposes the authenticated account's own configuration, reachable as client.Account() (SmplClient) or constructed directly:

account, err := smplkit.NewAccountClient(smplkit.Config{APIKey: "sk_..."})
settings, err := account.Settings().Get(ctx)
settings.SetEnvironmentOrder([]string{"production", "staging"})
settings.Save(ctx)

Sub-client: Settings (get/save). Pure CRUD — no Install required.

func NewAccountClient added in v3.0.126

func NewAccountClient(cfg Config, opts ...ClientOption) (*AccountClient, error)

NewAccountClient creates a standalone Smpl Account client that resolves and owns its own app transport.

func (*AccountClient) Close added in v3.0.126

func (a *AccountClient) Close() error

Close is a no-op — the underlying http.Client is pooled by net/http. Kept for interface symmetry and a clean defer point.

func (*AccountClient) Settings added in v3.0.126

func (a *AccountClient) Settings() *SettingsClient

Settings returns the sub-client for account settings get/save.

type AccountSettings

type AccountSettings struct {
	// Raw is the full settings map. Mutations here are persisted on Save.
	Raw map[string]interface{}
	// contains filtered or unexported fields
}

AccountSettings holds per-account configuration. The wire format is an opaque JSON object; documented keys are exposed as typed accessors, and all keys (known and unknown) are preserved in Raw. Mutate via the setters and call Save(ctx) to persist.

func (*AccountSettings) EnvironmentOrder

func (s *AccountSettings) EnvironmentOrder() []string

EnvironmentOrder returns the canonical ordering of STANDARD environments, or nil when no order has been set.

func (*AccountSettings) Save

func (s *AccountSettings) Save(ctx context.Context) error

Save writes the full settings object back to the server.

func (*AccountSettings) SetEnvironmentOrder

func (s *AccountSettings) SetEnvironmentOrder(order []string)

SetEnvironmentOrder sets the canonical ordering of STANDARD environments. order is the environment identifiers in the desired order. Call Save(ctx) to persist.

type ApiErrorDetail

type ApiErrorDetail struct {
	// Status is the HTTP status code as a string (e.g. "404").
	Status string `json:"status,omitempty"`
	// Code is an application-specific machine-readable error code (e.g.
	// "environment_unmanaged"). Per JSON:API §7, smplkit sets this on
	// every error so callers can branch without string-matching the
	// human Detail field.
	Code string `json:"code,omitempty"`
	// Title is a short, human-readable summary (e.g. "Not Found").
	Title string `json:"title,omitempty"`
	// Detail is a longer, human-readable explanation specific to this
	// occurrence.
	Detail string `json:"detail,omitempty"`
	// Source identifies the source of the error within the request.
	Source ErrorSource `json:"source,omitempty"`
	// Meta carries additional structured context (e.g.
	// {"environment": "staging"}). The value types are JSON-decoded
	// natively (string, float64, bool, []any, map[string]any, nil).
	Meta map[string]any `json:"meta,omitempty"`
}

ApiErrorDetail holds a single JSON:API error object as surfaced by the smplkit platform's JSON:API responses.

type AuditCategories added in v3.0.126

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

AuditCategories lists the distinct category values seen in the account.

environment is the SDK's configured runtime environment (empty when unset); it scopes the listing as the default filter[environment] (ADR-055).

func (*AuditCategories) List added in v3.0.126

List returns one page of distinct category values seen in the account.

Response time is independent of how many years of events the account has accumulated. Sorted alphabetically; offset pagination via PageNumber / PageSize.

type AuditCategory added in v3.0.126

type AuditCategory struct {
	// ID is the category value, surfaced as the JSON:API resource id.
	ID string
	// Category is the same value as ID; provided for readability.
	Category string
	// CreatedAt is the earliest sighting of this category for the account.
	CreatedAt time.Time
}

AuditCategory is a distinct category value seen for the account.

Same shape as AuditResourceType and AuditEventType — ID and Category are the same value, surfaced as the JSON:API resource id. The duplication keeps SDK consumers from having to dig into the ID field when populating filter UI controls; pick whichever name reads better in context.

type AuditClient added in v3.0.10

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

AuditClient is the Smpl Audit client.

Audit installs no in-process machinery, so a single client exposes the full surface — event recording and reads, distinct-value discovery, and SIEM forwarder CRUD — reachable as client.Audit() or constructed directly via NewAuditClient.

Namespaces: Events (Record/Flush/List/Get), ResourceTypes, EventTypes, Categories (discovery), and Forwarders (CRUD).

func NewAuditClient added in v3.0.126

func NewAuditClient(cfg Config, opts ...ClientOption) (*AuditClient, error)

NewAuditClient builds a standalone Smpl Audit client.

Audit installs no in-process machinery, so a single client exposes the full surface — event recording and reads, distinct-value discovery, and SIEM forwarder CRUD.

Environment scoping is body-driven (ADR-055): cfg.Environment is stamped onto the event request body when recording and supplied as the default filter[environment] on the read / discovery surfaces (Events.List, ResourceTypes, EventTypes, Categories). It no longer rides on a request header, so a single transport backs the whole surface, forwarder CRUD included. Config is resolved from cfg merged with SMPLKIT_* environment variables and the ~/.smplkit profile.

Call Close when done to release the underlying HTTP resources and drain the in-memory event buffer.

func (*AuditClient) Categories added in v3.0.126

func (a *AuditClient) Categories() *AuditCategories

Categories returns the categories index sub-client.

func (*AuditClient) Close added in v3.0.126

func (a *AuditClient) Close() error

Close drains the in-memory event buffer, blocking until it empties or the drain times out. Call it when done with a standalone AuditClient (one built via NewAuditClient) so buffered fire-and-forget events are delivered before the process exits. When the audit surface was wired in by a top-level Client, SmplClient.Close drives this.

func (*AuditClient) EventTypes added in v3.0.69

func (a *AuditClient) EventTypes() *AuditEventTypes

EventTypes returns the event-types index sub-client.

func (*AuditClient) Events added in v3.0.10

func (a *AuditClient) Events() *AuditEvents

Events returns the events sub-client.

func (*AuditClient) Forwarders added in v3.0.16

func (a *AuditClient) Forwarders() *AuditForwarders

Forwarders returns the SIEM forwarder CRUD sub-client.

func (*AuditClient) ResourceTypes added in v3.0.34

func (a *AuditClient) ResourceTypes() *AuditResourceTypes

ResourceTypes returns the resource-types index sub-client.

type AuditEvent added in v3.0.10

type AuditEvent struct {
	// ID is the server-assigned UUID for this event.
	ID uuid.UUID
	// EventType is the event type slug — e.g. "user.created", "invoice.paid".
	EventType string
	// ResourceType is the type of resource the event operated on — e.g. "invoice".
	ResourceType string
	// ResourceID is the customer-facing id of the resource the event operated on.
	ResourceID string
	// OccurredAt is when the event actually happened, as reported by the source.
	OccurredAt time.Time
	// CreatedAt is when the audit service first ingested this event.
	CreatedAt time.Time
	// ActorType is a free-form label for the kind of actor that caused
	// the event (e.g. "USER", "API_KEY", "SYSTEM", or any custom value).
	// Empty when the caller did not supply one; the audit service never
	// backfills from the request credential.
	ActorType string
	// ActorID is the actor identifier. Free-form — any string scheme
	// is accepted; non-UUID values round-trip verbatim. Empty when not
	// supplied.
	ActorID string
	// ActorLabel is a human-readable label for the actor (e.g. an email
	// address or API key name). Empty when not supplied.
	ActorLabel string
	// Category is a free-form bucket label for the event (e.g. "auth",
	// "billing", "config-change"). Stored exactly as supplied; drives the
	// audit log's category filter and the categories discovery listing
	// (client.Audit().Categories()). Empty when not supplied.
	Category string
	// Data is the free-form per-event payload defined by the customer.
	Data map[string]interface{}
	// IdempotencyKey is the customer-supplied dedupe key. Empty when
	// the customer didn't supply one.
	IdempotencyKey string
	// DoNotForward, when true, skips this event from SIEM forwarder
	// delivery regardless of any matching forwarder filter.
	DoNotForward bool
	// Environment is the environment the event was recorded in. Read-only
	// and always present on reads — the audit service resolves it when the
	// event is recorded, either from a single-environment credential or from
	// the environment the SDK stamps onto the recording request body (the
	// runtime SDK's configured environment, when set).
	Environment string
}

AuditEvent represents an audit event returned by the audit service.

The SDK exposes flat-named fields rather than the nested JSON:API attribute object — the wrapper takes care of the envelope on both create and read.

type AuditEventType added in v3.0.69

type AuditEventType struct {
	// ID is the event type slug (e.g. "invoice.created").
	ID string
	// EventType is the same slug as ID; both fields are populated for clarity.
	EventType string
	// CreatedAt is the earliest sighting of this event_type for the account.
	// When the parent List call filtered by ResourceType, this is the first
	// sighting of that specific (event_type, resource_type) pair rather than
	// the event_type overall.
	CreatedAt time.Time
}

AuditEventType is one row from the event-types index.

type AuditEventTypes added in v3.0.69

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

AuditEventTypes lists the distinct event type slugs seen in the account.

environment is the SDK's configured runtime environment (empty when unset); it scopes the listing as the default filter[environment] (ADR-055).

func (*AuditEventTypes) List added in v3.0.69

List returns one page of distinct event type slugs seen in the account.

Without FilterResourceType, returns one row per distinct event type. With the filter, returns only the event types seen with that specific resource type. Sorted alphabetically; offset pagination via PageNumber / PageSize.

type AuditEvents added in v3.0.10

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

AuditEvents handles event recording, listing, and retrieval. Writes are fire-and-forget by default and return as soon as the event is enqueued onto the in-process buffer.

environment is the SDK's configured runtime environment (empty when unset). It is stamped onto the event request body when recording and supplied as the default filter[environment] on List (ADR-055).

func (*AuditEvents) Flush added in v3.0.10

func (e *AuditEvents) Flush(timeout time.Duration)

Flush blocks until the in-memory event buffer is drained or the timeout elapses. Useful for shutdown semantics in short-lived processes that don't always reach SmplClient.Close.

func (*AuditEvents) Get added in v3.0.10

func (e *AuditEvents) Get(ctx context.Context, eventID uuid.UUID) (*AuditEvent, error)

Get retrieves a single audit event by id.

Returns a *NotFoundError if no event with that id exists in the caller's account.

func (*AuditEvents) List added in v3.0.10

List returns one page of audit events scoped to the caller's account.

Filters are exact-match except OccurredAtRange which uses the platform's range syntax (e.g. "[2026-01-01T00:00:00Z,*)"). Pass the previous page's NextCursor as PageAfter to walk subsequent pages.

func (*AuditEvents) Record added in v3.0.13

func (e *AuditEvents) Record(input CreateEventInput) error

Record enqueues an audit event for delivery.

By default it returns nil immediately and the buffer worker handles the actual POST, retrying on transient failures. Set input.Flush to block until the event has drained (or input.FlushTimeout elapses) before returning — useful when the caller needs the event durable before continuing. ResourceType beginning with "smpl." is rejected by the server with 403 — that namespace is reserved for smplkit-emitted events.

type AuditForwarders added in v3.0.16

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

AuditForwarders manages SIEM streaming destinations for the authenticated account. Accessed via client.Audit().Forwarders().

Forwarder CRUD is part of the single unified audit surface. It is account-wide and not environment-scoped; per-environment enablement lives in each forwarder's Environments map.

func (*AuditForwarders) Delete added in v3.0.16

func (f *AuditForwarders) Delete(ctx context.Context, forwarderID string) error

Delete removes a forwarder by id.

func (*AuditForwarders) Get added in v3.0.16

func (f *AuditForwarders) Get(ctx context.Context, forwarderID string) (*Forwarder, error)

Get returns one forwarder by id; returned instance is bound to this client so forwarder.Save(ctx) and forwarder.Delete(ctx) work.

func (*AuditForwarders) List added in v3.0.16

List returns one page of forwarders. Offset pagination via PageNumber / PageSize.

func (*AuditForwarders) New added in v3.0.52

func (f *AuditForwarders) New(
	id string,
	name string,
	forwarderType ForwarderType,
	configuration HttpConfiguration,
	opts ...ForwarderOption,
) *Forwarder

New returns an unsaved Forwarder bound to this client. Call (*Forwarder).Save(ctx) to persist.

id is the caller-supplied forwarder key — required at create time (the audit service does not auto-generate it). It is unique within the account and immutable for the lifetime of the forwarder; the audit service returns 409 if another live forwarder already uses it. Use a stable, human-readable identifier (e.g. "splunk-prod"); the key is what appears in every URL and audit-log line for this forwarder.

type AuditResourceType added in v3.0.34

type AuditResourceType struct {
	// ID is the resource_type slug (e.g. "invoice").
	ID string
	// ResourceType is the same slug as ID; both fields are populated
	// for clarity.
	ResourceType string
	// CreatedAt is the earliest sighting of this resource_type for the
	// account.
	CreatedAt time.Time
}

AuditResourceType is one row from the resource-type index.

type AuditResourceTypes added in v3.0.34

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

AuditResourceTypes lists the distinct resource-type slugs seen in the account.

environment is the SDK's configured runtime environment (empty when unset); it scopes the listing as the default filter[environment] (ADR-055).

func (*AuditResourceTypes) List added in v3.0.34

List returns one page of distinct resource-type slugs seen in the account.

Response time is independent of how many years of events the account has accumulated. Sorted alphabetically; offset pagination via PageNumber / PageSize.

type Backoff added in v3.0.152

type Backoff string

Backoff is how the wait between retries grows (a retry policy's backoff strategy).

  • BackoffExponential: Double the wait each retry — DelaySeconds, then 2×, 4×, … — capped at MaxDelaySeconds.
  • BackoffFixed: Wait a constant DelaySeconds before every retry.

type BindOption added in v3.0.83

type BindOption func(*bindOptions)

BindOption configures a Bind call.

func WithBindParent added in v3.0.83

func WithBindParent(parent interface{}) BindOption

WithBindParent declares the named target as inheriting from a previously bound parent. The parent must be the same object reference previously returned from a successful Bind call on this client. Activates parent-chain inheritance at the server side for any keys the caller omitted from the target (map-target form only — struct fields always register as explicit overrides).

type BooleanFlagHandle

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

BooleanFlagHandle is a typed handle for a boolean flag.

func (*BooleanFlagHandle) Get

func (h *BooleanFlagHandle) Get(ctx context.Context, contexts ...Context) bool

Get evaluates the flag and returns a typed boolean value.

The variadic contexts are optional Context entities to evaluate targeting rules against; when omitted, the ambient request context (if any) is used. Returns the evaluated boolean value, or this flag's default when no environment override or rule applies, or when the evaluated value is not a bool.

func (*BooleanFlagHandle) OnChange

func (h *BooleanFlagHandle) OnChange(cb func(*FlagChangeEvent))

OnChange registers a flag-specific change listener.

type CategoryListPage added in v3.0.126

type CategoryListPage struct {
	// Categories is the slice of categories on this page.
	Categories []AuditCategory
	// Pagination describes the page boundaries and totals (if requested).
	Pagination Pagination
}

CategoryListPage is one page of category values.

type ChangeListenerOption

type ChangeListenerOption func(*changeListenerConfig)

ChangeListenerOption configures an OnChange listener.

func WithConfigID

func WithConfigID(id string) ChangeListenerOption

WithConfigID restricts the listener to changes in the given config.

func WithItemKey

func WithItemKey(key string) ChangeListenerOption

WithItemKey restricts the listener to changes of the given item key.

type ClientOption

type ClientOption func(*clientConfig)

ClientOption configures the Client. Pass options to NewClient.

func WithHTTPClient

func WithHTTPClient(c *http.Client) ClientOption

WithHTTPClient replaces the default HTTP client entirely. When set, the WithTimeout option is ignored because the caller controls the client.

func WithTimeout

func WithTimeout(d time.Duration) ClientOption

WithTimeout sets the HTTP request timeout. The default is 30 seconds.

type Color

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

Color is a CSS hex color string. It is immutable: construct a fresh Color via NewColor or NewColorRGB to change a value.

The constructors validate their inputs at the SDK boundary so customer mistakes surface at the call site rather than as a server 400 later.

func MustColor

func MustColor(hex string) Color

MustColor is the panic-on-error variant of NewColor for compile-time constants. Customer code that builds colors from runtime input should always use NewColor and check the error.

func NewColor

func NewColor(hex string) (Color, error)

NewColor constructs a Color from a CSS hex string. Accepts #RGB, #RRGGBB, or #RRGGBBAA. Any other input returns a non-nil error.

func NewColorRGB

func NewColorRGB(r, g, b int) (Color, error)

NewColorRGB constructs a Color from 0–255 integer components. Each component is validated; out-of-range values produce a non-nil error.

func (Color) Hex

func (c Color) Hex() string

Hex returns the canonical (lowercase) CSS hex string.

func (Color) IsZero

func (c Color) IsZero() bool

IsZero reports whether c is the zero Color value (i.e. unset).

func (Color) String

func (c Color) String() string

String returns the canonical hex string, satisfying fmt.Stringer.

type Config

type Config struct {
	// Profile selects the INI profile from ~/.smplkit.
	// Falls back to SMPLKIT_PROFILE env var, then "default".
	Profile string

	// APIKey is the Bearer token for API authentication.
	// Falls back to SMPLKIT_API_KEY env var, then the config file.
	APIKey string

	// BaseDomain overrides the base domain for service URLs.
	// Default: "smplkit.com". Falls back to SMPLKIT_BASE_DOMAIN env var.
	BaseDomain string

	// Scheme overrides the URL scheme. Default: "https".
	// Falls back to SMPLKIT_SCHEME env var.
	Scheme string

	// Environment is the target environment (e.g. "production", "staging").
	// Falls back to SMPLKIT_ENVIRONMENT env var, then the config file.
	Environment string

	// Service is the service identifier.
	// Falls back to SMPLKIT_SERVICE env var, then the config file.
	Service string

	// Debug enables verbose debug output.
	// Falls back to SMPLKIT_DEBUG env var, then the config file.
	Debug bool

	// DisableTelemetry disables anonymous SDK usage telemetry.
	// Falls back to SMPLKIT_DISABLE_TELEMETRY env var, then the config file.
	DisableTelemetry bool

	// ExtraHeaders are additional HTTP headers sent on every request.
	// SDK-owned headers (Authorization, Accept, User-Agent) take precedence
	// over any key supplied here — callers cannot override them.
	ExtraHeaders map[string]string
}

Config holds user-facing configuration for the smplkit SDK. Fields use Go zero values (empty string, false) to represent "unset". Resolution order: defaults -> config file -> env vars -> struct fields.

type ConfigChangeEvent

type ConfigChangeEvent struct {
	// ConfigID is the config ID that changed (e.g. "user_service").
	ConfigID string
	// ItemKey is the item key within the config that changed.
	ItemKey string
	// OldValue is the value before the change (nil if the key was new).
	OldValue interface{}
	// NewValue is the value after the change (nil if the key was removed).
	NewValue interface{}
	// Source is "websocket" for server-pushed changes or "manual" for Refresh calls.
	Source string
}

ConfigChangeEvent describes a single value change detected on refresh.

type ConfigClient

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

ConfigClient is the Smpl Config client.

One client exposes the full surface, reachable as client.Config() (SmplClient) or constructed directly:

config, err := smplkit.NewConfigClient(smplkit.Config{Environment: "production", Service: "billing"})
billing := config.New("billing", smplkit.WithConfigName("Billing"))
billing.Save(ctx)
proxy, _ := config.Subscribe(ctx, "billing")
v, _ := proxy.Get("max_seats")

The CRUD surface (New / Get / List / Delete and discovery) is pure CRUD. The live surface (Subscribe / GetValue / Bind / OnChange / Refresh) connects lazily on first use — the first call flushes discovery, fetches and resolves all configs into the local cache, and opens the live-updates WebSocket. No explicit install step is required.

func NewConfigClient added in v3.0.126

func NewConfigClient(cfg Config, opts ...ClientOption) (*ConfigClient, error)

NewConfigClient creates a standalone Smpl Config client that builds and owns its own config transport, and on first live use opens and owns its own WebSocket.

func (*ConfigClient) Bind added in v3.0.83

func (c *ConfigClient) Bind(ctx context.Context, id string, target interface{}, opts ...BindOption) error

Bind declares a configuration from code and registers `target` as the live, in-place-mutated handle for it.

`target` must be a non-nil pointer to a struct, or a non-nil `map[string]interface{}`. Both kinds are reference types in Go — the SDK mutates them in place when the server pushes updates, so the caller's reference always sees the current resolved value.

  • Struct pointer: every exported field is registered as a config item, using the field's `json` tag if present (without the `,omitempty` suffix), else the field name. Nested struct fields flatten to dot-notation. Every field is treated as an explicit override — Go's type system has no equivalent of Pydantic's `model_fields_set`, so omit-to-inherit semantics are not available on the struct path. Use a `map[string]interface{}` if you need omit-to-inherit.
  • Map: every key in the map is registered as a config item; values are used as the in-code defaults; nested maps flatten to dot-notation. Keys absent from the map inherit from the parent at the server side.

Idempotent. Repeated calls with the same `id` return without re-registering — the originally bound target keeps receiving updates.

After Bind returns, the local cache has been synced into `target` for any keys the server already had values for. On every subsequent WebSocket-delivered change, the SDK mutates `target` in place.

Mirrors python-sdk's `client.config.bind()` and typescript-sdk's `client.config.bind()`.

func (*ConfigClient) Delete added in v3.0.126

func (c *ConfigClient) Delete(ctx context.Context, id string) error

Delete removes a config by id.

func (*ConfigClient) Flush added in v3.0.126

func (c *ConfigClient) Flush(ctx context.Context) error

Flush sends any queued config and item declarations to the server.

Discovery is best-effort — failures here never propagate to your code. Drained entries are not requeued; the SDK re-observes them on the next process start.

func (*ConfigClient) Get

func (c *ConfigClient) Get(ctx context.Context, id string) (*ConfigEntry, error)

Get fetches the editable ConfigEntry resource by id.

Returns a NotFoundError if no config with that id exists. For a live, dict-like view of resolved values use Subscribe; for typed access via a bound struct/map use Bind.

func (*ConfigClient) GetValue

func (c *ConfigClient) GetValue(ctx context.Context, configID, key string) (interface{}, error)

GetValue returns the resolved value of `key` within `configID`. Returns a NotFoundError if either the config or the key is missing. Does not register the key — use GetValueOr if you want default-on-miss + code- first console observability.

func (*ConfigClient) GetValueOr added in v3.0.83

func (c *ConfigClient) GetValueOr(ctx context.Context, configID, key string, defaultValue interface{}) interface{}

GetValueOr returns the resolved value of `key` within `configID`, or `defaultValue` if either the config or the key is missing. Never returns an error. Auto-registers the config and key (with `defaultValue` as the in-code default) for code-first console observability — operators see the reference in the smplkit console even when no schema was declared via Bind.

The item type is inferred from `defaultValue`'s Go runtime type: bool → BOOLEAN, int / int64 / float / float64 → NUMBER, string → STRING, anything else → STRING (universal fallback; an admin can retype the item in the console).

func (*ConfigClient) List added in v3.0.126

func (c *ConfigClient) List(ctx context.Context, opts ...ListOption) ([]*ConfigEntry, error)

List returns one page of configs for the account.

Without options the server applies its defaults (page 1, page size 1000). Use WithPageNumber / WithPageSize to walk additional pages.

func (*ConfigClient) New added in v3.0.126

func (c *ConfigClient) New(id string, opts ...ConfigOption) *ConfigEntry

New returns a new unsaved ConfigEntry. Call ConfigEntry.Save to persist. If name is not provided via WithConfigName it is auto-generated from the ID.

func (*ConfigClient) OnChange

func (c *ConfigClient) OnChange(cb func(*ConfigChangeEvent), opts ...ChangeListenerOption)

OnChange registers a listener that fires when a config value changes. Use WithConfigID and/or WithItemKey to scope the listener.

func (*ConfigClient) PendingCount added in v3.0.126

func (c *ConfigClient) PendingCount() int

PendingCount returns the number of pending config declarations awaiting flush.

func (*ConfigClient) Refresh

func (c *ConfigClient) Refresh(ctx context.Context) error

Refresh re-fetches all configs and resolves current values. OnChange listeners fire for any values that changed.

func (*ConfigClient) RegisterConfig added in v3.0.126

func (c *ConfigClient) RegisterConfig(configID, service, environment, parent, name, description string)

RegisterConfig queues a configuration declaration for bulk-discovery upload.

The declaration is buffered and sent in the background; it surfaces the config in the smplkit console even if no values are set yet. configID is the config identifier (slug) being declared. service is the name of the service declaring the config. environment is the environment the declaration is scoped to. parent is an optional parent config id this config inherits from. name is an optional display name. description is an optional human-readable description.

func (*ConfigClient) RegisterConfigItem added in v3.0.126

func (c *ConfigClient) RegisterConfigItem(configID, itemKey, itemType string, defaultVal interface{}, description string)

RegisterConfigItem queues a config item declaration. RegisterConfig must run first.

The declaration is buffered and sent in the background, surfacing the item (with its type and default) in the smplkit console. configID is the config identifier (slug) the item belongs to. itemKey is the key of the item within the config. itemType is the item value type — one of "STRING", "NUMBER", "BOOLEAN", or "JSON". defaultVal is the in-code default value for the item. description is an optional human-readable description.

func (*ConfigClient) Subscribe

func (c *ConfigClient) Subscribe(ctx context.Context, id string) (*LiveConfig, error)

Subscribe returns a live, dict-like, read-only LiveConfig proxy whose reads always reflect the latest resolved values for the given config id. WebSocket updates are picked up automatically. Subscribing registers the config declaration for code-first observability so the reference appears in the smplkit console.

Connects lazily on first use — no explicit install step. Returns a NotFoundError if the config is unknown. For typed access via an in-place-mutated struct or map, use Bind instead.

type ConfigEntry

type ConfigEntry struct {
	// ID is the config identifier (e.g. "user_service").
	ID string
	// Name is the display name for the config.
	Name string
	// Description is an optional description of the config.
	Description *string
	// Parent is the parent config ID, or nil for root configs.
	Parent *string
	// Items holds the base configuration values as a flat {key: value} map.
	Items map[string]interface{}
	// Environments maps environment names to their value overrides.
	Environments map[string]map[string]interface{}
	// CreatedAt is the creation timestamp.
	CreatedAt *time.Time
	// UpdatedAt is the last-modified timestamp.
	UpdatedAt *time.Time
	// contains filtered or unexported fields
}

ConfigEntry represents a configuration resource from the smplkit platform.

func (*ConfigEntry) Delete

func (c *ConfigEntry) Delete(ctx context.Context) error

Delete removes the config from the server. Equivalent to client.Config().Delete(ctx, c.ID).

func (*ConfigEntry) ItemsRaw added in v3.0.128

func (c *ConfigEntry) ItemsRaw() map[string]map[string]interface{}

ItemsRaw returns the full typed view of the base items as a read-only deep copy: {key: {"value": ..., "type": "STRING"|"NUMBER"|"BOOLEAN"|"JSON", "description": ...}}. The "description" key is present only when the item carries one. Unlike Items (which exposes resolved values only), this view preserves each item's declared type and description.

func (*ConfigEntry) Remove

func (c *ConfigEntry) Remove(name, environment string)

Remove removes an item. environment="" removes from base; non-empty removes the per-env override only.

func (*ConfigEntry) Save

func (c *ConfigEntry) Save(ctx context.Context) error

Save persists the config to the server. The Config instance is updated with the server response.

func (*ConfigEntry) Set added in v3.0.128

func (c *ConfigEntry) Set(item ConfigItem, environment string)

Set writes (or replaces) an item from a ConfigItem. environment="" updates the base item, carrying the item's declared type and description; a non-empty environment stores only the raw value as an override on that environment (the type and description come from the base item, so the ConfigItem's Type and Description are ignored). Call Save(ctx) to persist.

func (*ConfigEntry) SetBoolean

func (c *ConfigEntry) SetBoolean(name string, value bool, environment string, opts ...ItemOption)

SetBoolean sets a boolean item. environment="" updates the base item; non-empty scopes the value to that environment as an override. Pass WithItemDescription to attach a description (base item only). Call Save(ctx) to persist.

func (*ConfigEntry) SetJSON

func (c *ConfigEntry) SetJSON(name string, value interface{}, environment string, opts ...ItemOption)

SetJSON sets a JSON item. environment="" updates the base item; non-empty scopes the value to that environment as an override. Pass WithItemDescription to attach a description (base item only). Call Save(ctx) to persist.

func (*ConfigEntry) SetNumber

func (c *ConfigEntry) SetNumber(name string, value float64, environment string, opts ...ItemOption)

SetNumber sets a numeric item. environment="" updates the base item; non-empty scopes the value to that environment as an override. Pass WithItemDescription to attach a description (base item only). Call Save(ctx) to persist.

func (*ConfigEntry) SetString

func (c *ConfigEntry) SetString(name, value, environment string, opts ...ItemOption)

SetString sets a string item. environment="" updates the base item; non-empty scopes the value to that environment as an override. Pass WithItemDescription to attach a description (base item only). Call Save(ctx) to persist.

func (*ConfigEntry) TypedEnvironments

func (c *ConfigEntry) TypedEnvironments() map[string]ConfigEnvironment

TypedEnvironments returns a typed, read-only view of per-environment item overrides on a ConfigEntry.

type ConfigEnvironment

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

ConfigEnvironment is the per-environment value overrides on a ConfigEntry. Frozen — mutate via ConfigEntry.SetString / SetNumber / SetBoolean / SetJSON / Remove with an environment argument.

An override stores only the raw value; the declared type and description come from the base item.

func NewConfigEnvironment

func NewConfigEnvironment(values map[string]interface{}) ConfigEnvironment

NewConfigEnvironment constructs a ConfigEnvironment. Used by the SDK when parsing server responses.

func (ConfigEnvironment) Values

func (e ConfigEnvironment) Values() map[string]interface{}

Values returns a defensive copy of the per-env value overrides.

type ConfigItem added in v3.0.128

type ConfigItem struct {
	// Name is the item key within its config.
	Name string
	// Value is the item's value.
	Value interface{}
	// Type is the declared value type (STRING, NUMBER, BOOLEAN, or JSON).
	Type ItemType
	// Description is an optional human-readable description.
	Description string
}

ConfigItem is a single typed item within a ConfigEntry. Pass one to ConfigEntry.Set to write (or replace) an item with full control over its declared type and description; the SetString / SetNumber / SetBoolean / SetJSON convenience setters build a ConfigItem for you.

type ConfigOption

type ConfigOption func(*ConfigEntry)

ConfigOption configures an unsaved Config returned by ConfigClient.New.

func WithConfigDescription

func WithConfigDescription(desc string) ConfigOption

WithConfigDescription sets the description for a config.

func WithConfigEnvironments

func WithConfigEnvironments(envs map[string]map[string]interface{}) ConfigOption

WithConfigEnvironments sets the environment-specific overrides for a config.

func WithConfigItems

func WithConfigItems(items map[string]interface{}) ConfigOption

WithConfigItems sets the base configuration values for a config.

func WithConfigName

func WithConfigName(name string) ConfigOption

WithConfigName sets the display name for a config.

func WithConfigParent

func WithConfigParent(parentID string) ConfigOption

WithConfigParent sets the parent config UUID for inheritance.

type ConflictError

type ConflictError struct {
	// Base is the embedded base Error carrying the HTTP status, message,
	// raw response body, and any parsed JSON:API error details.
	Base Error
}

ConflictError is raised when an operation conflicts with current resource state.

func (*ConflictError) Error

func (e *ConflictError) Error() string

Error implements the error interface.

func (*ConflictError) Unwrap

func (e *ConflictError) Unwrap() error

Unwrap returns the embedded Error so errors.Is/errors.As walk the chain.

type ConnectionError

type ConnectionError struct {
	// Base is the embedded base Error carrying the HTTP status, message,
	// raw response body, and any parsed JSON:API error details.
	Base Error
}

ConnectionError is raised when a network request fails.

func (*ConnectionError) Error

func (e *ConnectionError) Error() string

Error implements the error interface.

func (*ConnectionError) Unwrap

func (e *ConnectionError) Unwrap() error

Unwrap returns the embedded Error so errors.Is/errors.As walk the chain.

type Context

type Context struct {
	// Type is the context type (e.g. "user", "account").
	Type string
	// Key is the unique identifier for this entity.
	Key string
	// Name is an optional display name.
	Name string
	// Attributes holds arbitrary key-value data for rule evaluation.
	Attributes map[string]interface{}
}

Context represents a typed evaluation context entity.

Each Context identifies an entity (user, account, device, etc.) by type and key, with optional attributes that JSON Logic rules can target.

ctx := smplkit.NewContext("user", "user-123", map[string]any{
    "plan": "enterprise",
    "firstName": "Alice",
})

Identity locking note: a persisted Context has a stable (type, key) identity. Go's idiom of exported struct fields makes that lock unenforceable at compile time — ctx.Type = "X" is always allowed by the language. Customer code that wants identity-locking semantics should treat persisted Contexts (those returned by client.Platform().Contexts().Get / List) as read-only and construct fresh ones via NewContext for new entities. NewContext enforces the runtime "must not be empty" check, panicking on empty inputs.

func NewContext

func NewContext(contextType, key string, attrs map[string]interface{}, opts ...ContextOption) Context

NewContext creates a new evaluation context. The optional attrs map provides attributes for JSON Logic rule evaluation. Use WithName to set a display name, or WithAttr to add individual attributes.

// Using a map:
ctx := smplkit.NewContext("user", "user-123", map[string]any{"plan": "enterprise"})

// Using functional options:
ctx := smplkit.NewContext("user", "user-123", nil,
    smplkit.WithName("Alice"),
    smplkit.WithAttr("plan", "enterprise"),
)

Fail-fast validation: empty type or key panics with a clear message. Go's type system already enforces string arguments, so only non-emptiness needs checking. Numeric IDs must be stringified at the SDK boundary — silent normalization weakens the contract.

func (Context) CompositeID

func (c Context) CompositeID() string

CompositeID returns the composite "type:key" identifier. Useful when calling sub-clients that accept either a composite id or separate (type, key) arguments.

type ContextEntity

type ContextEntity struct {
	// ContextType is the context type key (e.g. "user").
	ContextType string
	// Key is the entity's unique identifier within its type.
	Key string
	// Name is an optional display name.
	Name *string
	// Attributes holds arbitrary attribute data.
	Attributes map[string]interface{}
	// CreatedAt is the server creation timestamp.
	CreatedAt *time.Time
	// UpdatedAt is the last-modified timestamp.
	UpdatedAt *time.Time
	// contains filtered or unexported fields
}

ContextEntity is the active-record model returned by ContextsClient.List / Get. Mutate Attributes (or Name) and call Save(ctx) to persist; call Delete(ctx) to remove.

The builder-style Context (in flags_types.go) remains the canonical input type for flag evaluation; this struct is the read/write model returned by Contexts().List / Get, with a back-reference to its parent client.

func (*ContextEntity) CompositeID

func (ce *ContextEntity) CompositeID() string

CompositeID returns the composite "type:key" identifier.

func (*ContextEntity) Delete

func (ce *ContextEntity) Delete(ctx context.Context) error

Delete removes this context entity from the server. Equivalent to client.Platform().Contexts().Delete(ctx, ce.ContextType, ce.Key).

func (*ContextEntity) Save

func (ce *ContextEntity) Save(ctx context.Context) error

Save persists the context entity to the server. The instance is updated with server-returned fields on success.

type ContextOption

type ContextOption func(*Context)

ContextOption configures a Context. Use WithName and WithAttr.

func WithAttr

func WithAttr(key string, value interface{}) ContextOption

WithAttr adds a single attribute to a Context.

func WithName

func WithName(name string) ContextOption

WithName sets the display name on a Context.

type ContextScope added in v3.0.128

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

ContextScope is returned by SmplClient.SetContext.

Using it is optional: a bare client.SetContext(ctx, [...]) is fire-and-forget — the typical middleware pattern, where the context is set once at request entry and every context-sensitive evaluation inside that request picks it up. Capture the returned scope and defer Restore (or Close) to revert to the previously-active context on exit, useful for scoped overrides like impersonation:

defer client.SetContext(ctx, []smplkit.Context{userCtx}).Restore()

func (*ContextScope) Close added in v3.0.128

func (s *ContextScope) Close() error

Close calls Restore and returns nil so a ContextScope can be used with the io.Closer idiom (for example defer scope.Close()).

func (*ContextScope) Restore added in v3.0.128

func (s *ContextScope) Restore()

Restore reverts the active evaluation context to whatever was set before the SetContext call that produced this scope. Safe to call more than once; only the first call has any effect.

type ContextType

type ContextType struct {
	// ID is the context type identifier (e.g. "user", "account").
	ID string
	// Name is the display name.
	Name string
	// Attributes maps attribute names to their metadata dicts.
	Attributes map[string]map[string]interface{}
	// CreatedAt is the server creation timestamp (nil for unsaved instances).
	CreatedAt *time.Time
	// UpdatedAt is the last-modified timestamp.
	UpdatedAt *time.Time
	// contains filtered or unexported fields
}

ContextType resource on the smplkit platform. Mutate Attributes via AddAttribute / RemoveAttribute / UpdateAttribute, then call Save(ctx).

func (*ContextType) AddAttribute

func (ct *ContextType) AddAttribute(name string, meta ...map[string]interface{})

AddAttribute adds a known-attribute slot. Local-only; call Save(ctx) to persist.

name is the attribute name to declare on this context type. meta is optional metadata stored for the attribute slot; when omitted the slot is declared with empty metadata.

func (*ContextType) Delete added in v3.0.126

func (ct *ContextType) Delete(ctx context.Context) error

Delete removes this context type from the server.

func (*ContextType) RemoveAttribute

func (ct *ContextType) RemoveAttribute(name string)

RemoveAttribute removes a known-attribute slot. Local-only; call Save(ctx) to persist.

name is the attribute to remove; this is a no-op when the attribute is not declared on this context type.

func (*ContextType) Save

func (ct *ContextType) Save(ctx context.Context) error

Save creates or updates the context type on the server. Creates if CreatedAt is nil, otherwise updates.

func (*ContextType) UpdateAttribute

func (ct *ContextType) UpdateAttribute(name string, meta map[string]interface{})

UpdateAttribute replaces a known-attribute slot's metadata. Local-only; call Save(ctx) to persist.

name is the attribute name whose metadata to replace. meta is the new metadata for the attribute slot, replacing any existing metadata.

type ContextTypeOption

type ContextTypeOption func(*ContextType)

ContextTypeOption configures an unsaved ContextType returned by ContextTypesClient.New.

func WithContextTypeName

func WithContextTypeName(name string) ContextTypeOption

WithContextTypeName sets the display name for a context type.

type ContextTypesClient added in v3.0.126

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

ContextTypesClient provides CRUD operations for context-type resources (client.Platform().ContextTypes()).

func (*ContextTypesClient) Delete added in v3.0.126

func (m *ContextTypesClient) Delete(ctx context.Context, id string) error

Delete removes a context type by ID. id is the identifier of the context type to delete.

func (*ContextTypesClient) Get added in v3.0.126

Get retrieves a single context type by ID. id is the identifier of the context type to fetch. Returns a NotFoundError when no context type with that id exists.

func (*ContextTypesClient) List added in v3.0.126

func (m *ContextTypesClient) List(ctx context.Context, opts ...ListOption) ([]*ContextType, error)

List returns one page of context types for the account.

Without options the server applies its defaults (page 1, page size 1000). Use WithPageNumber / WithPageSize to walk additional pages.

func (*ContextTypesClient) New added in v3.0.126

New returns an unsaved ContextType. Call ct.Save(ctx) to persist.

id is a stable, human-readable identifier, e.g. "user". If no WithContextTypeName option is provided the ID is used as the display name. A new context type starts with no declared known-attribute slots; declare them via AddAttribute, each keyed by attribute name with a metadata map per slot, before saving.

type ContextsClient added in v3.0.126

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

ContextsClient provides context registration, listing, and deletion (client.Platform().Contexts()).

func (*ContextsClient) Delete added in v3.0.126

func (m *ContextsClient) Delete(ctx context.Context, parts ...string) error

Delete removes a context by its composite "type:key" id, or by separate type and key arguments.

parts identifies the context: pass one argument carrying the composite "type:key" id, or two arguments giving the type and key separately. Any other number of arguments is an error.

func (*ContextsClient) Flush added in v3.0.126

func (m *ContextsClient) Flush(ctx context.Context) error

Flush sends any pending context observations to the server immediately.

func (*ContextsClient) Get added in v3.0.126

func (m *ContextsClient) Get(ctx context.Context, parts ...string) (*ContextEntity, error)

Get retrieves a single context by its composite "type:key" id, or by separate type and key arguments:

client.Platform().Contexts().Get(ctx, "user:usr_123")
client.Platform().Contexts().Get(ctx, "user", "usr_123")

parts identifies the context: pass one argument carrying the composite "type:key" id, or two arguments giving the type and key separately. Any other number of arguments is an error. Returns a NotFoundError when no context with that id exists.

func (*ContextsClient) List added in v3.0.126

func (m *ContextsClient) List(ctx context.Context, contextType string, opts ...ListOption) ([]*ContextEntity, error)

List returns one page of context instances of the given context type.

contextType is the context type to list, e.g. "user". Without options the server applies its defaults (page 1, page size 1000). Use WithPageNumber / WithPageSize to walk additional pages.

func (*ContextsClient) PendingCount added in v3.0.126

func (m *ContextsClient) PendingCount() int

PendingCount reports the number of observations queued and awaiting flush.

func (*ContextsClient) Register added in v3.0.126

func (m *ContextsClient) Register(ctx context.Context, contexts []Context, opts ...ContextsRegisterOption) error

Register buffers contexts for registration with the server.

contexts are the contexts to buffer for registration. Buffered contexts are sent in batches: a background flush kicks in once enough have accumulated, and any remainder is sent on the next explicit flush. Pass WithContextFlush() to send everything buffered right away with an immediate synchronous flush after queuing.

type ContextsRegisterOption

type ContextsRegisterOption func(*contextsRegisterOpts)

ContextsRegisterOption configures a Register call.

func WithContextFlush

func WithContextFlush() ContextsRegisterOption

WithContextFlush causes Register to immediately flush the buffer to the server. Without this option contexts are queued for the next background flush.

type CreateEventInput added in v3.0.10

type CreateEventInput struct {
	// EventType is the event type slug — required.
	EventType string
	// ResourceType is the type of resource the event operated on. Must
	// not start with "smpl." (reserved for SDK-emitted events).
	ResourceType string
	// ResourceID is the customer-facing id of the resource.
	ResourceID string
	// OccurredAt is when the event actually happened. Defaults to the
	// server's receive time when nil.
	OccurredAt *time.Time
	// ActorType is a free-form label for the kind of actor that caused
	// the event (e.g. "USER", "API_KEY", "SYSTEM", or any custom value).
	// The audit service never backfills this from the request
	// credential — set it explicitly when you want the event attributed.
	ActorType string
	// ActorID is the actor identifier. Free-form — any string scheme is
	// accepted.
	ActorID string
	// ActorLabel is a human-readable label for the actor (e.g. an email
	// address or API key name).
	ActorLabel string
	// Category is an optional free-form bucket label for the event (e.g.
	// "auth", "billing", "config-change"). Stored exactly as supplied;
	// powers the audit log's category filter and the categories discovery
	// listing (client.Audit().Categories()). Omit it to leave the event
	// uncategorized.
	Category string
	// Data is free-form contextual JSON. To record a resource snapshot,
	// nest it inside Data — the smplkit internal convention is
	// Data["snapshot"], but the shape is unconstrained.
	Data map[string]interface{}
	// IdempotencyKey is an optional customer-supplied dedupe key. When
	// omitted, the server derives one from the event content (account_id
	// + event_type + resource_type + resource_id + occurred_at + actor_*
	// + data).
	IdempotencyKey string
	// DoNotForward suppresses SIEM forwarder execution for this event.
	// The event itself is still recorded; the forwarder loop records a
	// "skipped_do_not_forward" delivery row for each enabled forwarder.
	DoNotForward bool
	// Flush, when true, makes Record block until this event has been durably
	// delivered (or FlushTimeout elapses) before returning, instead of the
	// fire-and-forget default. Use it when the caller needs the event durable
	// before continuing — CLI tools, in-test assertions, and any flow about to
	// exit the process. Leave it false on the request-handling hot path.
	Flush bool
	// FlushTimeout bounds the blocking flush when Flush is true. Zero means the
	// default of 5 seconds. Ignored when Flush is false.
	FlushTimeout time.Duration
}

CreateEventInput is the input for AuditEvents.Record.

Customers must NOT use a ResourceType prefixed with "smpl." — the server returns 403 for those because that namespace is reserved for smplkit-emitted events.

DoNotForward suppresses SIEM forwarder execution for this event. The event itself is still recorded; the forwarder loop records a "skipped_do_not_forward" delivery row for each enabled forwarder so the skip is visible in the delivery log. Data is free-form contextual JSON. To record a resource snapshot, nest it inside Data — smplkit's internal convention is Data["snapshot"], but the shape is unconstrained.

type Environment

type Environment struct {
	// ID is the environment slug (e.g. "production").
	ID string
	// Name is the display name.
	Name string
	// Color is an optional hex color string for the Console UI.
	Color *string
	// Classification controls whether this environment participates in ordering.
	Classification EnvironmentClassification
	// CreatedAt is the server creation timestamp (nil for unsaved instances).
	CreatedAt *time.Time
	// UpdatedAt is the last-modified timestamp.
	UpdatedAt *time.Time
	// contains filtered or unexported fields
}

Environment resource. Mutate fields, then call Save(ctx).

func (*Environment) Delete added in v3.0.126

func (e *Environment) Delete(ctx context.Context) error

Delete removes this environment from the server.

func (*Environment) Save

func (e *Environment) Save(ctx context.Context) error

Save creates or updates the environment on the server. The instance is updated with server-returned fields on success. PUT semantics: creates if CreatedAt is nil, otherwise updates.

func (*Environment) SetTypedColor

func (e *Environment) SetTypedColor(c Color)

SetTypedColor sets the environment's display color from a typed Color. A zero Color clears the color. Call Save(ctx) to persist.

func (*Environment) TypedColor

func (e *Environment) TypedColor() Color

TypedColor returns the environment's display color as a typed Color, or the zero Color when no color is set or the stored value is not a valid hex string. Reading the color never surfaces a validation error.

type EnvironmentClassification

type EnvironmentClassification string

EnvironmentClassification indicates whether an environment participates in the canonical environment ordering.

STANDARD environments are the customer's deploy targets — production, staging, development, etc. They participate in AccountSettings.EnvironmentOrder and appear in the standard Console environment columns.

AD_HOC environments are transient targets (preview branches, individual developer sandboxes) that should not appear in the standard ordering.

const (
	// EnvironmentClassificationAdHoc marks an environment as a transient,
	// non-ordered target (preview branches, developer sandboxes).
	EnvironmentClassificationAdHoc EnvironmentClassification = "AD_HOC"
	// EnvironmentClassificationStandard marks an environment as a canonical
	// deploy target — appears in AccountSettings.EnvironmentOrder.
	EnvironmentClassificationStandard EnvironmentClassification = "STANDARD"
)

Supported EnvironmentClassification values, alphabetical by wire constant.

type EnvironmentOption

type EnvironmentOption func(*Environment)

EnvironmentOption configures an unsaved Environment returned by EnvironmentsClient.New.

func WithEnvironmentClassification

func WithEnvironmentClassification(c EnvironmentClassification) EnvironmentOption

WithEnvironmentClassification sets the classification (STANDARD or AD_HOC).

func WithEnvironmentColor

func WithEnvironmentColor(color string) EnvironmentOption

WithEnvironmentColor sets the display color (hex string, e.g. "#ef4444").

type EnvironmentsClient added in v3.0.126

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

EnvironmentsClient provides CRUD operations for environment resources (client.Platform().Environments()).

func (*EnvironmentsClient) Delete added in v3.0.126

func (m *EnvironmentsClient) Delete(ctx context.Context, id string) error

Delete removes an environment by ID. id is the identifier of the environment to delete.

func (*EnvironmentsClient) Get added in v3.0.126

Get retrieves a single environment by ID. id is the identifier of the environment to fetch. Returns a NotFoundError when no environment with that id exists.

func (*EnvironmentsClient) List added in v3.0.126

func (m *EnvironmentsClient) List(ctx context.Context, opts ...ListOption) ([]*Environment, error)

List returns one page of environments for the account.

Without options the server applies its defaults (page 1, page size 1000). Use WithPageNumber / WithPageSize to walk additional pages.

func (*EnvironmentsClient) New added in v3.0.126

func (m *EnvironmentsClient) New(id string, name string, opts ...EnvironmentOption) *Environment

New returns an unsaved Environment. Call env.Save(ctx) to persist.

id is a stable, human-readable identifier, e.g. "production". name is the display name shown in the Console. The options refine the environment: WithEnvironmentColor sets the accent color as a Color or CSS hex string (defaults to no color), and WithEnvironmentClassification controls whether the environment participates in the standard environment ordering (defaults to STANDARD).

type Error

type Error struct {
	// Message is a human-readable summary of the error.
	Message string
	// StatusCode holds the HTTP status code if the error came from the API.
	StatusCode int
	// ResponseBody holds the raw response body if available.
	ResponseBody string
	// Errors holds parsed JSON:API error details when available.
	Errors []ApiErrorDetail
}

Error is the base error type for all smplkit SDK errors. The hierarchy is flat: ConnectionError, TimeoutError, NotFoundError, ConflictError, and ValidationError are direct subtypes.

To match any SDK error use errors.As against *Error:

var e *smplkit.Error
if errors.As(err, &e) { ... }

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

type ErrorSource

type ErrorSource struct {
	// Pointer is the JSON Pointer to the offending member in the
	// request body (e.g. "/data/attributes/name").
	Pointer string `json:"pointer,omitempty"`
}

ErrorSource identifies the source of a JSON:API error.

type EventTypeListPage added in v3.0.69

type EventTypeListPage struct {
	// EventTypes is the slice of event types on this page.
	EventTypes []AuditEventType
	// Pagination describes the page boundaries and totals (if requested).
	Pagination Pagination
}

EventTypeListPage is one page of event type slugs.

type Flag

type Flag struct {
	// ID is the flag identifier (e.g. "dark-mode").
	ID string
	// Name is the display name for the flag.
	Name string
	// Type is the value type (BOOLEAN, STRING, NUMERIC, JSON).
	Type string
	// Default is the default value for the flag.
	Default interface{}
	// Values is the closed set of possible values (constrained), or nil (unconstrained).
	Values *[]FlagValue
	// Description is an optional description of the flag.
	Description *string
	// Environments maps environment names to their configuration.
	Environments map[string]interface{}
	// CreatedAt is the creation timestamp.
	CreatedAt *time.Time
	// UpdatedAt is the last-modified timestamp.
	UpdatedAt *time.Time
	// contains filtered or unexported fields
}

Flag represents a flag resource from the smplkit platform.

func (*Flag) AddRule

func (f *Flag) AddRule(builtRule map[string]interface{}) error

AddRule appends a rule to the specified environment. Call Save(ctx) to persist.

The builtRule is the map produced by Rule(..., environment).When(...).Serve(...) (in Go, the fluent NewRule(...).Environment("env").When(...).Serve(...).Build() chain); it must include an "environment" key naming the target environment. Returns an error when the built rule has no "environment" key.

func (*Flag) AddValue

func (f *Flag) AddValue(name string, value interface{}) *Flag

AddValue appends a constrained value to the flag's value set. Returns f for chaining.

func (*Flag) ClearDefault

func (f *Flag) ClearDefault(environment string)

ClearDefault clears the per-environment default override on the named environment. environment must be non-empty; an empty environment is a no-op.

Call Flag.Save(ctx) to persist.

func (*Flag) ClearRules

func (f *Flag) ClearRules(envKey string)

ClearRules removes all rules for the environment named by envKey. Call Save(ctx) to persist.

This is a retained, single-environment verb; the unified ClearRulesAll verb clears rules across every configured environment instead.

func (*Flag) ClearRulesAll

func (f *Flag) ClearRulesAll()

ClearRulesAll clears rules in every environment configured on this flag. For a single-environment clear, use ClearRules(envKey).

func (*Flag) ClearValues

func (f *Flag) ClearValues()

ClearValues sets values to nil (unconstrained). Call Save(ctx) to persist.

func (*Flag) Delete

func (f *Flag) Delete(ctx context.Context) error

Delete removes this flag from the server.

func (*Flag) DisableRules

func (f *Flag) DisableRules(environment string)

DisableRules disables rule evaluation (kill switch). environment="" disables rules in every environment configured on this flag.

func (*Flag) EnableRules

func (f *Flag) EnableRules(environment string)

EnableRules enables rule evaluation. environment="" enables rules in every environment configured on this flag; non-empty scopes to that single environment.

func (*Flag) RemoveValue

func (f *Flag) RemoveValue(value interface{}) *Flag

RemoveValue removes the first values entry whose Value field matches. Returns f for chaining.

func (*Flag) Save

func (f *Flag) Save(ctx context.Context) error

Save persists the flag to the server. The Flag instance is updated with the server response.

func (*Flag) SetDefault

func (f *Flag) SetDefault(value interface{}, environment string)

SetDefault sets the default served value. environment="" updates the flag-level base default; environment="production" sets the per-env default.

Call Flag.Save(ctx) to persist.

func (*Flag) SetEnvironmentDefault

func (f *Flag) SetEnvironmentDefault(envKey string, defaultVal interface{})

SetEnvironmentDefault sets the default value served in the environment named by envKey to defaultVal, used when no rule matches there. Call Save(ctx) to persist.

This is a retained, single-environment verb layered on the unified SetDefault verb; SetDefault with an empty environment sets the flag-level base default instead.

func (*Flag) SetEnvironmentEnabled

func (f *Flag) SetEnvironmentEnabled(envKey string, enabled bool)

SetEnvironmentEnabled sets whether rule evaluation is enabled for the environment named by envKey to the given enabled value. Call Save(ctx) to persist.

This is a retained, single-environment verb layered on the unified per-env verbs EnableRules / DisableRules; pass an empty environment to those to apply the change across every configured environment.

func (*Flag) TypedEnvironments

func (f *Flag) TypedEnvironments() map[string]FlagEnvironment

TypedEnvironments returns a typed, read-only view of per-environment configuration on a Flag.

The returned map is a defensive copy; mutating it has no effect on the underlying flag. Mutate the flag via SetDefault / EnableRules / DisableRules / AddRule (with environment scoping) instead.

type FlagChangeEvent

type FlagChangeEvent struct {
	// ID is the flag ID that changed.
	ID string
	// Source is "websocket" or "manual".
	Source string
	// Deleted is true when the flag was deleted server-side.
	Deleted bool
}

FlagChangeEvent describes a flag definition change.

type FlagDeclaration added in v3.0.128

type FlagDeclaration struct {
	// ID is the stable flag identifier the declaration registers.
	ID string
	// Type is the flag value type (BOOLEAN, STRING, NUMERIC, or JSON).
	Type FlagType
	// Default is the in-code default value registered for the flag.
	Default interface{}
	// Service is the originating service name. When empty, the client fills it
	// from the owning SmplClient's resolved service.
	Service string
	// Environment is the target environment. When empty, the client fills it
	// from the owning SmplClient's resolved environment.
	Environment string
}

FlagDeclaration describes a flag for buffered bulk registration. Pass one or more to FlagsClient.Register to queue them for discovery upload.

type FlagEnvironment

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

FlagEnvironment is the per-environment configuration on a Flag. Frozen. Mutate via Flag.AddRule / Flag.EnableRules / Flag.DisableRules / Flag.SetDefault / Flag.ClearRules with environment scoping.

func NewFlagEnvironment

func NewFlagEnvironment(enabled bool, defaultValue interface{}, rules []FlagRule) FlagEnvironment

NewFlagEnvironment constructs a FlagEnvironment. Used by the SDK when parsing server responses; exposed for completeness.

func (FlagEnvironment) Default

func (e FlagEnvironment) Default() interface{}

Default returns the environment-specific default override, or nil if no override is set (in which case the flag's base default applies).

func (FlagEnvironment) Enabled

func (e FlagEnvironment) Enabled() bool

Enabled reports whether the flag is active in this environment.

func (FlagEnvironment) Rules

func (e FlagEnvironment) Rules() []FlagRule

Rules returns a defensive copy of the targeting rules.

type FlagOption

type FlagOption func(*Flag)

FlagOption configures an unsaved Flag returned by factory methods.

func WithFlagDescription

func WithFlagDescription(desc string) FlagOption

WithFlagDescription sets the description for a flag.

func WithFlagName

func WithFlagName(name string) FlagOption

WithFlagName sets the display name for a flag.

func WithFlagValues

func WithFlagValues(values []FlagValue) FlagOption

WithFlagValues sets the closed value set for a flag (constrained).

type FlagRegisterOption added in v3.0.128

type FlagRegisterOption func(*flagRegisterOpts)

FlagRegisterOption configures a batch Register call. Use WithFlagFlush.

func WithFlagFlush added in v3.0.128

func WithFlagFlush() FlagRegisterOption

WithFlagFlush makes Register flush all buffered declarations immediately rather than waiting for the batch threshold or the next periodic flush.

type FlagRule

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

FlagRule is a single targeting rule on a Flag. Frozen — author rules via the smplkit.Rule fluent builder and pass through Flag.AddRule.

func NewFlagRule

func NewFlagRule(logic map[string]interface{}, value interface{}, description string) FlagRule

NewFlagRule constructs a FlagRule. Customer code typically uses the Rule fluent builder; this constructor is used by the SDK when parsing server responses and exposed for completeness.

func (FlagRule) Description

func (r FlagRule) Description() string

Description returns the human-readable label, if any.

func (FlagRule) Logic

func (r FlagRule) Logic() map[string]interface{}

Logic returns a defensive copy of the JSON Logic predicate. Empty map means "always match".

func (FlagRule) Value

func (r FlagRule) Value() interface{}

Value returns the value served when Logic evaluates truthy.

type FlagStats

type FlagStats struct {
	// CacheHits is the number of evaluations served from cache.
	CacheHits int
	// CacheMisses is the number of evaluations that required computation.
	CacheMisses int
}

FlagStats holds runtime statistics for the flags subsystem.

type FlagType

type FlagType string

FlagType represents the value type of a flag.

const (
	// FlagTypeBoolean represents a boolean flag.
	FlagTypeBoolean FlagType = "BOOLEAN"
	// FlagTypeJSON represents a JSON flag.
	FlagTypeJSON FlagType = "JSON"
	// FlagTypeNumeric represents a numeric flag.
	FlagTypeNumeric FlagType = "NUMERIC"
	// FlagTypeString represents a string flag.
	FlagTypeString FlagType = "STRING"
)

Supported FlagType values, alphabetical by wire constant.

type FlagValue

type FlagValue struct {
	// Name is the human-readable label for this value option.
	Name string
	// Value is the raw value returned when this option is selected.
	// Shape depends on the flag's FlagType.
	Value interface{}
}

FlagValue represents a named value in a flag's value set.

type FlagsClient

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

FlagsClient is the Smpl Flags client.

One client exposes the full surface, reachable as client.Flags() or constructed directly via NewFlagsClient. The CRUD surface (NewBooleanFlag / NewStringFlag / NewNumberFlag / NewJsonFlag, Get / List / Delete, and the flag-declaration discovery buffer) is pure CRUD. The live surface (BooleanFlag / StringFlag / NumberFlag / JsonFlag / Refresh / Stats / OnChange) connects lazily on first use — the first call flushes discovery, fetches all flag definitions into the local cache, and opens the live-updates WebSocket. No explicit install step is required.

The client supports two construction shapes:

  • Wired into SmplClient — borrows the parent's flags transport for both runtime fetch and CRUD, the parent's shared WebSocket for the live channel, and the platform contexts sub-client for evaluation-context registration. This is the common path.
  • Standalone — NewFlagsClient(cfg, ...) builds and owns its own flags and app transports, and on first live use opens and owns its own WebSocket.

func NewFlagsClient added in v3.0.126

func NewFlagsClient(cfg Config, opts ...ClientOption) (*FlagsClient, error)

NewFlagsClient creates a standalone Smpl Flags client that builds and owns its own generated flags + app transports and, on first live use, its own WebSocket against the event gateway.

Flags needs environment + service: the environment scopes runtime flag values and discovery declarations, and the service is auto-injected as an evaluation context. Both resolve from cfg (or ~/.smplkit / env vars).

func (*FlagsClient) BooleanFlag

func (c *FlagsClient) BooleanFlag(key string, defaultValue bool) *BooleanFlagHandle

BooleanFlag returns a typed handle for a boolean flag.

The id is the identifier of the flag to evaluate. The defaultValue is returned by the handle's Get when the flag is unknown or no environment override or rule applies. Connects lazily on first use.

Returns a *BooleanFlagHandle whose Get evaluates against the live cache.

func (*FlagsClient) ConnectionStatus

func (c *FlagsClient) ConnectionStatus() string

ConnectionStatus returns the current real-time connection status.

func (*FlagsClient) Delete added in v3.0.126

func (c *FlagsClient) Delete(ctx context.Context, id string) error

Delete deletes a flag by id.

The id is the identifier of the flag to delete. Returns a *NotFoundError when no flag with that id exists for the account.

func (*FlagsClient) Disconnect

func (c *FlagsClient) Disconnect(ctx context.Context)

Disconnect stops real-time updates and releases runtime resources.

func (*FlagsClient) Evaluate

func (c *FlagsClient) Evaluate(ctx context.Context, key string, environment string, contexts []Context) interface{}

Evaluate evaluates a flag against an explicit environment and contexts and returns the raw resolved value.

The key is the identifier of the flag to evaluate. The environment is the environment name whose overrides and rules are applied. The contexts are the Context entities that targeting rules are evaluated against. The returned interface{} is the resolved value, untyped (nil when the flag is unknown or cannot be resolved).

This is the untyped, explicit-environment counterpart to the typed handle Get path (BooleanFlag/StringFlag/NumberFlag/JsonFlag and their Get): those resolve the environment from client configuration, coerce the result to a Go type, and fall back to a supplied default, whereas Evaluate names the environment directly and returns the value as-is.

func (*FlagsClient) Flush added in v3.0.126

func (c *FlagsClient) Flush(ctx context.Context)

Flush POSTs pending declarations to the flags bulk endpoint.

Items remain in the buffer until the request succeeds, so a flush against an unhealthy flags service is automatically retried by the next Flush() call (periodic background flush, install retry, or final flush on close).

func (*FlagsClient) FlushSync added in v3.0.128

func (c *FlagsClient) FlushSync(ctx context.Context)

FlushSync flushes pending flag declarations synchronously. It is an alias of Flush, mirroring LoggersClient.FlushSync for the periodic-flush path.

func (*FlagsClient) Get added in v3.0.126

func (c *FlagsClient) Get(ctx context.Context, id string) (*Flag, error)

Get fetches the editable Flag resource by id.

The id is the identifier of the flag to fetch. The returned *Flag is ready to mutate and Save. Returns a *NotFoundError when no flag with that id exists for the account.

func (*FlagsClient) JsonFlag

func (c *FlagsClient) JsonFlag(key string, defaultValue map[string]interface{}) *JsonFlagHandle

JsonFlag returns a typed handle for a JSON flag.

The id is the identifier of the flag to evaluate. The defaultValue is returned by the handle's Get when the flag is unknown or no environment override or rule applies. Connects lazily on first use.

Returns a *JsonFlagHandle whose Get evaluates against the live cache.

func (*FlagsClient) List added in v3.0.126

func (c *FlagsClient) List(ctx context.Context, opts ...ListOption) ([]*Flag, error)

List lists flags for the authenticated account.

Without options the server applies its defaults (page 1, page size 1000). Use WithPageNumber / WithPageSize to walk additional pages. The wrapper does not loop — callers that want every flag should iterate until a short page is returned.

Options:

  • WithPageNumber sets the 1-based page index to fetch; when omitted, the server default applies.
  • WithPageSize sets the number of flags per page; when omitted, the server default applies.

func (*FlagsClient) NewBooleanFlag added in v3.0.126

func (c *FlagsClient) NewBooleanFlag(id string, defaultValue bool, opts ...FlagOption) *Flag

NewBooleanFlag returns a new unsaved boolean Flag.

The id is a stable flag identifier, unique per account. The defaultValue is served when no environment override or rule applies.

Options:

  • WithFlagName sets a human-readable display name; when omitted it defaults to a title-cased form of id.
  • WithFlagDescription sets an optional free-text description.

Returns a new unsaved Flag; call Save to persist.

func (*FlagsClient) NewJsonFlag added in v3.0.126

func (c *FlagsClient) NewJsonFlag(id string, defaultValue map[string]interface{}, opts ...FlagOption) *Flag

NewJsonFlag returns a new unsaved JSON Flag.

The id is a stable flag identifier, unique per account. The defaultValue is served when no environment override or rule applies.

Options:

  • WithFlagName sets a human-readable display name; when omitted it defaults to a title-cased form of id.
  • WithFlagDescription sets an optional free-text description.
  • WithFlagValues sets an optional list of allowed values constraining what the flag may serve; when omitted, the flag is unconstrained.

Returns a new unsaved Flag; call Save to persist.

func (*FlagsClient) NewNumberFlag added in v3.0.126

func (c *FlagsClient) NewNumberFlag(id string, defaultValue float64, opts ...FlagOption) *Flag

NewNumberFlag returns a new unsaved numeric Flag.

The id is a stable flag identifier, unique per account. The defaultValue is served when no environment override or rule applies.

Options:

  • WithFlagName sets a human-readable display name; when omitted it defaults to a title-cased form of id.
  • WithFlagDescription sets an optional free-text description.
  • WithFlagValues sets an optional list of allowed values constraining what the flag may serve; when omitted, the flag is unconstrained.

Returns a new unsaved Flag; call Save to persist.

func (*FlagsClient) NewStringFlag added in v3.0.126

func (c *FlagsClient) NewStringFlag(id string, defaultValue string, opts ...FlagOption) *Flag

NewStringFlag returns a new unsaved string Flag.

The id is a stable flag identifier, unique per account. The defaultValue is served when no environment override or rule applies.

Options:

  • WithFlagName sets a human-readable display name; when omitted it defaults to a title-cased form of id.
  • WithFlagDescription sets an optional free-text description.
  • WithFlagValues sets an optional list of allowed values constraining what the flag may serve; when omitted, the flag is unconstrained.

Returns a new unsaved Flag; call Save to persist.

func (*FlagsClient) NumberFlag

func (c *FlagsClient) NumberFlag(key string, defaultValue float64) *NumberFlagHandle

NumberFlag returns a typed handle for a numeric flag.

The id is the identifier of the flag to evaluate. The defaultValue is returned by the handle's Get when the flag is unknown or no environment override or rule applies. Connects lazily on first use.

Returns a *NumberFlagHandle whose Get evaluates against the live cache.

func (*FlagsClient) OnChange

func (c *FlagsClient) OnChange(cb func(*FlagChangeEvent))

OnChange registers a global change listener that fires for any flag change.

func (*FlagsClient) OnChangeKey

func (c *FlagsClient) OnChangeKey(key string, cb func(*FlagChangeEvent))

OnChangeKey registers a key-scoped change listener that fires only when the specified flag key changes.

func (*FlagsClient) PendingCount added in v3.0.126

func (c *FlagsClient) PendingCount() int

PendingCount returns the number of pending flag declarations awaiting flush.

func (*FlagsClient) Refresh

func (c *FlagsClient) Refresh(ctx context.Context) error

Refresh fetches the latest flag definitions from the server.

func (*FlagsClient) Register added in v3.0.128

func (c *FlagsClient) Register(ctx context.Context, declarations []FlagDeclaration, opts ...FlagRegisterOption)

Register buffers one or more flag declarations for bulk-discovery upload.

Each declaration's Service and Environment default to the client's resolved values when left empty. Declarations stay buffered and are sent on the next flush — automatic once the buffer reaches its batch threshold, or on the first live call — unless WithFlagFlush is passed, which sends everything buffered immediately. Items remain in the buffer until the POST succeeds, so a failed flush is retried by the next Flush call.

func (*FlagsClient) RegisterFlag added in v3.0.126

func (c *FlagsClient) RegisterFlag(id, flagType string, defaultVal interface{})

RegisterFlag buffers a flag declaration for bulk-discovery upload.

Service and environment default to the client's resolved values. The declaration is queued for background flush; once the pending count reaches the batch threshold a flush is kicked off in the background. Items remain in the buffer until the POST succeeds, so failed flushes are retried by the next Flush() call.

func (*FlagsClient) SetContextProvider

func (c *FlagsClient) SetContextProvider(fn func(ctx context.Context) []Context)

SetContextProvider registers a function that supplies evaluation contexts.

The fn receives a context.Context and returns a []Context. The returned slice supplies the evaluation contexts that targeting rules are evaluated against. It is invoked during evaluation on the typed- handle Get path whenever no contexts are passed explicitly to Get, providing the ambient contexts in their place.

func (*FlagsClient) Stats

func (c *FlagsClient) Stats() FlagStats

Stats returns runtime statistics.

func (*FlagsClient) StringFlag

func (c *FlagsClient) StringFlag(key string, defaultValue string) *StringFlagHandle

StringFlag returns a typed handle for a string flag.

The id is the identifier of the flag to evaluate. The defaultValue is returned by the handle's Get when the flag is unknown or no environment override or rule applies. Connects lazily on first use.

Returns a *StringFlagHandle whose Get evaluates against the live cache.

type FlagsRuntime

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

FlagsRuntime holds the runtime state for the flags subsystem. Access it via FlagsClient methods like BooleanFlag, Disconnect, etc.

func (*FlagsRuntime) BooleanFlag

func (rt *FlagsRuntime) BooleanFlag(key string, defaultValue bool) *BooleanFlagHandle

BooleanFlag returns a typed handle for a boolean flag.

func (*FlagsRuntime) ConnectionStatus

func (rt *FlagsRuntime) ConnectionStatus() string

ConnectionStatus returns the current real-time connection status.

func (*FlagsRuntime) Evaluate

func (rt *FlagsRuntime) Evaluate(ctx context.Context, key string, environment string, contexts []Context) interface{}

Evaluate evaluates a flag with the given environment and contexts.

func (*FlagsRuntime) FlushContexts

func (rt *FlagsRuntime) FlushContexts(ctx context.Context)

FlushContexts sends any pending context registrations to the server immediately.

func (*FlagsRuntime) JsonFlag

func (rt *FlagsRuntime) JsonFlag(key string, defaultValue map[string]interface{}) *JsonFlagHandle

JsonFlag returns a typed handle for a JSON flag.

func (*FlagsRuntime) NumberFlag

func (rt *FlagsRuntime) NumberFlag(key string, defaultValue float64) *NumberFlagHandle

NumberFlag returns a typed handle for a numeric flag.

func (*FlagsRuntime) OnChange

func (rt *FlagsRuntime) OnChange(cb func(*FlagChangeEvent))

OnChange registers a global change listener.

func (*FlagsRuntime) OnChangeKey

func (rt *FlagsRuntime) OnChangeKey(key string, cb func(*FlagChangeEvent))

OnChangeKey registers a key-scoped change listener that fires only when the specified flag key changes.

func (*FlagsRuntime) Refresh

func (rt *FlagsRuntime) Refresh(ctx context.Context) error

Refresh fetches the latest flag definitions from the server. Change listeners fire after the refresh completes.

func (*FlagsRuntime) Register

func (rt *FlagsRuntime) Register(ctx context.Context, contexts ...Context)

Register explicitly registers context(s) with the server.

func (*FlagsRuntime) SetContextProvider

func (rt *FlagsRuntime) SetContextProvider(fn func(ctx context.Context) []Context)

SetContextProvider registers a function that provides evaluation contexts.

func (*FlagsRuntime) Stats

func (rt *FlagsRuntime) Stats() FlagStats

Stats returns runtime statistics.

func (*FlagsRuntime) StringFlag

func (rt *FlagsRuntime) StringFlag(key string, defaultValue string) *StringFlagHandle

StringFlag returns a typed handle for a string flag.

type Forwarder added in v3.0.16

type Forwarder struct {
	// ID is the caller-supplied key for this forwarder. Required at
	// create time (the audit service does not auto-generate it); unique
	// within the account and immutable for the lifetime of the forwarder.
	// The audit service returns 409 if another live forwarder already uses
	// this id. Empty string until Save has run for an unsaved instance
	// constructed without an id.
	ID string
	// Name is the display name. Free-form.
	Name string
	// Description is an optional free-text description.
	Description *string
	// ForwarderType is the destination type — see ForwarderType.
	ForwarderType ForwarderType
	// Environments holds per-environment sparse overrides keyed by environment
	// key (e.g. "production", "staging"). A forwarder delivers in an
	// environment only when Environments[env].Enabled is true. Each entry is a
	// flat overlay that overrides only the leaves it sets (URL, Method, headers,
	// …), inheriting the base Configuration for the rest. Reach (and lazily
	// create) an entry via Environment. Every referenced environment must exist
	// and be managed for the account. Nil/empty means the forwarder delivers
	// nowhere until enabled per environment. Enablement has no top-level field —
	// use Enabled() for the roll-up.
	Environments map[string]*ForwarderEnvironment
	// Filter is an optional JSON Logic expression evaluated per event.
	// When set, events that don't match are recorded as filtered_out
	// deliveries instead of being POSTed to the destination.
	Filter map[string]interface{}
	// Transform is an optional template applied to each event before
	// delivery. Shape depends on TransformType; for JSONATA, a string
	// containing a JSONata expression. Future engines may carry richer
	// shapes (objects, arrays, …), so the field is untyped. Nil
	// delivers the event JSON as-is; when set, TransformType must also
	// be set.
	Transform interface{}
	// TransformType identifies the engine used to evaluate Transform.
	// Currently only ForwarderTransformTypeJSONata is supported. Must
	// be set whenever Transform is set.
	TransformType *ForwarderTransformType
	// ForwardSmplkitEvents, when true, also delivers smplkit's own
	// platform change events (flag, configuration, and similar changes
	// smplkit records about your resources) through this forwarder. Each
	// such event is delivered through every environment this forwarder is
	// enabled in, using that environment's resolved configuration. Nil or
	// false (the default) means platform change events are not forwarded.
	// Independent of the per-environment Environments enablement, since
	// platform change events are not tied to a deployment environment.
	ForwardSmplkitEvents *bool
	// Configuration is the destination request configuration.
	Configuration HttpConfiguration
	// CreatedAt is when the audit service first persisted this
	// forwarder. Nil for an unsaved instance.
	CreatedAt *time.Time
	// UpdatedAt is when this forwarder was last mutated.
	UpdatedAt *time.Time
	// DeletedAt is when the forwarder was deleted. Nil for live forwarders.
	DeletedAt *time.Time
	// Version is a monotonic counter bumped on every server-side write.
	Version *int
	// contains filtered or unexported fields
}

Forwarder is a SIEM streaming destination configured on the customer's account. Active-record style: mutate fields directly and call Save(ctx) to persist, or Delete(ctx) to remove. Header values in Configuration.Headers are returned plaintext on reads, so a Get → mutate → Save round-trip preserves them.

func (*Forwarder) Delete added in v3.0.52

func (fwd *Forwarder) Delete(ctx context.Context) error

Delete removes this forwarder on the server.

func (*Forwarder) Enabled added in v3.0.16

func (fwd *Forwarder) Enabled() bool

Enabled reports the read-only roll-up: true when the forwarder is enabled in at least one environment. The audit API has no top-level enabled field, so the wrapper derives it from the Environments map (and it stays correct for in-memory edits made before Save). Enable per environment via forwarder.Environment(env).Enabled = true.

func (*Forwarder) Environment added in v3.0.155

func (fwd *Forwarder) Environment(environment string) *ForwarderEnvironment

Environment returns the per-environment override for environment — the single place to read or set what this forwarder overrides there (ADR-056).

It returns the ForwarderEnvironment for environment, creating an empty one (and inserting it into Environments) on first access, so overrides can be set directly on the returned pointer:

forwarder.Environment("production").Enabled = true
forwarder.Environment("production").URL = "https://prod.siem.example.com/in"
forwarder.Environment("production").SetHeader("DD-API-KEY", "prod-secret")

Only the leaves you set are sent on save; everything else inherits the base definition (the server resolves base ⊕ overrides on delivery).

func (*Forwarder) Save added in v3.0.52

func (fwd *Forwarder) Save(ctx context.Context) error

Save creates or updates this forwarder on the server. Upsert behavior keyed on CreatedAt: nil → create (POST), set → full-replace update (PUT). After the call, every field is refreshed from the server response (including CreatedAt, UpdatedAt, Version). Header values are returned plaintext on reads, so a Get → mutate → Save round-trip preserves them.

type ForwarderEnvironment added in v3.0.120

type ForwarderEnvironment struct {
	// Enabled controls whether the forwarder delivers events in this
	// environment. Defaults to false.
	Enabled bool
	// URL optionally overrides the base destination URL for this environment.
	// Empty does not override.
	URL string
	// Method optionally overrides the base HTTP verb for this environment.
	// Empty does not override.
	Method HttpMethod
	// SuccessStatus optionally overrides the base success-status pattern for
	// this environment. Empty does not override.
	SuccessStatus string
	// TlsVerify optionally overrides base TLS verification for this environment.
	// Nil does not override; &false / &true overrides explicitly.
	TlsVerify *bool
	// CaCert optionally overrides the base CA certificate for this environment.
	// Nil does not override.
	CaCert *string
	// Headers holds per-environment header overrides as a name→value map. Each
	// entry overrides (or adds) that one header by name on top of the base
	// headers, leaving the rest inherited. Use SetHeader / GetHeader.
	Headers map[string]string
}

ForwarderEnvironment is one environment's sparse override for a forwarder (ADR-056).

A forwarder's Environments map holds one of these per environment. Only the leaves you set are sent on save; everything you leave unset is inherited from the forwarder's base definition, and the server resolves base ⊕ overrides on delivery. The base definition delivers nowhere, so a forwarder delivers in an environment only when that environment's override sets Enabled=true.

Reach (and lazily create) an environment's override via (*Forwarder).Environment, then set leaves directly, e.g.

forwarder.Environment("production").Enabled = true
forwarder.Environment("production").URL = "https://prod.siem.example.com/in"
forwarder.Environment("production").SetHeader("DD-API-KEY", "prod-secret")

Reads are pure override: a leaf this environment does not override reads back as its zero value / nil, NOT the base value — the SDK does not merge in the base (forwarders resolve server-side). To see a base value, read the forwarder's base definition (forwarder.Configuration).

func (*ForwarderEnvironment) GetHeader added in v3.0.155

func (e *ForwarderEnvironment) GetHeader(name string) (string, bool)

GetHeader returns this environment's override for header name and whether it overrides that header.

func (*ForwarderEnvironment) SetHeader added in v3.0.155

func (e *ForwarderEnvironment) SetHeader(name, value string)

SetHeader overrides (or adds) a single header by name in this environment, allocating the Headers map on first use.

type ForwarderOption added in v3.0.52

type ForwarderOption func(*Forwarder)

ForwarderOption configures an unsaved Forwarder returned by AuditForwarders.New.

func WithForwardSmplkitEvents added in v3.0.123

func WithForwardSmplkitEvents(forward bool) ForwarderOption

WithForwardSmplkitEvents opts this forwarder into receiving smplkit's own platform change events (flag, configuration, and similar changes smplkit records about your resources) in addition to your audit events. When true, each platform change event is delivered through every environment this forwarder is enabled in. Omitting this option leaves the field unset, which the server treats as false.

func WithForwarderDescription added in v3.0.52

func WithForwarderDescription(description string) ForwarderOption

WithForwarderDescription sets the optional free-text description.

func WithForwarderEnvironments added in v3.0.120

func WithForwarderEnvironments(environments map[string]ForwarderEnvironment) ForwarderOption

WithForwarderEnvironments sets the per-environment override map that drives enablement. A forwarder delivers in an environment only when that environment's entry has Enabled=true; each entry is a flat overlay that overrides only the leaves it sets (URL, Method, headers, …), inheriting the base configuration for the rest. Every referenced environment must exist and be managed for the account. Without this option the forwarder is created enabled nowhere. The entries are copied, so later mutations of the passed map do not affect the forwarder; mutate via forwarder.Environment(env) instead.

func WithForwarderFilter added in v3.0.52

func WithForwarderFilter(filter map[string]interface{}) ForwarderOption

WithForwarderFilter sets the optional JSON Logic filter applied per event.

func WithForwarderTransform added in v3.0.52

func WithForwarderTransform(transformType ForwarderTransformType, transform interface{}) ForwarderOption

WithForwarderTransform sets the optional template applied to each event before delivery, paired with the engine used to evaluate it. transform is intentionally untyped — today JSONATA carries a string expression, but the field shape is engine-defined and future engines may carry richer payloads. Both arguments must be supplied together; passing a non-nil transform without a transformType (or vice versa) is rejected server-side.

type ForwarderTransformType added in v3.0.52

type ForwarderTransformType string

ForwarderTransformType identifies the engine used to evaluate a forwarder's transform expression. Currently only JSONATA is supported; additional engines may join later.

const (
	ForwarderTransformTypeJSONata ForwarderTransformType = "JSONATA"
)

Supported ForwarderTransformType values.

type ForwarderType added in v3.0.25

type ForwarderType string

ForwarderType is a SIEM streaming destination type. The audit service rejects any value outside the constants below with a 400.

const (
	ForwarderTypeDatadog   ForwarderType = "datadog"
	ForwarderTypeElastic   ForwarderType = "elastic"
	ForwarderTypeHoneycomb ForwarderType = "honeycomb"
	ForwarderTypeHTTP      ForwarderType = "http"
	ForwarderTypeNewRelic  ForwarderType = "new_relic"
	ForwarderTypeSplunkHEC ForwarderType = "splunk_hec"
	ForwarderTypeSumoLogic ForwarderType = "sumo_logic"
)

Supported ForwarderType values, alphabetical by wire constant.

type HttpConfig added in v3.0.114

type HttpConfig struct {
	// Method is the HTTP verb used when the job fires. Defaults to
	// JobHttpMethodPost when zero-valued.
	Method JobHttpMethod
	// URL is the absolute http:// or https:// destination the job calls.
	URL string
	// Headers are attached to every run's request, as a name→value map
	// (e.g. {"Authorization": "Bearer s3cr3t"}). Values carry credentials;
	// supply them plaintext on writes. Reads return them plaintext too, so a
	// Get → mutate → Save round-trip preserves them. Use SetHeader / GetHeader
	// to read and write individual headers without worrying about a nil map.
	Headers map[string]string
	// Body is the request body sent on each run. Nil sends an empty body
	// (suitable for a connectivity ping). Sent verbatim — pair with a
	// matching Content-Type header.
	Body *string
	// SuccessStatus is the response status that counts as success — an
	// exact code ("200", "204") or a class ("2xx", "5xx"). Defaults to
	// "2xx" server-side when zero-valued.
	SuccessStatus string
	// Timeout is the per-run timeout in seconds. A run that does not
	// complete within this many seconds fails with reason TIMEOUT.
	// Defaults to 30 server-side when zero-valued.
	Timeout int
	// TlsVerify controls whether the destination's TLS certificate chain
	// is verified. Pointer-valued so the zero-value HttpConfig is
	// unambiguous: nil means "leave at the server default of true", &false
	// means "skip verification", &true means "verify explicitly".
	TlsVerify *bool
	// CaCert is an optional PEM-encoded certificate (or bundle) trusted in
	// addition to the system CA store. Ignored when TlsVerify points to
	// false. Nil means "use system CAs only".
	CaCert *string
}

HttpConfig is the HTTP request a job performs when it fires (the job's "configuration"). It mirrors the shared HttpConfiguration used by audit forwarders but adds the two fields a scheduled job needs: a request Body and a per-run Timeout.

func (*HttpConfig) GetHeader added in v3.0.155

func (h *HttpConfig) GetHeader(name string) (string, bool)

GetHeader returns the value of header name and whether it is set.

func (*HttpConfig) SetHeader added in v3.0.155

func (h *HttpConfig) SetHeader(name, value string)

SetHeader sets (or replaces) a single request header by name, allocating the Headers map on first use.

type HttpConfiguration added in v3.0.52

type HttpConfiguration struct {
	// Method is the HTTP verb used for delivery. Defaults to
	// HttpMethodPost when zero-valued.
	Method HttpMethod
	// URL is the destination the audit service POSTs each event to.
	URL string
	// Headers are attached to every outbound request, as a name→value map
	// (e.g. {"DD-API-KEY": "s3cr3t"}). Values carry credentials; supply them
	// plaintext on writes. Reads return them plaintext too, so a Get → mutate
	// → Save round-trip preserves them. Use SetHeader / GetHeader to read and
	// write individual headers without worrying about a nil map.
	Headers map[string]string
	// SuccessStatus is the response status the destination must return
	// for delivery to count as success — an exact code ("200", "204")
	// or a class ("2xx", "4xx"). Defaults to "2xx" server-side when
	// zero-valued.
	SuccessStatus string
	// TlsVerify controls whether the destination's TLS certificate
	// chain is verified. Pointer-valued so the zero-value HttpConfiguration
	// is unambiguous: nil means "leave at the server default of true",
	// &false means "skip verification" (the trial-Splunk escape hatch),
	// &true means "verify explicitly". Prefer pinning the issuing CA via
	// CaCert for long-lived self-signed setups.
	TlsVerify *bool
	// CaCert is an optional PEM-encoded certificate (or bundle) trusted
	// in addition to the system CA store. Ignored when TlsVerify points
	// to false. Empty/nil string (the default) means "use system CAs only".
	CaCert *string
}

HttpConfiguration is the destination HTTP request configuration used by a forwarder of the HTTP family (HTTP, DATADOG, SPLUNK_HEC, SUMO_LOGIC, NEW_RELIC, HONEYCOMB, ELASTIC). Other transports will join this as members of a discriminated union under the Configuration field of Forwarder when they ship.

func (*HttpConfiguration) GetHeader added in v3.0.155

func (h *HttpConfiguration) GetHeader(name string) (string, bool)

GetHeader returns the value of header name and whether it is set.

func (*HttpConfiguration) SetHeader added in v3.0.155

func (h *HttpConfiguration) SetHeader(name, value string)

SetHeader sets (or replaces) a single request header by name, allocating the Headers map on first use.

type HttpMethod added in v3.0.52

type HttpMethod string

HttpMethod is the HTTP verb a forwarder uses when delivering an event. The audit service rejects any value outside the constants below with a 400.

const (
	HttpMethodDelete HttpMethod = "DELETE"
	HttpMethodGet    HttpMethod = "GET"
	HttpMethodPatch  HttpMethod = "PATCH"
	HttpMethodPost   HttpMethod = "POST"
	HttpMethodPut    HttpMethod = "PUT"
)

Supported HttpMethod values, alphabetical.

type ItemOption added in v3.0.77

type ItemOption func(*itemOpts)

ItemOption configures a config item setter (SetString / SetNumber / SetBoolean / SetJSON). Use WithItemDescription.

func WithItemDescription added in v3.0.77

func WithItemDescription(description string) ItemOption

WithItemDescription attaches a human-readable description to a config item. Ignored when setting a per-environment override (overrides store the raw value only; the declared type and description come from the base item).

type ItemType added in v3.0.128

type ItemType string

ItemType is the declared value type of a config item. It constrains the JSON shape of the item's value and of every per-environment override of the same key. Mirrors the flag-side FlagType enum.

const (
	// ItemTypeBoolean represents a boolean config item.
	ItemTypeBoolean ItemType = "BOOLEAN"
	// ItemTypeJSON represents a JSON config item.
	ItemTypeJSON ItemType = "JSON"
	// ItemTypeNumber represents a numeric config item.
	ItemTypeNumber ItemType = "NUMBER"
	// ItemTypeString represents a string config item.
	ItemTypeString ItemType = "STRING"
)

Supported ItemType values, alphabetical by wire constant.

type Job added in v3.0.114

type Job struct {
	// ID is the caller-supplied unique identifier for the job. Required
	// at create time (the jobs service does not auto-generate it) and
	// immutable thereafter.
	ID string
	// Name is the human-readable name for the job.
	Name string
	// Description is an optional free-text description.
	Description *string
	// Environments holds per-environment sparse overrides keyed by environment
	// key (e.g. "production", "development"). A job fires in an environment only
	// when Environments[env].Enabled is true. Each entry is a flat overlay that
	// overrides only the leaves it sets, inheriting the base definition for the
	// rest. Reach (and lazily create) an entry via Environment. For a recurring
	// job, supply this map to choose where it runs; a one-off job records the
	// single environment it was created in. Every referenced environment must
	// exist for the account. Enablement has no top-level field — use Enabled()
	// for the roll-up.
	Environments map[string]*JobEnvironment
	// Kind is how the job runs, derived server-side from Schedule (read-only):
	// JobKindRecurring (cron), JobKindManual (no schedule), or JobKindOneOff
	// ("now" / datetime). Nil on an unsaved Job; use IsRecurring / IsManual /
	// IsOneOff.
	Kind *JobKind
	// Type is the job type. Only "http" is supported today.
	Type string
	// Schedule is the base schedule every environment inherits unless it
	// overrides it, and the field that determines the job's Kind: empty for a
	// manual job (no schedule), a 5-field cron expression evaluated in UTC for
	// a recurring job, or an ISO-8601 datetime / "now" for a one-off job.
	Schedule string
	// Timezone is the base IANA timezone the cron Schedule is evaluated in
	// (e.g. "America/New_York"); empty means UTC. The base every environment
	// inherits unless it sets its own Timezone. The cron fires on this zone's
	// wall clock (DST-aware) while NextRunAt is still reported as a UTC instant.
	// Only valid on a recurring (cron) job — empty for a manual or one-off job.
	// Settable; sent on writes only when non-empty.
	Timezone string
	// RetryPolicy is the base retry policy for failed runs — the id of a
	// RetryPolicy (or the built-in "Default", which never retries), overridable
	// per environment via JobEnvironment.RetryPolicy. Empty (omitted on the
	// wire) means Default. Settable; sent on writes only when non-empty.
	RetryPolicy string
	// Configuration is the HTTP request the job performs when it fires.
	Configuration HttpConfig
	// ConcurrencyPolicy is how overlapping runs are handled. "ALLOW" (the
	// default and only value today) permits a new run to start while a
	// previous one is still in flight.
	ConcurrencyPolicy string
	// CreatedAt is when the job was created. Nil for an unsaved Job.
	CreatedAt *time.Time
	// UpdatedAt is when the job was last modified.
	UpdatedAt *time.Time
	// DeletedAt is when the job was deleted. Nil for live jobs.
	DeletedAt *time.Time
	// Version is a monotonic counter incremented on every update,
	// starting at 1.
	Version *int
	// contains filtered or unexported fields
}

Job is a unit of work: an HTTP request, run on a schedule or triggered on demand.

Active-record style: mutate fields directly and call Save(ctx) to persist, or Delete(ctx) to remove. The Job's id is caller-supplied, unique within the account, and immutable. A job is enabled per environment via Environments. A job's Kind follows from its Schedule: a recurring (cron) job may be enabled in several environments at once; a manual job (no schedule) runs only when triggered; a one-off ("now" / datetime) job is born in a single environment and is then spent.

func (*Job) Delete added in v3.0.114

func (job *Job) Delete(ctx context.Context) error

Delete removes this job on the server.

func (*Job) Enabled added in v3.0.114

func (job *Job) Enabled() bool

Enabled reports the read-only roll-up: true when the job is enabled in at least one environment. The jobs API has no top-level enabled field, so the wrapper derives it from the Environments map (and it stays correct for in-memory edits made before Save). Enable per environment via job.Environment(env).Enabled = true.

func (*Job) Environment added in v3.0.155

func (job *Job) Environment(environment string) *JobEnvironment

Environment returns the per-environment override for environment — the single place to read or set what this job overrides there (ADR-056).

It returns the JobEnvironment for environment, creating an empty one (and inserting it into Environments) on first access, so overrides can be set directly on the returned pointer:

job.Environment("production").Enabled = true
job.Environment("production").URL = "https://prod.example.com/warm"
job.Environment("production").SetHeader("Authorization", "Bearer prod")

Only the leaves you set are sent on save; everything else inherits the base definition (the server resolves base ⊕ overrides when the job fires).

func (*Job) IsManual added in v3.0.146

func (job *Job) IsManual() bool

IsManual reports whether this is a manual job — no schedule; runs only when triggered.

func (*Job) IsOneOff added in v3.0.146

func (job *Job) IsOneOff() bool

IsOneOff reports whether this is a one-off job — a single "now" / datetime run.

func (*Job) IsRecurring added in v3.0.146

func (job *Job) IsRecurring() bool

IsRecurring reports whether this is a recurring (cron-scheduled) job.

func (*Job) ListRuns added in v3.0.143

func (job *Job) ListRuns(ctx context.Context, input ListJobRunsInput) ([]*Run, error)

ListRuns returns this job's run history, most recent first.

input.Environment restricts the listing to runs stamped with that single environment (empty covers every environment you can access). input.Triggers restricts to runs started by any of those triggers; input.LastRunOnly collapses the result to the last completed run per environment. PageSize / After drive cursor pagination.

func (*Job) Save added in v3.0.114

func (job *Job) Save(ctx context.Context) error

Save creates this job on the server, or full-replaces it if it already exists. Upsert behavior keyed on CreatedAt: nil → create (POST), set → full-replace update (PUT). After the call, every field is refreshed from the server response (including CreatedAt, UpdatedAt, Version).

func (*Job) Trigger added in v3.0.143

func (job *Job) Trigger(ctx context.Context, environment string) (*Run, error)

Trigger starts one immediate, manual run of this job (a MANUAL run) and returns it. environment is the environment the run executes in; empty defaults to the client's configured environment.

type JobEnvironment added in v3.0.143

type JobEnvironment struct {
	// Enabled controls whether the job runs in this environment. Defaults to
	// false.
	Enabled bool
	// Schedule is an optional per-environment cron override that varies the
	// cadence for just this environment (recurring jobs only). Empty does not
	// override (inherits the job's base Schedule). When set, it must be a
	// 5-field cron expression; it cannot appear on a manual or one-off job, and
	// cannot change a job's kind.
	Schedule string
	// Timezone is an optional per-environment IANA timezone override for
	// evaluating this environment's cron Schedule (recurring jobs only). Empty
	// does not override (inherits the base Timezone, else UTC). When set, it
	// must be a valid IANA zone key (e.g. "America/New_York").
	Timezone string
	// RetryPolicy is an optional per-environment retry-policy override — the id
	// of a RetryPolicy (or "Default"); pass a saved policy's ID. Empty does not
	// override (inherits the job's base RetryPolicy).
	RetryPolicy string
	// URL optionally overrides the base destination URL for this environment.
	// Empty does not override.
	URL string
	// Method optionally overrides the base HTTP verb for this environment.
	// Empty does not override.
	Method JobHttpMethod
	// Timeout optionally overrides the base per-run timeout (seconds) for this
	// environment. Zero does not override.
	Timeout int
	// Body optionally overrides the base request body for this environment. Nil
	// does not override.
	Body *string
	// SuccessStatus optionally overrides the base success-status pattern for
	// this environment. Empty does not override.
	SuccessStatus string
	// TlsVerify optionally overrides base TLS verification for this environment.
	// Nil does not override; &false / &true overrides explicitly.
	TlsVerify *bool
	// CaCert optionally overrides the base CA certificate for this environment.
	// Nil does not override.
	CaCert *string
	// Headers holds per-environment header overrides as a name→value map. Each
	// entry overrides (or adds) that one header by name on top of the base
	// headers, leaving the rest inherited. Use SetHeader / GetHeader.
	Headers map[string]string
	// NextRunAt is the read-only next scheduled fire time in this environment.
	// Nil when the environment is not enabled, or once a one-off run has fired.
	// Populated on reads; never sent on writes.
	NextRunAt *time.Time
}

JobEnvironment is one environment's sparse override for a job (ADR-056).

A job's Environments map holds one of these per environment. Only the leaves you set are sent on save; everything you leave unset is inherited from the job's base definition, and the server resolves base ⊕ overrides when the job fires. The base definition is disabled everywhere, so a job runs in an environment only when that environment's override sets Enabled=true.

Reach (and lazily create) an environment's override via (*Job).Environment, then set leaves directly, e.g.

job.Environment("production").Enabled = true
job.Environment("production").URL = "https://prod.example.com/warm"
job.Environment("production").SetHeader("Authorization", "Bearer prod")

Reads are pure override: a leaf this environment does not override reads back as its zero value / nil, NOT the base value — the SDK does not merge in the base (jobs resolve server-side). To see a base value, read the job's base definition (job.Configuration, job.Schedule, …).

func (*JobEnvironment) GetHeader added in v3.0.155

func (e *JobEnvironment) GetHeader(name string) (string, bool)

GetHeader returns this environment's override for header name and whether it overrides that header.

func (*JobEnvironment) SetHeader added in v3.0.155

func (e *JobEnvironment) SetHeader(name, value string)

SetHeader overrides (or adds) a single header by name in this environment, allocating the Headers map on first use.

type JobHttpMethod added in v3.0.114

type JobHttpMethod string

JobHttpMethod is the HTTP verb a job uses when it fires. The jobs service rejects any value outside the constants below with a 400.

type JobKind added in v3.0.146

type JobKind string

JobKind is how a job runs, derived from its schedule (read-only).

  • JobKindManual: No schedule — never auto-fires; runs only when triggered.
  • JobKindOneOff: A "now" or datetime schedule — runs a single time, then is spent.
  • JobKindRecurring: A cron schedule — fires on a repeating cadence.

type JobOption added in v3.0.114

type JobOption func(*Job)

JobOption configures an unsaved Job returned by JobsClient.NewRecurringJob, NewManualJob, or Schedule.

func WithJobBirthEnvironment added in v3.0.143

func WithJobBirthEnvironment(environment string) JobOption

WithJobBirthEnvironment sets the single environment a one-off ("now" / datetime) job is born in, sent as the X-Smplkit-Environment header on create. Defaults to the client's configured environment. Ignored for recurring and manual jobs, whose environments come from WithJobEnvironments / SetEnabled.

func WithJobConcurrencyPolicy added in v3.0.114

func WithJobConcurrencyPolicy(policy string) JobOption

WithJobConcurrencyPolicy overrides how overlapping runs are handled. "ALLOW" (the default and only value today) permits a new run to start while a previous one is still in flight.

func WithJobDescription added in v3.0.114

func WithJobDescription(description string) JobOption

WithJobDescription sets the optional free-text description.

func WithJobEnvironments added in v3.0.143

func WithJobEnvironments(environments map[string]JobEnvironment) JobOption

WithJobEnvironments sets the per-environment override map that drives enablement. A job fires in an environment only when that environment's entry has Enabled=true; each entry is a flat overlay that overrides only the leaves it sets (URL, Method, Schedule, headers, …), inheriting the base configuration for the rest. Every referenced environment must exist for the account. Without this option (and without setting any Environment), a recurring job is enabled nowhere. The entries are copied, so later mutations of the passed map do not affect the job; mutate via job.Environment(env) instead.

func WithJobRetryPolicy added in v3.0.152

func WithJobRetryPolicy(retryPolicy string) JobOption

WithJobRetryPolicy sets the base retry policy for failed runs — the id of a RetryPolicy, overridable per environment. Empty (the default) uses the built-in "Default" policy, which never retries.

func WithJobTimezone added in v3.0.152

func WithJobTimezone(timezone string) JobOption

WithJobTimezone sets the base IANA timezone the cron schedule is evaluated in (e.g. "America/New_York"), DST-aware; empty means UTC. Every environment inherits it unless it overrides it. Only meaningful on a recurring (cron) job — manual and one-off jobs have no cron.

type JobsClient added in v3.0.126

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

JobsClient is the Smpl Jobs client.

Reachable as client.Jobs() (SmplClient) or constructed directly:

jobs, err := smplkit.NewJobsClient(smplkit.Config{APIKey: "sk_..."})
list, err := jobs.List(ctx, smplkit.ListJobsInput{})
for _, job := range list {
	fmt.Println(job.ID)
}

The surface is active-record job CRUD (NewRecurringJob / NewManualJob / Schedule / Get / List / Delete), the run-now action (Run), usage counters (Usage), and run history plus run actions (Runs).

func NewJobsClient added in v3.0.126

func NewJobsClient(cfg Config, opts ...ClientOption) (*JobsClient, error)

NewJobsClient creates a standalone Smpl Jobs client that resolves and owns its own jobs transport.

cfg.Environment is the default environment for environment-scoped operations — the environment a one-off job created through this client is born in, the default a manual run executes in, and the default scope for Runs().List. Leave it empty to leave these unset (the credential's permitted environment is implied where unambiguous).

func (*JobsClient) Delete added in v3.0.126

func (j *JobsClient) Delete(ctx context.Context, id string) error

Delete removes a job by id.

func (*JobsClient) Get added in v3.0.126

func (j *JobsClient) Get(ctx context.Context, id string) (*Job, error)

Get returns one job by id; the returned instance is bound to this client so job.Save(ctx) and job.Delete(ctx) work.

func (*JobsClient) List added in v3.0.126

func (j *JobsClient) List(ctx context.Context, input ListJobsInput) ([]*Job, error)

List returns the jobs for the authenticated account. Offset pagination via PageNumber / PageSize.

func (*JobsClient) NewManualJob added in v3.0.146

func (j *JobsClient) NewManualJob(
	id string,
	name string,
	configuration HttpConfig,
	opts ...JobOption,
) *Job

NewManualJob returns an unsaved manual Job bound to this client. Call (*Job).Save(ctx) to create it.

A manual job has no schedule — it never auto-fires and runs only when triggered via Run / (*Job).Trigger.

id is the caller-supplied unique identifier for the job — unique within the account and immutable; the service returns 409 if another live job already uses this id. name is the human-readable name. configuration is the HTTP request the job sends each time it runs.

Enablement is per environment: pass WithJobEnvironments, or set job.Environment(env).Enabled = true after construction, to choose where the job is triggerable. The remaining fields — description, retry policy (WithJobRetryPolicy), and concurrency policy — are set via the WithJob* options. A manual job has no cron, so WithJobTimezone does not apply.

func (*JobsClient) NewRecurringJob added in v3.0.146

func (j *JobsClient) NewRecurringJob(
	id string,
	name string,
	schedule string,
	configuration HttpConfig,
	opts ...JobOption,
) *Job

NewRecurringJob returns an unsaved recurring Job bound to this client. Call (*Job).Save(ctx) to create it.

id is the caller-supplied unique identifier for the job — unique within the account and immutable; the service returns 409 if another live job already uses this id. name is the human-readable name. schedule is the base cadence — a 5-field cron expression evaluated in UTC (e.g. "0 2 * * *") — that every environment inherits unless it sets its own override. configuration is the HTTP request the job sends each time it fires.

Enablement is per environment: pass WithJobEnvironments, or set job.Environment(env).Enabled = true after construction, to choose where the job is scheduled. The remaining fields — description, base timezone (WithJobTimezone), base retry policy (WithJobRetryPolicy), and concurrency policy — are set via the WithJob* options.

func (*JobsClient) RetryPolicies added in v3.0.152

func (j *JobsClient) RetryPolicies() *RetryPoliciesClient

RetryPolicies returns the retry-policy management sub-client. Retry policies are account-global — never environment-scoped.

func (*JobsClient) Run added in v3.0.126

func (j *JobsClient) Run(ctx context.Context, id string, environment string) (*Run, error)

Run triggers one immediate MANUAL run of the job and returns it.

environment is the environment the manual run executes in; empty defaults to the client's configured environment (and a single-environment credential implies it). The job must be enabled in the chosen environment. It is sent as the X-Smplkit-Environment header.

func (*JobsClient) Runs added in v3.0.126

func (j *JobsClient) Runs() *RunsClient

Runs returns the run history and run-action sub-client.

func (*JobsClient) Schedule added in v3.0.146

func (j *JobsClient) Schedule(
	id string,
	name string,
	schedule time.Time,
	configuration HttpConfig,
	opts ...JobOption,
) *Job

Schedule returns an unsaved one-off Job bound to this client. Call (*Job).Save(ctx) to create it.

A one-off job runs a single time at schedule and is then spent.

id is the caller-supplied unique identifier for the job — unique within the account and immutable; the service returns 409 if another live job already uses this id. name is the human-readable name. schedule is the instant the single run fires. configuration is the HTTP request the job sends when it runs.

The job is born in a single environment — WithJobBirthEnvironment, defaulting to the client's configured environment. A retry policy may be set via WithJobRetryPolicy; a one-off job has no cron, so WithJobTimezone does not apply.

func (*JobsClient) Usage added in v3.0.126

func (j *JobsClient) Usage(ctx context.Context) (*Usage, error)

Usage returns the current-period usage counters for the account.

type JsonFlagHandle

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

JsonFlagHandle is a typed handle for a JSON flag.

func (*JsonFlagHandle) Get

func (h *JsonFlagHandle) Get(ctx context.Context, contexts ...Context) map[string]interface{}

Get evaluates the flag and returns a typed map value.

The variadic contexts are optional Context entities to evaluate targeting rules against; when omitted, the ambient request context (if any) is used. Returns the evaluated JSON object, or this flag's default when no environment override or rule applies, or when the evaluated value is not a map.

func (*JsonFlagHandle) OnChange

func (h *JsonFlagHandle) OnChange(cb func(*FlagChangeEvent))

OnChange registers a flag-specific change listener.

type ListCategoriesInput added in v3.0.126

type ListCategoriesInput struct {
	// Environments scopes results to the given environment keys (e.g.
	// "production", "staging"). When omitted or empty, results are scoped
	// to your single accessible environment. The reserved value "smplkit"
	// selects platform change events that smplkit records about your own
	// resources (flags, configuration, and so on); these are not tied to a
	// deployment environment and are readable regardless of which
	// environments you manage. Multiple values are sent as a single
	// comma-separated filter[environment].
	Environments []string
	// PageNumber is the 1-based page index. Zero defers to the server default.
	PageNumber int
	// PageSize is items per page. Zero defers to the server default.
	PageSize int
	// MetaTotal asks the server to populate total / total_pages.
	MetaTotal bool
}

ListCategoriesInput is the filter + pagination input for AuditCategories.List.

type ListEventTypesInput added in v3.0.69

type ListEventTypesInput struct {
	// Environments scopes results to the given environment keys (e.g.
	// "production", "staging"). When omitted or empty, results are scoped
	// to your single accessible environment. The reserved value "smplkit"
	// selects platform change events that smplkit records about your own
	// resources (flags, configuration, and so on); these are not tied to a
	// deployment environment and are readable regardless of which
	// environments you manage. Multiple values are sent as a single
	// comma-separated filter[environment].
	Environments []string
	// FilterResourceType, when set, returns only event types seen with that
	// specific resource type.
	FilterResourceType string
	// PageNumber is the 1-based page index. Zero defers to the server default.
	PageNumber int
	// PageSize is items per page. Zero defers to the server default.
	PageSize int
	// MetaTotal asks the server to populate total / total_pages.
	MetaTotal bool
}

ListEventTypesInput is the filter + pagination input for AuditEventTypes.List.

type ListEventsInput added in v3.0.10

type ListEventsInput struct {
	// Environments scopes results to the given environment keys (e.g.
	// "production", "staging"). When omitted or empty, results are scoped
	// to your single accessible environment. The reserved value "smplkit"
	// selects platform change events that smplkit records about your own
	// resources (flags, configuration, and so on); these are not tied to a
	// deployment environment and are readable regardless of which
	// environments you manage. Multiple values are sent as a single
	// comma-separated filter[environment].
	Environments []string
	// EventType filters by exact event type slug.
	EventType string
	// ResourceType filters by exact resource type.
	ResourceType string
	// ResourceID filters by exact resource id.
	ResourceID string
	// ActorType filters by exact actor type. Matches the literal string
	// stored on the event.
	ActorType string
	// ActorID filters by exact actor id. Matches the literal string
	// stored on the event — any identifier scheme works.
	ActorID string
	// OccurredAtRange filters by occurred_at using the platform's range
	// syntax (e.g. "[2026-01-01T00:00:00Z,*)").
	OccurredAtRange string
	// Search performs a case-insensitive substring match against resource_id
	// or description. A search filter must be scoped — combine it with
	// occurred_at_range, or with both resource_type and resource_id — or the
	// request is rejected.
	Search string
	// PageSize is items per page. Zero defers to the server default.
	PageSize int
	// PageAfter is the opaque cursor returned as NextCursor by the
	// previous call. Empty fetches the first page.
	PageAfter string
}

ListEventsInput passes filters and pagination to AuditEvents.List.

type ListEventsPage added in v3.0.10

type ListEventsPage struct {
	// Events is the slice of audit events on this page.
	Events []AuditEvent
	// NextCursor is the opaque token to pass as PageAfter on the next
	// call. Empty when this is the last page.
	NextCursor string
}

ListEventsPage is one page of audit events. NextCursor is the opaque token to pass back as ListEventsInput.PageAfter on the next call; empty string means this is the last page.

type ListForwardersInput added in v3.0.16

type ListForwardersInput struct {
	// ForwarderType filters to a single destination type. Zero-valued
	// returns every type.
	ForwarderType ForwarderType
	// PageNumber is the 1-based page index. Zero defers to the server
	// default (page 1).
	PageNumber int
	// PageSize is items per page. Zero defers to the server default
	// (1000, max 1000).
	PageSize int
	// MetaTotal asks the server to populate total / total_pages in the
	// returned Pagination. Costs an extra COUNT query.
	MetaTotal bool
}

ListForwardersInput is the filter + pagination input for List.

type ListForwardersPage added in v3.0.16

type ListForwardersPage struct {
	// Forwarders is the slice of forwarders on this page, each bound
	// to its forwarders client so Save / Delete work directly.
	Forwarders []Forwarder
	// Pagination describes the page boundaries and totals (if
	// requested via MetaTotal).
	Pagination Pagination
}

ListForwardersPage is one page of forwarders.

type ListJobRunsInput added in v3.0.143

type ListJobRunsInput struct {
	// Environment restricts the listing to runs stamped with this environment.
	// Empty covers every environment you can access (subject to the client's
	// configured environment default).
	Environment string
	// Triggers restricts the listing to runs started by any of these triggers
	// (see RunTrigger) — e.g. []RunTrigger{RunTriggerRetry} for automatic
	// retries. Empty covers every trigger.
	Triggers []RunTrigger
	// LastRunOnly, when true, returns only the last completed run per
	// environment (in-flight runs excluded). Defaults to false.
	LastRunOnly bool
	// PageSize is runs per page. Zero defers to the server default.
	PageSize int
	// After is the opaque cursor returned by the previous call. Empty
	// fetches the first page.
	After string
}

ListJobRunsInput passes the optional single-environment filter and cursor pagination to (*Job).ListRuns.

type ListJobsInput added in v3.0.114

type ListJobsInput struct {
	// Kind filters to jobs of this JobKind. Nil lists recurring and manual
	// jobs; one-off jobs are omitted unless you pass JobKindOneOff.
	Kind *JobKind
	// Scheduled filters to jobs that have an upcoming fire in some environment
	// (true) or none (false) — the feed for an upcoming-runs view, which
	// includes one-offs. Nil does not filter on scheduling.
	Scheduled *bool
	// Name filters to jobs whose name contains this text (case-insensitive).
	// Nil returns all.
	Name *string
	// PageNumber is the 1-based page index. Zero defers to the server
	// default (page 1).
	PageNumber int
	// PageSize is items per page. Zero defers to the server default.
	PageSize int
}

ListJobsInput passes filters and pagination to JobsClient.List.

type ListOption added in v3.0.49

type ListOption func(*listOptions)

ListOption configures a paginated list call. Pass options to any list method to request a specific page or page size:

loggers, err := client.Logging().Loggers().List(ctx, smplkit.WithPageSize(50))

Omit all options to let the server apply its defaults (page 1, page size 1000). The wrapper does not loop on the caller's behalf — see each list method's docs for the slice it returns.

func WithPageNumber added in v3.0.49

func WithPageNumber(n int) ListOption

WithPageNumber requests a specific 1-based page from a list endpoint. Values < 1 are rejected by the server with a 400.

func WithPageSize added in v3.0.49

func WithPageSize(n int) ListOption

WithPageSize requests a specific page size from a list endpoint. The server caps this at 1000; values outside [1, 1000] are rejected with a 400.

type ListResourceTypesInput added in v3.0.34

type ListResourceTypesInput struct {
	// Environments scopes results to the given environment keys (e.g.
	// "production", "staging"). When omitted or empty, results are scoped
	// to your single accessible environment. The reserved value "smplkit"
	// selects platform change events that smplkit records about your own
	// resources (flags, configuration, and so on); these are not tied to a
	// deployment environment and are readable regardless of which
	// environments you manage. Multiple values are sent as a single
	// comma-separated filter[environment].
	Environments []string
	// PageNumber is the 1-based page index. Zero defers to the server default.
	PageNumber int
	// PageSize is items per page. Zero defers to the server default.
	PageSize int
	// MetaTotal asks the server to populate total / total_pages.
	MetaTotal bool
}

ListResourceTypesInput is the pagination input for AuditResourceTypes.List.

type ListRetryPoliciesInput added in v3.0.152

type ListRetryPoliciesInput struct {
	// Name filters to policies whose name contains this text (case-insensitive).
	// Nil returns all.
	Name *string
	// PageNumber is the 1-based page index. Zero defers to the server default
	// (page 1).
	PageNumber int
	// PageSize is items per page. Zero defers to the server default.
	PageSize int
}

ListRetryPoliciesInput passes filters and pagination to RetryPoliciesClient.List.

type ListRunsInput added in v3.0.114

type ListRunsInput struct {
	// Job scopes the listing to a single job's run history. Empty returns
	// runs across all jobs.
	Job string
	// Environments restricts the listing to runs stamped with any of these
	// environment keys, sent as a single comma-separated filter[environment].
	// Empty falls back to the client's configured environment (if any),
	// otherwise covers every environment you can access.
	Environments []string
	// Triggers restricts the listing to runs started by any of these triggers
	// (see RunTrigger) — e.g. []RunTrigger{RunTriggerRetry} for automatic
	// retries. Sent as a comma-separated filter[trigger]. Empty covers every
	// trigger.
	Triggers []RunTrigger
	// LastRunOnly, when true, collapses the result to the last completed
	// (succeeded / failed / canceled) run per job-and-environment; in-flight
	// runs are excluded. The other filters apply first, then the collapse. The
	// query param is sent only when true.
	LastRunOnly bool
	// PageSize is runs per page. Zero defers to the server default.
	PageSize int
	// After is the opaque cursor returned by the previous call. Empty
	// fetches the first page.
	After string
}

ListRunsInput passes filters and cursor pagination to RunsClient.List.

type LiveConfig

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

LiveConfig is a live, dict-like, read-only proxy for a config's resolved values. Returned by ConfigClient.Subscribe. Every read goes through the client's resolved-config cache, so WebSocket updates are picked up automatically.

Customer mutation paths are absent: there is no Set / Put / Delete method on LiveConfig. To mutate configs use the editable record:

client.Config().Get(ctx, id) // active-record model with Save / Delete

func (*LiveConfig) Get

func (lc *LiveConfig) Get(key string) (interface{}, bool)

Get returns a single resolved value by key. The second return is false if the key is absent.

func (*LiveConfig) Has

func (lc *LiveConfig) Has(key string) bool

Has reports whether a resolved value exists for the given key.

func (*LiveConfig) ID

func (lc *LiveConfig) ID() string

ID returns the config ID this proxy reads from.

func (*LiveConfig) Keys

func (lc *LiveConfig) Keys() []string

Keys returns a snapshot of the resolved key set in unspecified order.

func (*LiveConfig) Len

func (lc *LiveConfig) Len() int

Len returns the number of resolved keys.

func (*LiveConfig) OnChange

func (lc *LiveConfig) OnChange(cb func(*ConfigChangeEvent))

OnChange registers a change listener scoped to this config: it fires when any item in this config changes.

func (*LiveConfig) OnChangeKey

func (lc *LiveConfig) OnChangeKey(key string, cb func(*ConfigChangeEvent))

OnChangeKey registers a listener that fires only when the named item in this config changes. Mirrors `proxy.on_change(item_key=...)`.

func (*LiveConfig) Value

func (lc *LiveConfig) Value() map[string]interface{}

Value returns a defensive copy of the latest resolved values.

type LogGroup

type LogGroup struct {
	// ID is the log group identifier.
	ID string
	// Name is the display name for the log group.
	Name string
	// Level is the base log level (nil = inherit).
	Level *LogLevel
	// Group is the parent group ID (nil = no parent).
	Group *string
	// Environments maps environment names to their configuration.
	Environments map[string]interface{}
	// CreatedAt is the creation timestamp.
	CreatedAt *time.Time
	// UpdatedAt is the last-modified timestamp.
	UpdatedAt *time.Time
	// contains filtered or unexported fields
}

LogGroup represents a log group resource from the smplkit platform.

func (*LogGroup) ClearAllEnvironmentLevels

func (g *LogGroup) ClearAllEnvironmentLevels()

ClearAllEnvironmentLevels clears all environment-specific levels. Call Save to persist.

func (*LogGroup) ClearBaseLevel deprecated added in v3.0.127

func (g *LogGroup) ClearBaseLevel()

ClearBaseLevel clears the log group's base level.

Deprecated: Use ClearLevel("") for the unified per-env verb.

func (*LogGroup) ClearEnvironmentLevel

func (g *LogGroup) ClearEnvironmentLevel(env string)

ClearEnvironmentLevel clears the log level for a specific environment. Call Save to persist.

func (*LogGroup) ClearLevel

func (g *LogGroup) ClearLevel(environment string)

ClearLevel clears the level. environment="" clears the log group's base level (causing it to inherit from its parent); non-empty clears the per-env override.

Call LogGroup.Save(ctx) to persist.

func (*LogGroup) Delete added in v3.0.126

func (g *LogGroup) Delete(ctx context.Context) error

Delete removes the log group from the server. Equivalent to client.Logging().LogGroups().Delete(ctx, g.ID).

func (*LogGroup) Save

func (g *LogGroup) Save(ctx context.Context) error

Save persists the log group to the server (create or update). The LogGroup instance is updated with the server response.

func (*LogGroup) SetBaseLevel deprecated added in v3.0.127

func (g *LogGroup) SetBaseLevel(level LogLevel)

SetBaseLevel sets the log group's base level (no environment scoping).

Deprecated: Use SetLevel(level, "") for the unified per-environment verb.

func (*LogGroup) SetEnvironmentLevel

func (g *LogGroup) SetEnvironmentLevel(env string, level LogLevel)

SetEnvironmentLevel sets the log level for a specific environment. Call Save to persist.

func (*LogGroup) SetLevel

func (g *LogGroup) SetLevel(level LogLevel, environment string)

SetLevel sets the level. environment="" updates the log group's base level; non-empty scopes to that environment.

Call LogGroup.Save(ctx) to persist.

func (*LogGroup) TypedEnvironments

func (g *LogGroup) TypedEnvironments() map[string]LoggerEnvironment

TypedEnvironments returns a typed, read-only view of per-environment configuration on a LogGroup.

type LogGroupOption

type LogGroupOption func(*LogGroup)

LogGroupOption configures an unsaved LogGroup returned by LogGroupsClient.New.

func WithLogGroupName

func WithLogGroupName(name string) LogGroupOption

WithLogGroupName sets the display name for a log group.

func WithLogGroupParent

func WithLogGroupParent(groupID string) LogGroupOption

WithLogGroupParent sets the parent group UUID.

type LogGroupsClient added in v3.0.126

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

LogGroupsClient is the surface for client.Logging().LogGroups() — log group CRUD.

Obtain one via client.Logging().LogGroups().

func (*LogGroupsClient) Delete added in v3.0.126

func (m *LogGroupsClient) Delete(ctx context.Context, id string) error

Delete deletes a log group by id.

func (*LogGroupsClient) Get added in v3.0.126

func (m *LogGroupsClient) Get(ctx context.Context, id string) (*LogGroup, error)

Get fetches the editable LogGroup resource by id. It returns a *NotFoundError when no log group with that id exists.

func (*LogGroupsClient) List added in v3.0.126

func (m *LogGroupsClient) List(ctx context.Context, opts ...ListOption) ([]*LogGroup, error)

List lists log groups for the authenticated account.

Without options the server applies its defaults (page 1, page size 1000). Use WithPageNumber / WithPageSize to walk additional pages. The wrapper does not loop — callers that want every log group should iterate until a short page is returned.

func (*LogGroupsClient) New added in v3.0.126

func (m *LogGroupsClient) New(id string, opts ...LogGroupOption) *LogGroup

New returns a new unsaved LogGroup. Call group.Save(ctx) to persist.

type LogLevel

type LogLevel string

LogLevel represents a smplkit canonical log level.

const (
	// LogLevelTrace is the most verbose level; finer-grained than DEBUG.
	LogLevelTrace LogLevel = "TRACE"
	// LogLevelDebug emits diagnostic detail useful while debugging.
	LogLevelDebug LogLevel = "DEBUG"
	// LogLevelInfo is the default level for routine informational messages.
	LogLevelInfo LogLevel = "INFO"
	// LogLevelWarn signals a non-fatal condition that warrants attention.
	LogLevelWarn LogLevel = "WARN"
	// LogLevelError signals a failure that the caller should handle.
	LogLevelError LogLevel = "ERROR"
	// LogLevelFatal signals a non-recoverable failure.
	LogLevelFatal LogLevel = "FATAL"
	// LogLevelSilent suppresses all output.
	LogLevelSilent LogLevel = "SILENT"
)

Supported LogLevel values, declared in increasing order of severity to match Go's log/slog convention (where higher-severity levels have larger numeric values). LogLevelSilent is the cut-off above any real severity and suppresses all output.

type Logger

type Logger struct {
	// ID is the logger identifier.
	ID string
	// Name is the display name for the logger.
	Name string
	// Level is the base log level (nil = inherit).
	Level *LogLevel
	// Group is the group ID (nil = no group).
	Group *string
	// Managed indicates whether smplkit controls this logger's level.
	Managed bool
	// Sources holds source metadata.
	Sources []map[string]interface{}
	// Environments maps environment names to their configuration.
	Environments map[string]interface{}
	// CreatedAt is the creation timestamp.
	CreatedAt *time.Time
	// UpdatedAt is the last-modified timestamp.
	UpdatedAt *time.Time
	// contains filtered or unexported fields
}

Logger represents a logger resource from the smplkit platform.

func (*Logger) ClearAllEnvironmentLevels

func (l *Logger) ClearAllEnvironmentLevels()

ClearAllEnvironmentLevels clears all environment-specific levels. Call Save to persist.

func (*Logger) ClearBaseLevel deprecated

func (l *Logger) ClearBaseLevel()

ClearBaseLevel clears the logger's base level.

Deprecated: Use ClearLevel("") for the unified per-env verb.

func (*Logger) ClearEnvironmentLevel

func (l *Logger) ClearEnvironmentLevel(env string)

ClearEnvironmentLevel clears the log level for a specific environment. Call Save to persist.

func (*Logger) ClearLevel

func (l *Logger) ClearLevel(environment string)

ClearLevel clears the level. environment="" clears the logger's base level (causing it to inherit from its parent); non-empty clears the per-env override.

func (*Logger) Delete

func (l *Logger) Delete(ctx context.Context) error

Delete removes the logger from the server. Equivalent to client.Logging().Loggers().Delete(ctx, l.ID).

func (*Logger) Save

func (l *Logger) Save(ctx context.Context) error

Save persists the logger to the server. PUT has upsert semantics: the server creates the logger if it does not exist. The Logger instance is updated with the server response.

func (*Logger) SetBaseLevel deprecated

func (l *Logger) SetBaseLevel(level LogLevel)

SetBaseLevel sets the logger's base level (no environment scoping).

Deprecated: Use SetLevel(level, "") for the unified per-environment verb.

func (*Logger) SetEnvironmentLevel

func (l *Logger) SetEnvironmentLevel(env string, level LogLevel)

SetEnvironmentLevel sets the log level for a specific environment. Call Save to persist.

func (*Logger) SetLevel

func (l *Logger) SetLevel(level LogLevel, environment string)

SetLevel sets the level. environment="" updates the logger's base level; non-empty scopes to that environment.

func (*Logger) TypedEnvironments

func (l *Logger) TypedEnvironments() map[string]LoggerEnvironment

TypedEnvironments returns a typed, read-only view of per-environment configuration on a Logger. Each value's Level() is a *LogLevel — nil when no override is set for that environment.

type LoggerChangeEvent

type LoggerChangeEvent struct {
	// ID is the normalized logger id whose effective level just moved.
	ID string
	// Level is the newly-applied effective level.
	Level *LogLevel
	// Source identifies the trigger ("websocket", "manual").
	Source string
}

LoggerChangeEvent describes a logger whose effective level was just re-applied. The SDK fires one event per logger per trigger — never a batch / summary event and never a deletion-flavored event. If a trigger removes a logger from server-side tracking, the deleted key itself fires nothing; dependents whose effective level moves fire normal change events through this same payload.

type LoggerEnvironment

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

LoggerEnvironment is the per-environment configuration on a Logger or LogGroup — currently just an optional level override. Frozen.

func NewLoggerEnvironment

func NewLoggerEnvironment(level *LogLevel) LoggerEnvironment

NewLoggerEnvironment constructs a LoggerEnvironment. Used by the SDK when parsing server responses.

func (LoggerEnvironment) Level

func (e LoggerEnvironment) Level() *LogLevel

Level returns the per-env level override, or nil if no override is set (in which case inheritance applies).

type LoggerOption

type LoggerOption func(*Logger)

LoggerOption configures an unsaved Logger returned by LoggersClient.New.

func WithLoggerManaged

func WithLoggerManaged(managed bool) LoggerOption

WithLoggerManaged sets whether smplkit controls this logger's level.

func WithLoggerName

func WithLoggerName(name string) LoggerOption

WithLoggerName sets the display name for a logger.

type LoggerSource

type LoggerSource struct {
	// ID is the logger name (e.g. "sqlalchemy.engine"). It is normalized to
	// lowercase with slashes and colons replaced by dots before being sent
	// to the API.
	ID string
	// Service overrides the client's own service name.
	// Nil means use the client's service.
	Service *string
	// Environment overrides the client's own environment.
	// Nil means use the client's environment.
	Environment *string
	// ResolvedLevel is the effective log level observed for this source.
	ResolvedLevel *LogLevel
	// Level is the explicit (configured) log level, when it differs from
	// ResolvedLevel. Nil when the level is inherited.
	Level *LogLevel
}

LoggerSource describes a logger to register via client.Logging().Loggers().Register (and RegisterSources).

Used both for buffered runtime discovery — the SDK queues sources as its adapters discover loggers — and for explicit registration from setup code that already knows the (service, environment) the loggers belong to, e.g. sample-data loading or cross-service migration without running the actual service process.

func NewLoggerSource

func NewLoggerSource(id string, opts ...LoggerSourceOption) LoggerSource

NewLoggerSource creates a LoggerSource with the given logger ID and options.

type LoggerSourceOption

type LoggerSourceOption func(*LoggerSource)

LoggerSourceOption configures a LoggerSource.

func WithLoggerSourceEnvironment

func WithLoggerSourceEnvironment(env string) LoggerSourceOption

WithLoggerSourceEnvironment sets an explicit environment for the source.

func WithLoggerSourceLevel added in v3.0.127

func WithLoggerSourceLevel(level LogLevel) LoggerSourceOption

WithLoggerSourceLevel sets the explicit (configured) log level for the source. Leave it unset when the level is inherited.

func WithLoggerSourceResolvedLevel

func WithLoggerSourceResolvedLevel(level LogLevel) LoggerSourceOption

WithLoggerSourceResolvedLevel sets the effective log level for the source.

func WithLoggerSourceService

func WithLoggerSourceService(service string) LoggerSourceOption

WithLoggerSourceService sets an explicit service name for the source.

type LoggersClient added in v3.0.126

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

LoggersClient is the surface for client.Logging().Loggers() — logger CRUD plus the discovery buffer. The buffer is owned by the fused LoggingClient and shared here so discovery (driven by LoggingClient.Install) and explicit Register drain through one queue.

Obtain one via client.Logging().Loggers().

func (*LoggersClient) Delete added in v3.0.126

func (m *LoggersClient) Delete(ctx context.Context, id string) error

Delete deletes a logger by id.

func (*LoggersClient) Flush added in v3.0.126

func (m *LoggersClient) Flush(ctx context.Context) error

Flush drains the buffer and POSTs pending logger sources to the bulk endpoint. Returns nil immediately when there is nothing to flush.

func (*LoggersClient) FlushSync added in v3.0.126

func (m *LoggersClient) FlushSync(ctx context.Context) error

FlushSync is an alias of Flush for the periodic-flush path.

func (*LoggersClient) Get added in v3.0.126

func (m *LoggersClient) Get(ctx context.Context, id string) (*Logger, error)

Get fetches the editable Logger resource by id. It returns a *NotFoundError when no logger with that id exists.

func (*LoggersClient) List added in v3.0.126

func (m *LoggersClient) List(ctx context.Context, opts ...ListOption) ([]*Logger, error)

List lists loggers for the authenticated account.

Without options the server applies its defaults (page 1, page size 1000). Use WithPageNumber / WithPageSize to walk additional pages. The wrapper does not loop — callers that want every logger should iterate until a short page is returned.

func (*LoggersClient) New added in v3.0.126

func (m *LoggersClient) New(id string, opts ...LoggerOption) *Logger

New returns a new unsaved Logger. Call logger.Save(ctx) to persist.

id is the identifier for the logger (its normalized name); the display name defaults to id. managed defaults to true (WithLoggerManaged overrides it): when true, smplkit controls this logger's level at runtime; set false to register the logger for visibility without taking over its level.

func (*LoggersClient) PendingCount added in v3.0.126

func (m *LoggersClient) PendingCount() int

PendingCount returns the number of sources queued and awaiting flush.

func (*LoggersClient) Register added in v3.0.126

func (m *LoggersClient) Register(ctx context.Context, sources []LoggerSource, flush bool) error

Register queues one or more logger sources for registration with the server. Sources are buffered locally and coalesced into the shared discovery buffer, then sent in a batch.

sources are the logger sources to queue. flush, when true, sends the buffered batch immediately instead of waiting for it to fill.

func (*LoggersClient) RegisterSources added in v3.0.126

func (m *LoggersClient) RegisterSources(ctx context.Context, sources []LoggerSource) error

RegisterSources registers a batch of logger sources observed in external services. This is useful for seeding source-discovery data without running the actual service process — e.g. for sample-data loading or cross-service migration.

type LoggingClient

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

LoggingClient is the Smpl Logging client.

One client exposes the full surface, reachable as client.Logging() or constructed directly via NewLoggingClient.

Smpl Logging has two surfaces on a single client, mirroring how the config, flags, audit, and jobs clients expose their full surface from one class:

  • CRUD surface — works without Install. Two sub-clients:
  • client.Logging().Loggers() — logger CRUD + discovery: New / List / Get / Delete plus Register / Flush / FlushSync / PendingCount.
  • client.Logging().LogGroups() — log-group CRUD: New / List / Get / Delete.

The fused client owns the logger-discovery buffer directly; the Loggers sub-client shares that same buffer so discovery and explicit registration drain through one queue.

  • Live surface — directly on the client. RegisterAdapter is a PRE-install configuration call (allowed before Install). Install opens the live connection (hooks the app's logging framework via adapters, discovers loggers, fetches + applies levels, opens the shared WebSocket). OnChange / Refresh require Install first; calling them earlier returns a *NotInstalledError.

The client supports two construction shapes:

  • Wired into SmplClient — borrows the parent's logging transport for both runtime fetch and CRUD and the parent's shared WebSocket for the live channel. This is the common path.
  • Standalone — NewLoggingClient(cfg, ...) builds and owns its own logging transport and an app transport (the WebSocket gateway lives on the app service), and on Install opens and owns its own WebSocket.

func NewLoggingClient added in v3.0.126

func NewLoggingClient(cfg Config, opts ...ClientOption) (*LoggingClient, error)

NewLoggingClient creates a standalone Smpl Logging client that builds and owns its own generated logging transport and, on first live use, its own WebSocket against the event gateway (the WebSocket gateway lives on the app service).

Logging needs environment + service: the environment scopes runtime level resolution and discovery declarations, and the service scopes discovery declarations. Both resolve from cfg (or ~/.smplkit / env vars).

func (*LoggingClient) Flush added in v3.0.4

func (c *LoggingClient) Flush(ctx context.Context) error

Flush sends any pending logger discoveries to the server immediately via the bulk-register endpoint. Discoveries are buffered as adapter hooks fire (e.g. slog WithGroup creating a sub-handler) and on explicit RegisterLogger calls; they are normally flushed on a 5-second interval. Call this when you need them sent right away — e.g. before exiting a short-lived script. Returns nil immediately when the buffer is empty.

func (*LoggingClient) Install

func (c *LoggingClient) Install(ctx context.Context) error

Install hooks smplkit into the application's logging machinery.

Loads adapters, scans existing loggers, applies levels from the smplkit server, and wires WebSocket handlers for live updates. This IS the explicit consent gate — OnChange / Refresh require it first.

Idempotent — safe to call multiple times.

func (*LoggingClient) LogGroups added in v3.0.126

func (c *LoggingClient) LogGroups() *LogGroupsClient

LogGroups returns the log-group CRUD sub-client.

func (*LoggingClient) Loggers added in v3.0.126

func (c *LoggingClient) Loggers() *LoggersClient

Loggers returns the logger CRUD + discovery sub-client.

func (*LoggingClient) OnChange

func (c *LoggingClient) OnChange(cb func(*LoggerChangeEvent)) error

OnChange registers a global change listener.

Requires Install first; returns a *NotInstalledError otherwise.

func (*LoggingClient) OnChangeKey

func (c *LoggingClient) OnChangeKey(key string, cb func(*LoggerChangeEvent)) error

OnChangeKey registers a key-scoped change listener.

Requires Install first; returns a *NotInstalledError otherwise.

func (*LoggingClient) Refresh added in v3.0.4

func (c *LoggingClient) Refresh(ctx context.Context) error

Refresh re-fetches all loggers and groups and fires listener events for any deltas.

Requires Install first; returns a *NotInstalledError otherwise.

func (*LoggingClient) RegisterAdapter

func (c *LoggingClient) RegisterAdapter(adapter adapters.LoggingAdapter)

RegisterAdapter registers a logging adapter. Must be called before Install().

If called at least once, auto-loading is disabled — only explicitly registered adapters are used. This is a pre-install configuration call: it is intentionally NOT gated by Install.

func (*LoggingClient) RegisterLogger

func (c *LoggingClient) RegisterLogger(name string, level LogLevel)

RegisterLogger explicitly registers a logger name for smplkit management. Call before or after Install().

type NotFoundError

type NotFoundError struct {
	// Base is the embedded base Error carrying the HTTP status, message,
	// raw response body, and any parsed JSON:API error details.
	Base Error
}

NotFoundError is raised when a requested resource does not exist.

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

Error implements the error interface.

func (*NotFoundError) Unwrap

func (e *NotFoundError) Unwrap() error

Unwrap returns the embedded Error so errors.Is/errors.As walk the chain.

type NotInstalledError added in v3.0.126

type NotInstalledError struct {
	// Base is the embedded base Error carrying the HTTP status, message,
	// raw response body, and any parsed JSON:API error details.
	Base Error
}

NotInstalledError is raised when a logging operation is attempted before Install.

Smpl Logging hooks into your application's logging framework, so it stays opt-in: its live surface requires an explicit LoggingClient.Install first. Config and flags connect lazily on first live use and never raise this.

func (*NotInstalledError) Error added in v3.0.126

func (e *NotInstalledError) Error() string

Error implements the error interface.

func (*NotInstalledError) Unwrap added in v3.0.126

func (e *NotInstalledError) Unwrap() error

Unwrap returns the embedded Error so errors.Is/errors.As walk the chain.

type NumberFlagHandle

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

NumberFlagHandle is a typed handle for a numeric flag.

func (*NumberFlagHandle) Get

func (h *NumberFlagHandle) Get(ctx context.Context, contexts ...Context) float64

Get evaluates the flag and returns a typed float64 value.

The variadic contexts are optional Context entities to evaluate targeting rules against; when omitted, the ambient request context (if any) is used. Returns the evaluated numeric value, or this flag's default when no environment override or rule applies, or when the evaluated value is not a numeric type.

func (*NumberFlagHandle) OnChange

func (h *NumberFlagHandle) OnChange(cb func(*FlagChangeEvent))

OnChange registers a flag-specific change listener.

type Op added in v3.0.128

type Op string

Op is a comparison operator accepted by Rule.When.

Prefer the Op constants (OpEQ, OpContains, …) over raw operator strings so the IDE can validate calls. Op is a string type, so a raw operator literal (for example "==" or "contains") is still accepted for backward compatibility.

const (
	// OpContains matches when the value is contained in the variable
	// (JSON Logic "in" with reversed operands).
	OpContains Op = "contains"
	// OpEQ matches when the variable equals the value.
	OpEQ Op = "=="
	// OpGT matches when the variable is greater than the value.
	OpGT Op = ">"
	// OpGTE matches when the variable is greater than or equal to the value.
	OpGTE Op = ">="
	// OpIN matches when the variable is contained in the value.
	OpIN Op = "in"
	// OpLT matches when the variable is less than the value.
	OpLT Op = "<"
	// OpLTE matches when the variable is less than or equal to the value.
	OpLTE Op = "<="
	// OpNEQ matches when the variable does not equal the value.
	OpNEQ Op = "!="
)

Supported Op values, alphabetical by name.

type Pagination added in v3.0.47

type Pagination struct {
	// Page is the 1-based page number that served the response.
	Page int
	// Size is the page size that served the response.
	Size int
	// Total is the total number of matching items across all pages.
	// Populated only when the request set MetaTotal=true.
	Total *int
	// TotalPages is the total number of pages at the requested page size.
	// Populated only when the request set MetaTotal=true.
	TotalPages *int
}

Pagination is the offset-pagination meta block returned on every standard list response. Page and Size always reflect the parameters that served the response. Total and TotalPages are populated only when the request set MetaTotal=true.

type PaymentRequiredError added in v3.0.34

type PaymentRequiredError struct {
	// Base is the embedded base Error carrying the HTTP status, message,
	// raw response body, and any parsed JSON:API error details.
	Base Error
}

PaymentRequiredError is raised when the server rejects a request with a 402 — typically because the account's subscription plan doesn't include the required entitlement. Surfaced as a typed error so callers that care about plan-gated paths can errors.As on it; no curated method in the SDK anticipates 402 specifically.

func (*PaymentRequiredError) Error added in v3.0.34

func (e *PaymentRequiredError) Error() string

Error implements the error interface.

func (*PaymentRequiredError) Unwrap added in v3.0.34

func (e *PaymentRequiredError) Unwrap() error

Unwrap returns the embedded Error so errors.Is/errors.As walk the chain.

type PlatformClient added in v3.0.126

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

PlatformClient is the Smpl Platform client.

Groups the account-wide CRUD resources that aren't owned by a single product, reachable as client.Platform() (SmplClient) or constructed directly:

platform, err := smplkit.NewPlatformClient(smplkit.Config{APIKey: "sk_..."})
prod := platform.Environments().New("production", "Production")
prod.Save(ctx)
svcs, err := platform.Services().List(ctx)

Sub-clients: Environments, Services, Contexts, ContextTypes. Pure CRUD — no Install required.

func NewPlatformClient added in v3.0.126

func NewPlatformClient(cfg Config, opts ...ClientOption) (*PlatformClient, error)

NewPlatformClient creates a standalone Smpl Platform client that owns its own app transport and context-registration buffer.

Construction has zero side effects: no service registration, no metrics, no websocket — just CRUD against the app service.

func (*PlatformClient) Close added in v3.0.126

func (p *PlatformClient) Close() error

Close releases resources held by a standalone PlatformClient. A wired client borrows the parent's app transport and closes nothing; the underlying http.Client is pooled by net/http, so this is a no-op kept for symmetry and a clean defer point.

func (*PlatformClient) ContextTypes added in v3.0.126

func (p *PlatformClient) ContextTypes() *ContextTypesClient

ContextTypes returns the sub-client for context-type CRUD operations.

func (*PlatformClient) Contexts added in v3.0.126

func (p *PlatformClient) Contexts() *ContextsClient

Contexts returns the sub-client for context registration and read/delete operations.

func (*PlatformClient) Environments added in v3.0.126

func (p *PlatformClient) Environments() *EnvironmentsClient

Environments returns the sub-client for environment CRUD operations.

func (*PlatformClient) Services added in v3.0.126

func (p *PlatformClient) Services() *ServicesClient

Services returns the sub-client for service CRUD operations.

type ResourceTypeListPage added in v3.0.34

type ResourceTypeListPage struct {
	// ResourceTypes is the slice of resource types on this page.
	ResourceTypes []AuditResourceType
	// Pagination describes the page boundaries and totals (if requested).
	Pagination Pagination
}

ResourceTypeListPage is one page of resource-type slugs.

type RetryPoliciesClient added in v3.0.152

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

RetryPoliciesClient is the client.Jobs().RetryPolicies() surface: manage reusable retry policies. A RetryPolicy is an active record — build one with New, set fields, and call Save(ctx); then reference it from a job's RetryPolicy (see WithJobRetryPolicy and (*Job).SetRetryPolicy). Retry policies are account-global — never environment-scoped.

func (*RetryPoliciesClient) Delete added in v3.0.152

func (c *RetryPoliciesClient) Delete(ctx context.Context, id string) error

Delete removes a retry policy by id.

func (*RetryPoliciesClient) Get added in v3.0.152

Get returns one retry policy by id; the returned instance is bound to this client so policy.Save(ctx) and policy.Delete(ctx) work.

func (*RetryPoliciesClient) List added in v3.0.152

List returns the retry policies for the authenticated account. Offset pagination via PageNumber / PageSize; Name filters on a case-insensitive substring of the policy name.

func (*RetryPoliciesClient) New added in v3.0.152

func (c *RetryPoliciesClient) New(
	id string,
	name string,
	maxRetries int,
	backoff Backoff,
	delaySeconds int,
	opts ...RetryPolicyOption,
) *RetryPolicy

New returns an unsaved RetryPolicy bound to this client. Call (*RetryPolicy).Save(ctx) to create it.

id is the caller-supplied unique identifier for the policy — unique within the account and immutable; the service returns 409 if another live policy already uses this id. name is the human-readable name. maxRetries is how many times a failed run is retried after the initial attempt (3 means up to 4 attempts total; 0 disables retries; maximum 10). backoff is how the wait between retries grows (see Backoff). delaySeconds is the wait before a retry — the constant wait for fixed backoff, or the base that doubles each retry for exponential. The optional max delay (exponential only) and the failures to retry are set via WithRetryPolicyMaxDelaySeconds, WithRetryPolicyRetryOnTimeout, WithRetryPolicyRetryOnConnectionError, WithRetryPolicyRetryStatuses, and WithRetryPolicyRetryStatusesExcept.

type RetryPolicy added in v3.0.152

type RetryPolicy struct {
	// ID is the caller-supplied unique identifier for the policy. Unique within
	// the account and immutable; the service returns 409 if another live policy
	// already uses this id.
	ID string
	// Name is the human-readable name for the policy.
	Name string
	// MaxRetries is how many times a failed run is retried after the initial
	// attempt — 3 means up to 4 attempts total. 0 disables retries. Maximum 10.
	MaxRetries int
	// Backoff is how the wait between retries grows (see Backoff).
	Backoff Backoff
	// DelaySeconds is the wait before a retry, in seconds — the constant wait
	// for fixed backoff, or the base that doubles each retry for exponential.
	DelaySeconds int
	// MaxDelaySeconds is the ceiling on the wait between retries, for
	// exponential backoff only. Nil (the default) leaves it uncapped; omit it
	// for fixed backoff. Sent on writes only when non-nil.
	MaxDelaySeconds *int
	// RetryOnTimeout retries a run that failed because the request did not
	// complete within the job's timeout. Defaults to false (timeouts are not
	// retried).
	RetryOnTimeout bool
	// RetryOnConnectionError retries a run that failed because the destination
	// could not be reached (DNS, connection refused, TLS, or transport error).
	// Defaults to false (connection errors are not retried).
	RetryOnConnectionError bool
	// RetryStatuses is an allowlist of response status patterns to retry when a
	// run fails because the response did not match the job's success status.
	// Each element is either an exact 3-digit HTTP code (e.g. "429") or a status
	// class ("1xx", "2xx", "3xx", "4xx", "5xx") — e.g. []string{"429", "5xx"} to
	// retry on rate-limit and any server error. Empty (the default) matches no
	// status, so nothing is retried on a non-success response.
	RetryStatuses []string
	// RetryStatusesExcept subtracts from RetryStatuses, using the same exact-code
	// or class syntax. A status matching both lists is not retried — except wins
	// on overlap — so RetryStatuses of []string{"5xx"} with RetryStatusesExcept
	// of []string{"501"} retries every server error except 501. Empty (the
	// default) subtracts nothing.
	RetryStatusesExcept []string
	// CreatedAt is when the policy was created. Nil for an unsaved RetryPolicy.
	CreatedAt *time.Time
	// UpdatedAt is when the policy was last modified.
	UpdatedAt *time.Time
	// DeletedAt is when the policy was deleted. Nil for live policies.
	DeletedAt *time.Time
	// Version is a monotonic counter incremented on every update, starting at 1.
	Version *int
	// contains filtered or unexported fields
}

RetryPolicy is a named, reusable retry policy.

A policy decides whether and how a failed run is retried. Reference it from a job's RetryPolicy (and optionally override it per environment). A job that references nothing uses the built-in "Default" policy, which never retries. Retry policies are account-global — never environment-scoped.

Active-record style: build one with RetryPoliciesClient.New, mutate fields, and call Save(ctx) to persist (create when new, full-replace update when it already exists), or Delete(ctx) to remove.

func (*RetryPolicy) Delete added in v3.0.152

func (policy *RetryPolicy) Delete(ctx context.Context) error

Delete removes this retry policy on the server.

func (*RetryPolicy) Save added in v3.0.152

func (policy *RetryPolicy) Save(ctx context.Context) error

Save creates this retry policy on the server, or full-replaces it if it already exists. Upsert behavior keyed on CreatedAt: nil → create (POST), set → full-replace update (PUT). After the call, every field is refreshed from the server response (including CreatedAt, UpdatedAt, Version).

type RetryPolicyOption added in v3.0.152

type RetryPolicyOption func(*RetryPolicy)

RetryPolicyOption configures an unsaved RetryPolicy returned by RetryPoliciesClient.New.

func WithRetryPolicyMaxDelaySeconds added in v3.0.152

func WithRetryPolicyMaxDelaySeconds(maxDelaySeconds int) RetryPolicyOption

WithRetryPolicyMaxDelaySeconds sets the ceiling on the wait between retries, for exponential backoff only. Unset (the default) leaves it uncapped; omit it for fixed backoff.

func WithRetryPolicyRetryOnConnectionError added in v3.0.154

func WithRetryPolicyRetryOnConnectionError(retryOnConnectionError bool) RetryPolicyOption

WithRetryPolicyRetryOnConnectionError sets whether to retry a run that failed because the destination could not be reached (DNS, connection refused, TLS, or transport error). Unset (the default) does not retry connection errors.

func WithRetryPolicyRetryOnTimeout added in v3.0.154

func WithRetryPolicyRetryOnTimeout(retryOnTimeout bool) RetryPolicyOption

WithRetryPolicyRetryOnTimeout sets whether to retry a run that failed because the request did not complete within the job's timeout. Unset (the default) does not retry timeouts.

func WithRetryPolicyRetryStatuses added in v3.0.154

func WithRetryPolicyRetryStatuses(retryStatuses []string) RetryPolicyOption

WithRetryPolicyRetryStatuses sets the allowlist of response status patterns to retry when a run fails because the response did not match the job's success status. Each element is an exact 3-digit HTTP code (e.g. "429") or a status class ("1xx"–"5xx"). Unset (the default) matches no status.

func WithRetryPolicyRetryStatusesExcept added in v3.0.154

func WithRetryPolicyRetryStatusesExcept(retryStatusesExcept []string) RetryPolicyOption

WithRetryPolicyRetryStatusesExcept sets patterns subtracted from the RetryStatuses allowlist, using the same exact-code or class syntax; except wins on overlap. Unset (the default) subtracts nothing.

type Rule

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

Rule is a fluent builder for JSON Logic rule dicts.

rule := smplkit.NewRule("Enable for enterprise users").
    When("user.plan", "==", "enterprise").
    Serve(true).
    Build()

func NewRule

func NewRule(description string) *Rule

NewRule creates a new rule builder with the given description.

func (*Rule) Build

func (r *Rule) Build() map[string]interface{}

Build finalizes and returns the rule as a plain map.

Every rule requires an environment. The builder permits a chained Environment(...) call and validates at the AddRule boundary — Flag.AddRule rejects any rule whose Build() output has no "environment" key.

func (*Rule) Environment

func (r *Rule) Environment(envKey string) *Rule

Environment tags this rule with an environment key (required for AddRule).

func (*Rule) Serve

func (r *Rule) Serve(value interface{}) *Rule

Serve sets the value returned when this rule matches.

func (*Rule) When

func (r *Rule) When(variable string, op Op, value interface{}) *Rule

When adds a simple comparison condition. Multiple When / WhenLogic calls are AND'd at the top level.

op accepts an Op constant (preferred, e.g. OpEQ) or a raw operator string (e.g. "==", "contains"), since Op is a string type. Supported operators: ==, !=, >, <, >=, <=, in, contains.

For predicates this convenience form can't express — OR, nested AND/OR, if, etc. — use WhenLogic with a raw JSON Logic expression.

func (*Rule) WhenLogic added in v3.0.128

func (r *Rule) WhenLogic(expr map[string]interface{}) *Rule

WhenLogic adds a raw JSON Logic predicate as a condition. Use this escape hatch for expressions When can't build — OR, nested AND/OR, if, and so on. Multiple When / WhenLogic calls are AND'd at the top level. See https://jsonlogic.com/ for the expression grammar.

type Run added in v3.0.114

type Run struct {
	// ID is the server-assigned UUID for this run.
	ID string
	// Job is the id of the job this run belongs to.
	Job string
	// JobVersion is the job's version at the time the run executed.
	JobVersion *int
	// Environment is the environment this run executed in. A scheduled run
	// inherits the firing job-environment; a manual run is created in the
	// environment named by the X-Smplkit-Environment header; a rerun copies
	// its source run's environment.
	Environment string
	// Trigger is why the run exists: "SCHEDULE", "MANUAL" (Run now), or
	// "RERUN". Raw trigger string; compare against the RunTrigger constants.
	Trigger string
	// RerunOf is the source run's id; set only when Trigger is "RERUN".
	RerunOf *string
	// Retry is the run's position in its retry chain; set (non-nil) only when
	// Trigger is "RETRY", nil otherwise.
	Retry *RunRetry
	// ScheduledFor is the intended fire time for a scheduled run; nil for
	// manual / rerun runs.
	ScheduledFor *time.Time
	// Status is the lifecycle state of the run (e.g. "PENDING",
	// "SUCCEEDED", "FAILED", "CANCELED").
	Status string
	// StartedAt is when execution started.
	StartedAt *time.Time
	// FinishedAt is when execution finished.
	FinishedAt *time.Time
	// PendingDurationMs is the milliseconds the run waited as PENDING
	// before starting.
	PendingDurationMs *int
	// RunDurationMs is the milliseconds the run spent executing.
	RunDurationMs *int
	// TotalDurationMs is the milliseconds from enqueue to finish.
	TotalDurationMs *int
	// FailureReason is why a FAILED run failed; nil otherwise.
	FailureReason *string
	// Error is free-text failure detail, if any.
	Error *string
	// Request is a snapshot of the request that was sent (header values
	// redacted). Forensics only; nil when not available.
	Request map[string]interface{}
	// Result is the outcome of the call (e.g. status, headers, body).
	// Nil when not available.
	Result map[string]interface{}
	// CreatedAt is when the run was enqueued (became PENDING).
	CreatedAt *time.Time
	// contains filtered or unexported fields
}

Run is one occurrence of a job executing.

Read-only apart from the Rerun / Cancel actions: a run is created and driven by the jobs service, not by clients. A Run returned by the SDK is bound to its runs client so run.Rerun(ctx) and run.Cancel(ctx) work.

func (*Run) Cancel added in v3.0.143

func (run *Run) Cancel(ctx context.Context) (*Run, error)

Cancel cancels this run if it has not finished yet.

func (*Run) Rerun added in v3.0.143

func (run *Run) Rerun(ctx context.Context) (*Run, error)

Rerun starts a new run that repeats this one (a RERUN), in the same environment.

type RunRetry added in v3.0.152

type RunRetry struct {
	// Of is the id of the chain's original run — the first attempt that failed
	// and started the chain.
	Of string
	// Attempt is which retry this run is — 1 for the first retry, 2 for the
	// second, and so on.
	Attempt int
}

RunRetry is where a RETRY run sits in its retry chain (read-only).

type RunTrigger added in v3.0.146

type RunTrigger string

RunTrigger is what started a run (read-only).

  • RunTriggerManual: A Run / Trigger call started it on demand.
  • RunTriggerRerun: It repeats an earlier run.
  • RunTriggerRetry: An automatic retry of a failed run, per the job's retry policy.
  • RunTriggerSchedule: The job's schedule fired.

type RunsClient added in v3.0.114

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

RunsClient is the client.Jobs().Runs() surface: read-only run history plus the cancel / rerun run actions.

func (*RunsClient) Cancel added in v3.0.114

func (r *RunsClient) Cancel(ctx context.Context, runID string) (*Run, error)

Cancel cancels a pending run and returns its updated state.

func (*RunsClient) Get added in v3.0.114

func (r *RunsClient) Get(ctx context.Context, runID string) (*Run, error)

Get returns one run by id.

func (*RunsClient) List added in v3.0.114

func (r *RunsClient) List(ctx context.Context, input ListRunsInput) ([]*Run, error)

List returns runs for the authenticated account, newest first. Cursor paginated: pass PageSize and the After cursor from the prior page. Pass Job to scope to a single job's history, and Environments to scope to one or more environment keys (resolved as explicit list → client default → omitted). Pass Triggers to restrict to runs with any of those triggers, and LastRunOnly to collapse to the last completed run per job-and-environment.

func (*RunsClient) Rerun added in v3.0.114

func (r *RunsClient) Rerun(ctx context.Context, runID string) (*Run, error)

Rerun re-runs a prior run, spawning a new RERUN run that inherits the source run's environment.

type Service added in v3.0.88

type Service struct {
	// ID is the service slug (e.g. "user_service").
	ID string
	// Name is the display name.
	Name string
	// CreatedAt is the server creation timestamp (nil for unsaved instances).
	CreatedAt *time.Time
	// UpdatedAt is the last-modified timestamp.
	UpdatedAt *time.Time
	// contains filtered or unexported fields
}

Service resource — a backend application or microservice in the customer's stack that contexts can be evaluated against.

Mutate fields, then call Save(ctx).

func (*Service) Delete added in v3.0.88

func (s *Service) Delete(ctx context.Context) error

Delete removes this service from the server.

func (*Service) Save added in v3.0.88

func (s *Service) Save(ctx context.Context) error

Save creates or updates the service on the server. The instance is updated with server-returned fields on success. PUT semantics: creates if CreatedAt is nil, otherwise updates.

type ServicesClient added in v3.0.126

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

ServicesClient provides CRUD operations for service resources (client.Platform().Services()).

func (*ServicesClient) Delete added in v3.0.126

func (m *ServicesClient) Delete(ctx context.Context, id string) error

Delete removes a service by ID. id is the identifier of the service to delete.

func (*ServicesClient) Get added in v3.0.126

func (m *ServicesClient) Get(ctx context.Context, id string) (*Service, error)

Get retrieves a single service by ID. id is the identifier of the service to fetch. Returns a NotFoundError when no service with that id exists.

func (*ServicesClient) List added in v3.0.126

func (m *ServicesClient) List(ctx context.Context, opts ...ListOption) ([]*Service, error)

List returns one page of services for the account.

Without options the server applies its defaults (page 1, page size 1000). Use WithPageNumber / WithPageSize to walk additional pages.

func (*ServicesClient) New added in v3.0.126

func (m *ServicesClient) New(id string, name string) *Service

New returns an unsaved Service. Call svc.Save(ctx) to persist.

id is a stable, human-readable identifier for the service. name is the display name shown in the Console.

type SettingsClient added in v3.0.126

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

SettingsClient provides get/save for account-level settings (client.Account().Settings()).

func (*SettingsClient) Get added in v3.0.126

Get retrieves the current account settings.

Returns an AccountSettings active record; mutate its fields and call Save(ctx) to persist the changes.

type SmplClient added in v3.0.126

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

SmplClient is the canonical entry point for the smplkit SDK.

Create one with NewClient and access sub-clients via accessor methods:

client, err := smplkit.NewClient(smplkit.Config{APIKey: "sk_api_...", Environment: "production", Service: "my-service"})
billing, err := client.Config().Get(ctx, "billing")

One client exposes config, flags, logging, audit, jobs, platform, and account.

func NewClient

func NewClient(cfg Config, opts ...ClientOption) (*SmplClient, error)

NewClient creates a new smplkit API client.

Configuration is resolved from four layers (later layers override earlier ones):

  1. Defaults (scheme=https, baseDomain=smplkit.com)
  2. Config file (~/.smplkit) with [common] and profile sections
  3. Environment variables (SMPLKIT_API_KEY, SMPLKIT_ENVIRONMENT, etc.)
  4. Explicit Config struct fields

Use ClientOption functions to customize the timeout or HTTP client.

Construction is side-effect-free: no background goroutines, no phone-home. The periodic registration-buffer flush and the service-context registration are deferred until the first config/flags/logging operation — so an audit-only or jobs-only customer pays zero goroutines and zero network at construction.

func (*SmplClient) Account added in v3.0.126

func (c *SmplClient) Account() *AccountClient

Account returns the Smpl Account sub-client — account-level settings.

func (*SmplClient) Audit added in v3.0.126

func (c *SmplClient) Audit() *AuditClient

Audit returns the sub-client for the Smpl Audit service.

Use client.Audit().Events().Create(...) to record an event; the call is fire-and-forget — the SDK buffers the event in memory and a background goroutine flushes the buffer with retry on transient failures.

func (*SmplClient) Close added in v3.0.126

func (c *SmplClient) Close() error

Close releases all resources held by the client and its sub-clients.

func (*SmplClient) Config added in v3.0.126

func (c *SmplClient) Config() *ConfigClient

Config returns the sub-client for the Smpl Config service.

func (*SmplClient) Environment added in v3.0.126

func (c *SmplClient) Environment() string

Environment returns the resolved environment name.

func (*SmplClient) Flags added in v3.0.126

func (c *SmplClient) Flags() *FlagsClient

Flags returns the sub-client for the Smpl Flags service.

func (*SmplClient) Jobs added in v3.0.126

func (c *SmplClient) Jobs() *JobsClient

Jobs returns the sub-client for the Smpl Jobs service.

func (*SmplClient) Logging added in v3.0.126

func (c *SmplClient) Logging() *LoggingClient

Logging returns the sub-client for the Smpl Logging service.

func (*SmplClient) Platform added in v3.0.126

func (c *SmplClient) Platform() *PlatformClient

Platform returns the Smpl Platform sub-client — cross-cutting CRUD on environments, services, contexts, and context types.

func (*SmplClient) Service added in v3.0.126

func (c *SmplClient) Service() string

Service returns the resolved service name.

func (*SmplClient) SetContext added in v3.0.128

func (c *SmplClient) SetContext(ctx context.Context, contexts []Context) *ContextScope

SetContext stashes contexts as the active evaluation context for context-sensitive evaluations (flag.Get today) and registers each one with the platform in the background.

Typical use is from middleware — set the context once at request entry and every flag.Get inside that request automatically evaluates against it, without threading the contexts through every call. Each unique (type, key) is also queued for registration with the platform (deduplicated; sent in the background).

Two usage shapes:

// Fire-and-forget (typical middleware)
client.SetContext(ctx, []smplkit.Context{userCtx, accountCtx})

// Scoped override (e.g. impersonation) — revert on return
defer client.SetContext(ctx, []smplkit.Context{impersonated}).Restore()

An empty contexts slice clears the active context (and skips registration) but still returns a scope. This is a separate capability from FlagsClient.SetContextProvider: a provider, when set, takes precedence over the SetContext stash during evaluation.

Returns a ContextScope you can ignore for fire-and-forget use, or whose Restore / Close reverts to the previously-active context.

func (*SmplClient) WaitUntilReady added in v3.0.126

func (c *SmplClient) WaitUntilReady(ctx context.Context, timeout time.Duration) error

WaitUntilReady optionally pre-warms the SDK and blocks until the live socket is up.

Eagerly connects config and flags — flushing discovery, pre-fetching all flags and configs into the local cache, opening the live-updates WebSocket — and waits for the handshake to complete. After this returns, flag.Get() / client.Config().Subscribe() hit cache (no first-request connect tax) and any OnChange listeners receive every server event from this point forward.

Optional: config and flags connect lazily on first live use, so this is purely a pre-warm / WebSocket-ready barrier. Logging integration is not connected here — call client.Logging().Install() separately if you want it (it installs adapters and hooks into your application's logger, which should be opt-in).

timeout=0 uses the SDK default. Context cancellation also returns. Returns a TimeoutError if the WebSocket fails to connect within timeout.

type StringFlagHandle

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

StringFlagHandle is a typed handle for a string flag.

func (*StringFlagHandle) Get

func (h *StringFlagHandle) Get(ctx context.Context, contexts ...Context) string

Get evaluates the flag and returns a typed string value.

The variadic contexts are optional Context entities to evaluate targeting rules against; when omitted, the ambient request context (if any) is used. Returns the evaluated string value, or this flag's default when no environment override or rule applies, or when the evaluated value is not a string.

func (*StringFlagHandle) OnChange

func (h *StringFlagHandle) OnChange(cb func(*FlagChangeEvent))

OnChange registers a flag-specific change listener.

type TimeoutError

type TimeoutError struct {
	// Base is the embedded base Error carrying the HTTP status, message,
	// raw response body, and any parsed JSON:API error details.
	Base Error
}

TimeoutError is raised when an operation exceeds its timeout.

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

Error implements the error interface.

func (*TimeoutError) Unwrap

func (e *TimeoutError) Unwrap() error

Unwrap returns the embedded Error so errors.Is/errors.As walk the chain.

type Usage added in v3.0.114

type Usage struct {
	// Period is the usage period this report covers, as "YYYY-MM" (UTC).
	Period string
	// RunsUsed is the runs metered so far this period.
	RunsUsed int
	// RunsIncluded is the runs included in the plan this period (-1 means
	// unlimited).
	RunsIncluded int
	// ActiveJobs is the number of permanent jobs (recurring and manual)
	// counted against the plan's job limit.
	ActiveJobs int
	// ActiveJobsLimit is the maximum permanent jobs the plan allows (-1
	// means unlimited).
	ActiveJobsLimit int
}

Usage is the current-period usage against the account's plan allotments (read-only).

type ValidationError

type ValidationError struct {
	// Base is the embedded base Error carrying the HTTP status, message,
	// raw response body, and any parsed JSON:API error details.
	Base Error
}

ValidationError is raised when the server rejects a request due to validation errors.

func (*ValidationError) Error

func (e *ValidationError) Error() string

Error implements the error interface.

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Unwrap returns the embedded Error so errors.Is/errors.As walk the chain.

Directories

Path Synopsis
internal
debug
Package debug provides the SMPLKIT_DEBUG diagnostic facility.
Package debug provides the SMPLKIT_DEBUG diagnostic facility.
generated/app
Package app contains auto-generated types from the app OpenAPI spec.
Package app contains auto-generated types from the app OpenAPI spec.
generated/audit
Package audit provides primitives to interact with the openapi HTTP API.
Package audit provides primitives to interact with the openapi HTTP API.
generated/config
Package config contains auto-generated types from the config OpenAPI spec.
Package config contains auto-generated types from the config OpenAPI spec.
generated/flags
Package flags provides primitives to interact with the openapi HTTP API.
Package flags provides primitives to interact with the openapi HTTP API.
generated/jobs
Package jobs provides primitives to interact with the openapi HTTP API.
Package jobs provides primitives to interact with the openapi HTTP API.
generated/logging
Package logging provides primitives to interact with the openapi HTTP API.
Package logging provides primitives to interact with the openapi HTTP API.
logging

Jump to

Keyboard shortcuts

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