Documentation
¶
Index ¶
- Constants
- Variables
- func AcquirePluginEnv(ctx context.Context, client *apiclient.ApiClient, user *model.User, ...) (*scriptling.Scriptling, error)
- func AuthorizeForwardTarget(requester *model.User, ref string, port uint16) (*ForwardTarget, *ForwardTargetError)
- func AvailableZoneRuntimes() map[string]bool
- func BuildStackVariableData(space *model.Space, variables map[string]interface{}) map[string]interface{}
- func CanUserAccessCommand(user *model.User, command *model.Command) bool
- func CanUserAccessSkill(user *model.User, skill *model.Skill) bool
- func CanUserExecuteScript(user *model.User, script *model.Script) bool
- func CheckSpaceLifecycleEvents(oldSpace, newSpace *model.Space)
- func CloseAgentPlugins()
- func DispatchPluginHandler(ctx context.Context, client *apiclient.ApiClient, user *model.User, ...) (any, error)
- func DispatchPluginHandlerWithMethod(ctx context.Context, client *apiclient.ApiClient, user *model.User, ...) (any, error)
- func DispatchPluginMCPTool(ctx context.Context, client *apiclient.ApiClient, user *model.User, ...) (result any, response string, exitCode int, err error)
- func ExecuteEventScript(script *model.Script, eventParams map[string]object.Object, user *model.User, ...) (string, error)
- func ExecuteScriptWithMCP(script *model.Script, mcpParams map[string]object.Object, user *model.User) (string, error)
- func ExitOnSystemExit(result object.Object)
- func ForwardToNode(w http.ResponseWriter, r *http.Request, nodeId string) error
- func HandleScriptResult(result object.Object, err error, capturedOutput string) (int, string, error)
- func LoadAgentPlugins(ctx context.Context, plugins, dirs []string) error
- func MaskWebhookSecret(secret string) string
- func NewAgentScriptlingEnv(client *apiclient.ApiClient, userId string, opts AgentScriptlingOptions) (*scriptling.Scriptling, func(), error)
- func NewPluginScriptlingEnv(client *apiclient.ApiClient, user *model.User, plugin *plugins.Plugin) (*scriptling.Scriptling, error)
- func NewServerScriptlingEnv(client *apiclient.ApiClient, opts ServerScriptlingOptions) (*scriptling.Scriptling, *knotscriptling.MCPLibrary, func(), error)
- func NewUserObject(user *model.User) object.Object
- func NodeAPIEndpoint(nodeId string) (string, error)
- func PluginEnvPoolStats() (leases, builds int)
- func PoolNameForSpace(space *model.Space) string
- func QualifiedHandler(plugin *plugins.Plugin, handler string) string
- func RaiseCustomEvent(eventId, eventType, spaceId, userId, actorId string, ...)
- func RaiseSystemEvent(eventType, spaceId, userId string, payload map[string]interface{})
- func ReleasePluginEnv(env *scriptling.Scriptling, plugin *plugins.Plugin)
- func RequestObject(method, path string, params map[string]any, user *model.User, ...) object.Object
- func ResetPluginEnvPoolForTest()
- func ResolveCommandByName(name string, userId string) (*model.Command, error)
- func ResolveForwardTarget(requester *model.User, ref string, port uint16) (*ForwardTarget, *ForwardTargetError)
- func ResolveScriptByName(name string, userId string) (*model.Script, error)
- func ResolveSkillByName(name string, userId string) (*model.Skill, error)
- func ResolveWebHostName(userId, part string) *model.Space
- func SelectNodeForSpace(template *model.Template, selectedNodeId string) (string, error)
- func SetAgentHealthConfigUpdater(updater AgentHealthConfigUpdater)
- func SetContainerService(service Container)
- func SetJSONRPCCaller(fn JSONRPCCaller)
- func SetPoolSessionProvider(provider func(spaceID string) *PoolSessionState)
- func SetSpaceHealth(spaceId string, healthy bool, failures uint32)
- func SetTransport(t Transport)
- func SetUserService(service UserService)
- func ShouldForwardToNode(nodeId string) (bool, string)
- func SplitForwardRef(ref string) (string, string, bool)
- func StartConversationRetentionSweep()
- func TemplateRuntimeAvailable(template *model.Template) bool
- func TemplateRuntimeAvailableIn(template *model.Template, available map[string]bool) bool
- func ValidForwardRef(ref string) bool
- func ValidateKvmSpaceAddress(template *model.Template, ipAddress string, ignoreSpaceId string) error
- func ValidateServerNetPolicy() error
- type AgentHealthConfigUpdater
- type AgentScriptlingOptions
- type CommandListOptions
- type CommandService
- type Container
- type EventActor
- type EventDispatcher
- func (d *EventDispatcher) Dispatch(envelope *EventEnvelope)
- func (d *EventDispatcher) GetEntriesForGossip() []*InFlightEntry
- func (d *EventDispatcher) MarkEventDone(eventId string)
- func (d *EventDispatcher) MergeInFlight(entries []*InFlightEntry)
- func (d *EventDispatcher) RegisterSubscriptions(spaceId, userId string, methods []methods.MethodDefinition)
- func (d *EventDispatcher) ReloadSinks()
- func (d *EventDispatcher) ReplayPending()
- func (d *EventDispatcher) UnregisterSubscriptions(spaceId string)
- type EventEnvelope
- type ForwardTarget
- type ForwardTargetError
- type Icon
- type IconList
- type IconService
- type InFlightEntry
- type JSONRPCCaller
- type JSONRPCSubscription
- type PoolService
- func (s *PoolService) Acquire(ctx context.Context, pool *model.PoolDefinition, user *model.User, ...) (*apiclient.LeaseInfo, error)
- func (s *PoolService) Create(pool *model.PoolDefinition, user *model.User) error
- func (s *PoolService) Delete(pool *model.PoolDefinition, user *model.User) error
- func (s *PoolService) Extend(user *model.User, spaceIdOrName string, durationSeconds int) (*apiclient.LeaseInfo, error)
- func (s *PoolService) Info(pool *model.PoolDefinition, user *model.User) (apiclient.PoolInfo, error)
- func (s *PoolService) InitLeases()
- func (s *PoolService) IsDrained(spaceID string) bool
- func (s *PoolService) IsLeased(spaceID string) bool
- func (s *PoolService) List(user *model.User) ([]apiclient.PoolInfo, error)
- func (s *PoolService) ListLeases(pool *model.PoolDefinition, user *model.User) ([]apiclient.LeaseInfo, error)
- func (s *PoolService) MarkDrained(spaceID string)
- func (s *PoolService) MarkLeaseCleared(spaceID string)
- func (s *PoolService) MarkLeased(spaceID, userId string, expiresAtUnix int64)
- func (s *PoolService) MarkUndrained(spaceID string)
- func (s *PoolService) PickMemberForRouting(poolName, userId string) *model.Space
- func (s *PoolService) ReapOrphans() error
- func (s *PoolService) Release(user *model.User, spaceIdOrName string) (*apiclient.LeaseInfo, error)
- func (s *PoolService) ReleaseAndDestroy(user *model.User, spaceIdOrName string) (*apiclient.LeaseInfo, error)
- func (s *PoolService) Resolve(idOrName string) (*model.PoolDefinition, error)
- func (s *PoolService) ResolveForUser(idOrName string, user *model.User) (*model.PoolDefinition, error)
- func (s *PoolService) SaveCustomFields(pool *model.PoolDefinition, fields []model.SpaceCustomField, user *model.User) error
- func (s *PoolService) SaveLeaseConfig(pool *model.PoolDefinition) error
- func (s *PoolService) SetSize(pool *model.PoolDefinition, desiredCount int, user *model.User) error
- func (s *PoolService) Start(pool *model.PoolDefinition, user *model.User) error
- func (s *PoolService) StartReaper()
- func (s *PoolService) StartSweep()
- func (s *PoolService) Stop(pool *model.PoolDefinition, user *model.User) error
- func (s *PoolService) SweepOnce() error
- func (s *PoolService) SyncSpaceLease(space *model.Space)
- func (s *PoolService) UpdateStartupScript(pool *model.PoolDefinition, scriptId string, user *model.User) error
- type PoolSessionState
- type ScriptListOptions
- type ScriptService
- type ServerScriptlingOptions
- type SkillListOptions
- type SkillService
- type SpaceListOptions
- type SpaceService
- func (s *SpaceService) CheckUserQuotas(user *model.User, template *model.Template) error
- func (s *SpaceService) CreateSpace(space *model.Space, user *model.User) error
- func (s *SpaceService) DeleteSpace(spaceId string, user *model.User) error
- func (s *SpaceService) GetSpace(spaceId string, user *model.User) (*model.Space, error)
- func (s *SpaceService) GetSpaceCustomField(spaceId string, fieldName string, user *model.User) (string, error)
- func (s *SpaceService) ListSpaces(opts SpaceListOptions) ([]*model.Space, error)
- func (s *SpaceService) RemoveDependencyReferences(spaceId string, ownerUserId string) error
- func (s *SpaceService) SetSpaceCustomField(spaceId string, fieldName string, fieldValue string, user *model.User) error
- func (s *SpaceService) SetSpaceJobs(spaceId string, jobs []model.SpaceJob, jobsEnabled bool, user *model.User) error
- func (s *SpaceService) UpdateSpace(space *model.Space, user *model.User) error
- func (s *SpaceService) ValidateDependencies(space *model.Space) error
- func (s *SpaceService) ValidateDependenciesRunning(space *model.Space) error
- type TemplateListOptions
- type TemplateService
- func (s *TemplateService) CreateTemplate(template *model.Template, user *model.User) error
- func (s *TemplateService) DeleteTemplate(templateId string, user *model.User) error
- func (s *TemplateService) GetTemplate(templateId string) (*model.Template, error)
- func (s *TemplateService) GetTemplateUsage(templateId string) (total int, deployed int, err error)
- func (s *TemplateService) ListTemplates(opts TemplateListOptions) ([]*model.Template, error)
- func (s *TemplateService) UpdateTemplate(template *model.Template, user *model.User) error
- type Transport
- type UserService
Constants ¶
const ( SinkQueueSize = 100 WebhookTimeout = 10 * time.Second RetryAttempts = 3 TombstoneRetention = 5 * time.Minute )
const ( PoolSweepInterval = 15 * time.Second PoolReapInterval = 1 * time.Hour // PoolLeaseMaxWait bounds the server-side long-poll of Acquire. PoolLeaseMaxWait = 300 * time.Second )
const MaxPendingAge = 10 * time.Minute
Variables ¶
var ( RetryDelay1 = 5 * time.Second RetryDelay2 = 15 * time.Second )
Retry back-off between delivery attempts. Vars (not consts) so tests can shrink them; production values are unchanged.
var ( ErrPoolLeasesDisabled = errors.New("pool leases are not enabled — set lease_max_time on the pool first (edit the pool, or PUT /api/pools/{pool})") ErrPoolNotActive = errors.New("pool is not active") ErrPoolExhausted = errors.New("no free pool member available") ErrLeaseNotFound = errors.New("lease not found") ErrLeaseNotHolder = errors.New("lease is held by another user") ErrLeaseExtendLimit = errors.New("lease extension limit reached") ErrLeaseDuration = errors.New("lease duration exceeds the pool maximum") )
Lease lifecycle errors. The API layer maps these onto status codes.
var PushRestrictionsHook func(space *model.Space)
PushRestrictionsHook tells a space's agent its restrictions changed; the agent server installs it (it imports this package, not the other way).
Functions ¶
func AcquirePluginEnv ¶ added in v0.34.0
func AcquirePluginEnv(ctx context.Context, client *apiclient.ApiClient, user *model.User, plugin *plugins.Plugin) (*scriptling.Scriptling, error)
AcquirePluginEnv returns an environment for dispatching the plugin's handlers as the user: a pooled env Reset and rebound to the user (with the entry evaluated), or a freshly built one when the pool is empty. The caller MUST call ReleasePluginEnv when done — an acquired env is exclusively leased until released.
func AuthorizeForwardTarget ¶ added in v0.36.0
func AuthorizeForwardTarget(requester *model.User, ref string, port uint16) (*ForwardTarget, *ForwardTargetError)
AuthorizeForwardTarget resolves a port-forward target reference for a requesting user and port, and applies the access rule — but without requiring a live pool member. Use this when creating or persisting a forward (an empty pool now may have members by the time it dials):
- a bare name resolves to the requester's own space by that name, falling back to the requester's own pool;
- user--name resolves to that user's space, falling back to their pool;
- a space UUID resolves to the space directly (the form older stored forward entries use).
The owner may reach any port. Anyone else may only reach a port the target's template declares public — checked per connection, so template edits apply to running spaces immediately. Pool members all come from the pool's template, so the public check covers every member at once.
The returned target carries Space for space targets and Ref/IsPool for both; Space is nil for pool targets.
func AvailableZoneRuntimes ¶ added in v0.35.0
AvailableZoneRuntimes returns the set of runtimes offered by alive nodes in this zone — the local node's (detected once, 30s-cached) plus gossip peers' advertised runtimes. List endpoints build this once and use TemplateRuntimeAvailableIn for per-template checks, so a page of templates costs one detection burst rather than one per row.
func BuildStackVariableData ¶ added in v0.30.1
func BuildStackVariableData(space *model.Space, variables map[string]interface{}) map[string]interface{}
BuildStackVariableData builds the .stack.* template variable map for a space, exposing its sibling spaces within the same stack. Siblings are keyed by their stack-definition key (the space name with the stack prefix stripped), so a template can reference e.g. ${{ .stack.db.space.id }} or ${{ .stack.db.custom.password }}.
Each sibling exposes the full variable set (space, template, user, custom, and the shared server/nomad/var groups). Returns nil when the space is not part of a stack or no siblings can be loaded, leaving .stack absent from the render data (references then resolve to empty, like any missing variable).
This is injected into the model package via model.SetStackResolver at server startup to avoid the model <-> database import cycle.
func CanUserAccessCommand ¶ added in v0.29.0
func CanUserAccessSkill ¶ added in v0.23.0
func CanUserExecuteScript ¶ added in v0.23.0
CanUserExecuteScript checks if a user has permission to execute a script
func CheckSpaceLifecycleEvents ¶ added in v0.28.0
CheckSpaceLifecycleEvents compares the before/after state of a space and raises the appropriate system lifecycle events for any transition detected. Pass a nil oldSpace with a non-nil newSpace to signal creation.
func CloseAgentPlugins ¶ added in v0.34.0
func CloseAgentPlugins()
CloseAgentPlugins shuts down every spawned agent plugin process. Called on agent shutdown.
func DispatchPluginHandler ¶ added in v0.34.0
func DispatchPluginHandler(ctx context.Context, client *apiclient.ApiClient, user *model.User, plugin *plugins.Plugin, handler string, params map[string]any) (any, error)
DispatchPluginHandler runs one plugin handler function as the requesting user and returns its Go value: the shared core of plugin field handler and MCP tool calls. The environment comes from the per-plugin pool — isolation follows the trust boundary — with per-request state (params, request) bound by acquirePluginEnv.
func DispatchPluginHandlerWithMethod ¶ added in v0.34.0
func DispatchPluginHandlerWithMethod(ctx context.Context, client *apiclient.ApiClient, user *model.User, plugin *plugins.Plugin, handler string, params map[string]any, method string) (any, error)
DispatchPluginHandlerWithMethod is DispatchPluginHandler with the request method the handler sees — knot.plugin.call's method kwarg rides here (GET default, matching the loopback transport's real request).
func DispatchPluginMCPTool ¶ added in v0.34.0
func DispatchPluginMCPTool(ctx context.Context, client *apiclient.ApiClient, user *model.User, plugin *plugins.Plugin, handler string, params map[string]any) (result any, response string, exitCode int, err error)
DispatchPluginMCPTool runs a plugin handler as an MCP tool: the tool's parameters are bound both as the handler's `params` dict and as the MCP tool context (__mcp_params), so scriptling.mcp.tool accessors and the return_* functions work exactly as they do in script tools. A plain return value comes back as result; return_string/return_object surface as response (with exit code 0), return_error as a non-zero exit code.
func ExecuteEventScript ¶ added in v0.28.0
func ExecuteScriptWithMCP ¶ added in v0.23.0
func ExitOnSystemExit ¶ added in v0.23.0
ExitOnSystemExit checks for SystemExit and exits the process if found
func ForwardToNode ¶ added in v0.23.0
ForwardToNode forwards an HTTP request to another node in the cluster
func HandleScriptResult ¶ added in v0.23.0
func HandleScriptResult(result object.Object, err error, capturedOutput string) (int, string, error)
HandleScriptResult processes scriptling evaluation results with consistent exception handling. Returns (exitCode, output, error) where: - exitCode: 0 for success, non-zero for SystemExit - output: captured output or result inspection - error: non-nil for errors (excluding successful SystemExit with code 0)
func LoadAgentPlugins ¶ added in v0.34.0
LoadAgentPlugins spawns the agent's scriptling plugins and holds the manager for the agent env to register. It mirrors the scriptling CLI: explicit --plugin executables load first, in order (a binary's identity is its resolved path, so the same binary found again via --plugin-dir is a no-op), then each --plugin-dir is scanned. Both empty is a no-op. A plugin that fails to start is a hard error, matching the CLI — a space that asked for a driver should fail loudly rather than run without it.
func MaskWebhookSecret ¶ added in v0.28.0
func NewAgentScriptlingEnv ¶ added in v0.33.0
func NewAgentScriptlingEnv(client *apiclient.ApiClient, userId string, opts AgentScriptlingOptions) (*scriptling.Scriptling, func(), error)
NewAgentScriptlingEnv creates the scriptling environment for every script that runs in a space under the agent: startup/shutdown scripts, streaming user scripts (`knot space run-script`), `knot run-script` eval, `knot methods register`, and health check scripts. This is the full side of knot's two environments — registerAgentLibraries (the scriptling CLI surface minus container/nomad), knot libraries with knot.methods, and knot.healthcheck. Scripts already run inside the space container, so fs is unrestricted and the plugin scope allows both HTTP(S) and stdio executable plugins.
Interactive decorations are per-call and layered by the caller: the console stub and scriptling.ai.agent.interact in execute_script_stream.go, and per-call argv/input on pooled environments.
func NewPluginScriptlingEnv ¶ added in v0.34.0
func NewPluginScriptlingEnv(client *apiclient.ApiClient, user *model.User, plugin *plugins.Plugin) (*scriptling.Scriptling, error)
NewPluginScriptlingEnv creates the environment a plugin's handlers run in when dispatched for a user: registerPluginLibraries, knot's run-as-user libraries over the loopback API, the plugin's binary peers as plugin.* libraries, and a loader chain that resolves the plugin's own modules first, then knot's embedded libraries, then the invoking user's lib scripts.
func NewServerScriptlingEnv ¶ added in v0.33.0
func NewServerScriptlingEnv(client *apiclient.ApiClient, opts ServerScriptlingOptions) (*scriptling.Scriptling, *knotscriptling.MCPLibrary, func(), error)
NewServerScriptlingEnv creates the scriptling environment for scripts that run in the knot server: MCP tool execution and event sink scripts. This is the restricted side of knot's two environments — no system access libraries (subprocess, os, pathlib, …), no runtime, fs only when the admin configured ScriptFSAllowedPaths, outbound network access (requests, wait_for, scriptling.ai, scriptling.mcp) governed by the TOML policy at ScriptNetPolicyFile when the admin configured one, no knot.methods, and an HTTP-only plugin scope (no local executables on the server). Output is captured and returned.
Both modes get: stdlib + the base extended libraries, knot.ai, the knot.apiclient transport, knot.mcp, all knot.* API libraries via the embedded loader, on-demand user `lib` scripts from the server, and a per-execution isolated plugin scope (released via the returned cleanup). MCP tool mode additionally gets result capture (mcp.return_*); event sink mode additionally gets the knot.event sink accessors (no emit — prevents sink → event → sink recursion) and the event payload/metadata variables.
With a nil client the environment is base-only (used by tests); knot libraries and the loader require a client and user.
func NewUserObject ¶ added in v0.34.0
NewUserObject builds the requesting user as a User instance — fields id, name, is_admin, groups, permissions (stable snake_case keys like "manage_spaces") and plugin_permissions (qualified grants) — with has_permission and in_group methods. It backs knot.identity.user() (the authoritative identity surface in plugin and tool code) and the `user` global user-created MCP tool scripts bind. has_permission's argument picks the check: an integer is a built-in permission id (the knot.permission constants), a "plugin."-prefixed string a qualified grant, any other string a built-in key. It complements — never replaces — the metadata gates knot enforces before a handler runs.
func NodeAPIEndpoint ¶ added in v0.35.0
NodeAPIEndpoint resolves a cluster node's public API base URL (e.g. "https://knot-node-2:8443") from its gossip metadata, falling back to the advertised gossip address. Returns an error when the node is unknown or advertises nothing usable.
func PluginEnvPoolStats ¶ added in v0.34.0
func PluginEnvPoolStats() (leases, builds int)
PluginEnvPoolStats reports warm leases and cold builds (tests, observability).
func PoolNameForSpace ¶ added in v0.28.0
PoolNameForSpace returns the pool name if the space is a pool member, or "".
func QualifiedHandler ¶ added in v0.34.0
QualifiedHandler maps a declared handler reference to the addressable name dispatch calls. Handlers live under a plugin.<ns> namespace: a pure-script plugin's main.py is registered as plugin.<ScriptNamespace(folder)>, and a peer plugin's peer exports under its handshake name. So a bare "status" or "mod.fn" declaration resolves against the plugin's default namespace — its ScriptNamespace when it has a main.py, else its sole peer's handshake name — as "plugin.<ns>.status" / "plugin.<ns>.mod.fn". A reference already rooted at plugin.* (a peer plugin naming a specific peer as "plugin.demolib.status", or cross-plugin composition addressing another plugin) is used verbatim.
func RaiseCustomEvent ¶ added in v0.28.0
func RaiseCustomEvent(eventId, eventType, spaceId, userId, actorId string, payload map[string]interface{})
RaiseCustomEvent raises a custom event owned by userId and raised by actorId: the user who called the API, or the space owner for an event from inside a space, whose processes act as the owner.
func RaiseSystemEvent ¶ added in v0.28.0
func ReleasePluginEnv ¶ added in v0.34.0
func ReleasePluginEnv(env *scriptling.Scriptling, plugin *plugins.Plugin)
ReleasePluginEnv returns a dispatched env to its plugin's free list. Output printed by handlers is drained so an env's capture buffer cannot grow across leases; overflowing or stale lists are trimmed.
func RequestObject ¶ added in v0.34.0
func RequestObject(method, path string, params map[string]any, user *model.User, pluginConfig map[string]any) object.Object
RequestObject builds the `request` argument every plugin handler receives as its single parameter: the call's method, path, params dict, and an inert snapshot of the requesting user. request["user"] is plain, serializable data — a dict of id, name, is_admin, groups, permissions (stable snake_case keys) and plugin_permissions (qualified grants) — so a handler can branch on who is calling, and the same request dict crosses the wire unchanged to a binary peer as its function argument.
request["user"] is data, not authority: it carries no methods and makes no round trip. A handler that needs to ACT as the user, or wants the authoritative permission check, uses knot.identity.user() (a real User object with has_permission / in_group) and the knot.* libraries, which round-trip over the gated loopback. Browser fetches carry the real method and URL; knot.plugin.call carries its method (GET default) with the handler's plugin-root URL; MCP tool execution carries "CALL".
func ResetPluginEnvPoolForTest ¶ added in v0.34.0
func ResetPluginEnvPoolForTest()
ResetPluginEnvPoolForTest drops every pooled env.
func ResolveCommandByName ¶ added in v0.29.0
func ResolveForwardTarget ¶ added in v0.36.0
func ResolveForwardTarget(requester *model.User, ref string, port uint16) (*ForwardTarget, *ForwardTargetError)
ResolveForwardTarget authorizes the target and, for pools, picks a live member for this connection. Distinguishing "no such pool" from "pool has no free member" keeps the common transient state from looking like a permission failure.
func ResolveScriptByName ¶ added in v0.23.0
ResolveScriptByName resolves a script by name with user override support First checks user scripts, then falls back to global scripts Returns nil if script not found, deleted, inactive, or not valid for current zone Supports zone-specific overrides - returns the best match for the current zone
func ResolveSkillByName ¶ added in v0.23.0
func ResolveWebHostName ¶ added in v0.42.0
ResolveWebHostName finds the space a web host's name part routes to for a user: a space or alt name of theirs or shared with them, or a member of their pool, by name, or by its shortened form when the whole host would be longer than DNS allows (see hostlabel). Nil when none.
func SelectNodeForSpace ¶ added in v0.22.0
SelectNodeForSpace selects the best node for a space based on template requirements Returns node ID or empty string for auto-selection, or error if no suitable node found
func SetAgentHealthConfigUpdater ¶ added in v0.28.0
func SetAgentHealthConfigUpdater(updater AgentHealthConfigUpdater)
func SetContainerService ¶
func SetContainerService(service Container)
func SetJSONRPCCaller ¶ added in v0.28.0
func SetJSONRPCCaller(fn JSONRPCCaller)
func SetPoolSessionProvider ¶ added in v0.28.0
func SetPoolSessionProvider(provider func(spaceID string) *PoolSessionState)
func SetSpaceHealth ¶ added in v0.28.0
func SetTransport ¶
func SetTransport(t Transport)
func SetUserService ¶
func SetUserService(service UserService)
func ShouldForwardToNode ¶ added in v0.23.0
ShouldForwardToNode checks if a request should be forwarded to another node
func SplitForwardRef ¶ added in v0.36.0
SplitForwardRef splits a qualified forward target reference into its username and space-or-pool name parts. The second return is false for bare names (own spaces and pools) and for malformed refs.
func StartConversationRetentionSweep ¶ added in v0.29.0
func StartConversationRetentionSweep()
StartConversationRetentionSweep runs a background goroutine that tombstones stale conversations and reaps old tombstones. Runs once at start, then on a daily interval. Should be started only on full cluster members — leaf nodes keep chat history in the browser.
func TemplateRuntimeAvailable ¶ added in v0.35.0
TemplateRuntimeAvailable reports whether any node in the zone currently offers the runtime a template needs. Builds the zone set on each call — fine for one-off checks; list endpoints should use AvailableZoneRuntimes plus TemplateRuntimeAvailableIn instead.
func TemplateRuntimeAvailableIn ¶ added in v0.35.0
TemplateRuntimeAvailableIn is the pure membership check against a set built by AvailableZoneRuntimes — the same semantics SelectNodeForSpace applies. Manual and Nomad templates are always available (no knot-managed runtime involved); the "container" platform matches any container runtime but not KVM alone.
func ValidForwardRef ¶ added in v0.36.0
ValidForwardRef reports whether a forward target reference is well formed: a space UUID (as stored by older forward entries), a bare name, or a qualified user--name.
func ValidateKvmSpaceAddress ¶ added in v0.35.0
func ValidateKvmSpaceAddress(template *model.Template, ipAddress string, ignoreSpaceId string) error
ValidateKvmSpaceAddress checks that a KVM space's chosen IP is valid for the template's network: inside the configured range, not a reserved address, and not already taken by another space. Uniqueness is scoped to the local zone — different zones run independent bridged networks, so the same address there is not a conflict. An ignoreSpaceId lets the caller skip the space being validated (reserved for future re-validation paths; create passes "").
The template's own network fields are validated at template create/update time; a parse failure here means the template changed since, and is reported as an error rather than silently ignored.
func ValidateServerNetPolicy ¶ added in v0.36.0
func ValidateServerNetPolicy() error
ValidateServerNetPolicy validates the configured ScriptNetPolicyFile, if any, so the server refuses to start on a broken policy file rather than failing on the first MCP tool call or event sink run.
Types ¶
type AgentHealthConfigUpdater ¶ added in v0.28.0
type AgentScriptlingOptions ¶ added in v0.33.0
type AgentScriptlingOptions struct {
Argv []string
Logger logger.Logger
Output io.Writer
Input io.Reader
}
AgentScriptlingOptions configures an agent-side (in-space) scriptling environment. Output semantics: nil Output captures the script's output for retrieval; io.Discard throws it away (system scripts); any other writer streams to it. Input, when set, is wired to input() and sys.stdin.
type CommandListOptions ¶ added in v0.29.0
type CommandService ¶ added in v0.29.0
type CommandService struct{}
func GetCommandService ¶ added in v0.29.0
func GetCommandService() *CommandService
func (*CommandService) ListCommands ¶ added in v0.29.0
func (s *CommandService) ListCommands(opts CommandListOptions) ([]*model.Command, error)
type Container ¶
type Container interface {
// Volumes
CreateVolume(volume *model.Volume) error
DeleteVolume(volume *model.Volume) error
// Spaces. StopSpace/RestartSpace run the shutdown script and container
// teardown synchronously and return any teardown error. The shutdown script
// is bounded by a timeout (helper.ShutdownScriptTimeout) so a hung agent
// script cannot block the caller indefinitely.
StartSpace(space *model.Space, template *model.Template, user *model.User) error
StopSpace(space *model.Space) error
RestartSpace(space *model.Space) error
DeleteSpace(space *model.Space)
// Helpers
CleanupOnBoot()
}
func GetContainerService ¶
func GetContainerService() Container
type EventActor ¶ added in v0.28.0
type EventDispatcher ¶ added in v0.28.0
type EventDispatcher struct {
// contains filtered or unexported fields
}
func GetEventDispatcher ¶ added in v0.28.0
func GetEventDispatcher() *EventDispatcher
func (*EventDispatcher) Dispatch ¶ added in v0.28.0
func (d *EventDispatcher) Dispatch(envelope *EventEnvelope)
func (*EventDispatcher) GetEntriesForGossip ¶ added in v0.28.0
func (d *EventDispatcher) GetEntriesForGossip() []*InFlightEntry
GetEntriesForGossip returns all in-flight entries, including tombstoned ones. Used for periodic gossip to zone peers. Tombstones must be gossiped so peers that missed the direct done notification (e.g. they were down) learn the entry is complete and remove it after the retention window; otherwise the record would live on those peers until MaxPendingAge.
func (*EventDispatcher) MarkEventDone ¶ added in v0.28.0
func (d *EventDispatcher) MarkEventDone(eventId string)
MarkEventDone tombstones all in-flight entries for an event. Called by non-leaders on receipt of an EventDoneMsg from the leader.
func (*EventDispatcher) MergeInFlight ¶ added in v0.28.0
func (d *EventDispatcher) MergeInFlight(entries []*InFlightEntry)
MergeInFlight merges incoming in-flight records from gossip. Entries with a newer HLC version overwrite local copies; entries we don't have are added.
func (*EventDispatcher) RegisterSubscriptions ¶ added in v0.28.0
func (d *EventDispatcher) RegisterSubscriptions(spaceId, userId string, methods []methods.MethodDefinition)
RegisterSubscriptions extracts event subscriptions from method definitions and registers them for json-rpc event delivery. Called when methods are registered by a running session.
func (*EventDispatcher) ReloadSinks ¶ added in v0.28.0
func (d *EventDispatcher) ReloadSinks()
ReloadSinks refreshes the in-memory sink cache from the database.
func (*EventDispatcher) ReplayPending ¶ added in v0.28.0
func (d *EventDispatcher) ReplayPending()
ReplayPending is called when this node becomes the zone leader. It scans the in-flight map for entries that were not completed (status pending, attempting, or retry) and re-processes them. Since all servers receive every event, non-leaders have recorded these entries but never dispatched them. On leadership change, the new leader picks up where the old one left off. Consumers may see duplicate deliveries (at-least-once) — they dedup via the event UUID.
func (*EventDispatcher) UnregisterSubscriptions ¶ added in v0.28.0
func (d *EventDispatcher) UnregisterSubscriptions(spaceId string)
UnregisterSubscriptions removes all subscriptions for a space. Called when a session disconnects or methods are unregistered.
type EventEnvelope ¶ added in v0.28.0
type ForwardTarget ¶ added in v0.36.0
type ForwardTarget struct {
// Space is the space traffic should reach — the target itself for
// space targets, or the pool member picked for this connection (pools
// re-resolve per connection, round-robin). Nil for pool targets
// resolved by AuthorizeForwardTarget, which doesn't need a member.
Space *model.Space
// Ref is the canonical dial reference for the target: a bare space or
// pool name when the owner matches the dialing identity, otherwise
// user--name. Agents dial /proxy/spaces/{ref}/port/{port}.
Ref string
// IsPool reports whether the target resolved to a pool (the ref names
// the pool, not the member).
IsPool bool
// OwnerId is the user id the target belongs to — the pool's creator for
// pool targets, the space's owner otherwise.
OwnerId string
}
ForwardTarget is a resolved port-forward target.
type ForwardTargetError ¶ added in v0.36.0
ForwardTargetError maps a failed resolution to the HTTP response the proxy should send. The message is safe to return to the client and is what the forwarding agent logs on a failed dial.
func (*ForwardTargetError) Error ¶ added in v0.36.0
func (e *ForwardTargetError) Error() string
type Icon ¶ added in v0.19.0
type Icon struct {
Description string `toml:"description" json:"description" msgpack:"description"`
Source string `toml:"-" json:"source" msgpack:"source"`
URL string `toml:"url" json:"url" msgpack:"url"`
}
Icon represents a single icon entry
type IconList ¶ added in v0.19.0
type IconList struct {
Icons []Icon `toml:"icons" json:"icons" msgpack:"icons"`
}
type IconService ¶ added in v0.19.0
type IconService struct {
// contains filtered or unexported fields
}
func GetIconService ¶ added in v0.19.0
func GetIconService() *IconService
GetIconService returns the singleton icon service instance
func (*IconService) GetIcons ¶ added in v0.19.0
func (s *IconService) GetIcons() []Icon
GetIcons returns all available icons (built-in and user-supplied)
func (*IconService) ReloadIcons ¶ added in v0.19.0
func (s *IconService) ReloadIcons()
ReloadIcons reloads icons from configuration
type InFlightEntry ¶ added in v0.28.0
type InFlightEntry struct {
EventId string
EventType string
SinkId string
UserId string
SpaceId string
Payload map[string]interface{}
ActorId string
ActorName string
ActorKind string
Status string
Attempts uint32
NextAttemptAt time.Time
LastError string
Version hlc.Timestamp
TombstonedAt time.Time
}
type JSONRPCCaller ¶ added in v0.28.0
type JSONRPCCaller func(spaceId, localMethod string, params json.RawMessage) error
JSONRPCCaller is the callback used to invoke a method on a running session. Set by agent_server.ListenAndServe to avoid a circular dependency.
type JSONRPCSubscription ¶ added in v0.28.0
type PoolService ¶ added in v0.28.0
type PoolService struct {
// contains filtered or unexported fields
}
func GetPoolService ¶ added in v0.28.0
func GetPoolService() *PoolService
func (*PoolService) Acquire ¶ added in v0.36.0
func (s *PoolService) Acquire(ctx context.Context, pool *model.PoolDefinition, user *model.User, durationSeconds, waitSeconds int) (*apiclient.LeaseInfo, error)
Acquire grants the caller an exclusive lease on one free member of the pool. durationSeconds follows resolveLeaseDuration; waitSeconds optionally long-polls (bounded by PoolLeaseMaxWait) for a member to free up before returning ErrPoolExhausted.
func (*PoolService) Create ¶ added in v0.28.0
func (s *PoolService) Create(pool *model.PoolDefinition, user *model.User) error
func (*PoolService) Delete ¶ added in v0.28.0
func (s *PoolService) Delete(pool *model.PoolDefinition, user *model.User) error
func (*PoolService) Extend ¶ added in v0.36.0
func (s *PoolService) Extend(user *model.User, spaceIdOrName string, durationSeconds int) (*apiclient.LeaseInfo, error)
Extend renews the lease held on a member space: the new deadline is now + duration (or never, on unlimited pools), bounded by the pool's extension-count cap. Allowed until the lease has been reclaimed — including while an expired lease is still draining in-flight work, which rescues a lease that ran out by accident.
func (*PoolService) Info ¶ added in v0.28.0
func (s *PoolService) Info(pool *model.PoolDefinition, user *model.User) (apiclient.PoolInfo, error)
func (*PoolService) InitLeases ¶ added in v0.36.0
func (s *PoolService) InitLeases()
InitLeases populates the in-memory lease view from the database. Called once at server start so routing exclusion survives restarts; afterwards the view is maintained by lease operations, their gossip, and space merges (SyncSpaceLease).
func (*PoolService) IsDrained ¶ added in v0.28.0
func (s *PoolService) IsDrained(spaceID string) bool
IsDrained returns true if the pool sweep has drained the space (stopped routing new method calls to it). Used by the HTTP/TCP proxy to skip pool members that are being removed.
func (*PoolService) IsLeased ¶ added in v0.36.0
func (s *PoolService) IsLeased(spaceID string) bool
IsLeased reports whether the space is currently held by an exclusive lease — including one past its expiry that is still draining in-flight work: the member only returns to shared routing once the sweep reclaims the lease. Wired into the methods registry (SetLeaseChecker) so leased pool members are excluded from shared method routing.
func (*PoolService) ListLeases ¶ added in v0.36.0
func (s *PoolService) ListLeases(pool *model.PoolDefinition, user *model.User) ([]apiclient.LeaseInfo, error)
ListLeases returns the pool's held leases — active plus draining.
func (*PoolService) MarkDrained ¶ added in v0.28.0
func (s *PoolService) MarkDrained(spaceID string)
MarkDrained sets the local drain flag without re-gossiping. Called by the cluster handler on peer nodes when receiving a drain message from the leader, so that HTTP/TCP routing also skips the drained member.
func (*PoolService) MarkLeaseCleared ¶ added in v0.36.0
func (s *PoolService) MarkLeaseCleared(spaceID string)
MarkLeaseCleared removes the local lease view without gossiping. Called by the cluster handler when the leader reclaims an ended lease.
func (*PoolService) MarkLeased ¶ added in v0.36.0
func (s *PoolService) MarkLeased(spaceID, userId string, expiresAtUnix int64)
MarkLeased sets the local lease view without gossiping. Called by the cluster handler on peer nodes receiving a lease gossip push.
func (*PoolService) MarkUndrained ¶ added in v0.28.0
func (s *PoolService) MarkUndrained(spaceID string)
MarkUndrained clears the local drain flag without re-gossiping. Called by the cluster handler on peer nodes when receiving an undrain message.
func (*PoolService) PickMemberForRouting ¶ added in v0.28.0
func (s *PoolService) PickMemberForRouting(poolName, userId string) *model.Space
PickMemberForRouting selects a healthy, deployed, non-drained, non-leased member of the pool using round-robin. Returns nil if no suitable member exists. Exclusively leased members are skipped — the holder reaches its member by the member's own name instead.
func (*PoolService) ReapOrphans ¶ added in v0.28.0
func (s *PoolService) ReapOrphans() error
ReapOrphans finds spaces whose pool has been deleted (or no longer exists) and marks them for deletion. This is a safety net for when the normal sweep misses spaces — e.g., after a leader crash mid-deletion, or gossip merge leaving stale pool_id references.
func (*PoolService) Release ¶ added in v0.36.0
Release ends the lease held on a member space early. The member does not re-enter shared routing immediately: it stays excluded until in-flight method work has drained, then the sweep reclaims it (normally one sweep).
func (*PoolService) ReleaseAndDestroy ¶ added in v0.36.0
func (s *PoolService) ReleaseAndDestroy(user *model.User, spaceIdOrName string) (*apiclient.LeaseInfo, error)
ReleaseAndDestroy ends the lease held on a member space by destroying it: the space goes through the normal drain → two-phase delete, and a fresh replacement member is created (and started) immediately so the next acquire gets a clean space without waiting for the sweep. The returned LeaseInfo carries state "destroying" describing the ended lease.
func (*PoolService) Resolve ¶ added in v0.28.0
func (s *PoolService) Resolve(idOrName string) (*model.PoolDefinition, error)
func (*PoolService) ResolveForUser ¶ added in v0.28.0
func (s *PoolService) ResolveForUser(idOrName string, user *model.User) (*model.PoolDefinition, error)
func (*PoolService) SaveCustomFields ¶ added in v0.38.0
func (s *PoolService) SaveCustomFields(pool *model.PoolDefinition, fields []model.SpaceCustomField, user *model.User) error
SaveCustomFields persists the custom field values given to pool members. Running members keep their current values until they next start; new members get them on creation.
func (*PoolService) SaveLeaseConfig ¶ added in v0.36.0
func (s *PoolService) SaveLeaseConfig(pool *model.PoolDefinition) error
SaveLeaseConfig validates and persists a change to the pool's lease options without touching membership.
func (*PoolService) SetSize ¶ added in v0.28.0
func (s *PoolService) SetSize(pool *model.PoolDefinition, desiredCount int, user *model.User) error
func (*PoolService) Start ¶ added in v0.28.0
func (s *PoolService) Start(pool *model.PoolDefinition, user *model.User) error
func (*PoolService) StartReaper ¶ added in v0.28.0
func (s *PoolService) StartReaper()
func (*PoolService) StartSweep ¶ added in v0.28.0
func (s *PoolService) StartSweep()
func (*PoolService) Stop ¶ added in v0.28.0
func (s *PoolService) Stop(pool *model.PoolDefinition, user *model.User) error
func (*PoolService) SweepOnce ¶ added in v0.28.0
func (s *PoolService) SweepOnce() error
func (*PoolService) SyncSpaceLease ¶ added in v0.36.0
func (s *PoolService) SyncSpaceLease(space *model.Space)
SyncSpaceLease updates the in-memory lease view from a space record. Called at startup, on lease operations, and when a gossiped space merge changes a member's lease fields — that keeps servers that joined late or missed a lease gossip push converged with the durable truth.
func (*PoolService) UpdateStartupScript ¶ added in v0.28.0
func (s *PoolService) UpdateStartupScript(pool *model.PoolDefinition, scriptId string, user *model.User) error
UpdateStartupScript changes the pool's startup script and applies it to all existing member spaces. The pool must be stopped.
type PoolSessionState ¶ added in v0.28.0
type ScriptListOptions ¶ added in v0.23.0
type ScriptService ¶ added in v0.23.0
type ScriptService struct{}
func GetScriptService ¶ added in v0.23.0
func GetScriptService() *ScriptService
func (*ScriptService) ListScripts ¶ added in v0.23.0
func (s *ScriptService) ListScripts(opts ScriptListOptions) ([]*model.Script, error)
ListScripts returns a filtered list of scripts based on the provided options
type ServerScriptlingOptions ¶ added in v0.33.0
type ServerScriptlingOptions struct {
User *model.User
MCPParams map[string]object.Object
EventParams map[string]object.Object
EventEnvelope *EventEnvelope
}
ServerScriptlingOptions configures a server-side scriptling environment. Exactly one mode is selected by what is set: MCPParams (with User) selects MCP tool execution — result capture via the returned MCPLibrary; EventEnvelope (with User) selects event sink execution — knot.event accessors and the event payload/metadata variables.
type SkillListOptions ¶ added in v0.23.0
type SkillService ¶ added in v0.23.0
type SkillService struct{}
func GetSkillService ¶ added in v0.23.0
func GetSkillService() *SkillService
func (*SkillService) ListSkills ¶ added in v0.23.0
func (s *SkillService) ListSkills(opts SkillListOptions) ([]*model.Skill, error)
type SpaceListOptions ¶ added in v0.19.0
type SpaceService ¶ added in v0.19.0
type SpaceService struct{}
func GetSpaceService ¶ added in v0.19.0
func GetSpaceService() *SpaceService
func (*SpaceService) CheckUserQuotas ¶ added in v0.19.0
checkUserQuotas validates user quotas for space creation
func (*SpaceService) CreateSpace ¶ added in v0.19.0
CreateSpace creates a new space with validation and quota checks
func (*SpaceService) DeleteSpace ¶ added in v0.19.0
func (s *SpaceService) DeleteSpace(spaceId string, user *model.User) error
DeleteSpace marks a space as deleted with validation
func (*SpaceService) GetSpace ¶ added in v0.19.0
GetSpace retrieves a single space by ID with permission checks
func (*SpaceService) GetSpaceCustomField ¶ added in v0.21.5
func (s *SpaceService) GetSpaceCustomField(spaceId string, fieldName string, user *model.User) (string, error)
GetSpaceCustomField retrieves a single custom field value from a space
func (*SpaceService) ListSpaces ¶ added in v0.19.0
func (s *SpaceService) ListSpaces(opts SpaceListOptions) ([]*model.Space, error)
ListSpaces returns a filtered list of spaces based on the provided options
func (*SpaceService) RemoveDependencyReferences ¶ added in v0.24.0
func (s *SpaceService) RemoveDependencyReferences(spaceId string, ownerUserId string) error
func (*SpaceService) SetSpaceCustomField ¶ added in v0.21.5
func (s *SpaceService) SetSpaceCustomField(spaceId string, fieldName string, fieldValue string, user *model.User) error
SetSpaceCustomField sets or updates a single custom field on a space
func (*SpaceService) SetSpaceJobs ¶ added in v0.33.0
func (s *SpaceService) SetSpaceJobs(spaceId string, jobs []model.SpaceJob, jobsEnabled bool, user *model.User) error
SetSpaceJobs replaces the space's job definitions and runner state. The definitions are validated before the call; the caller is responsible for pushing them to a connected agent.
func (*SpaceService) UpdateSpace ¶ added in v0.19.0
UpdateSpace updates an existing space with validation
func (*SpaceService) ValidateDependencies ¶ added in v0.24.0
func (s *SpaceService) ValidateDependencies(space *model.Space) error
func (*SpaceService) ValidateDependenciesRunning ¶ added in v0.24.0
func (s *SpaceService) ValidateDependenciesRunning(space *model.Space) error
type TemplateListOptions ¶ added in v0.19.0
type TemplateService ¶ added in v0.19.0
type TemplateService struct{}
func GetTemplateService ¶ added in v0.19.0
func GetTemplateService() *TemplateService
func (*TemplateService) CreateTemplate ¶ added in v0.19.0
func (*TemplateService) DeleteTemplate ¶ added in v0.19.0
func (s *TemplateService) DeleteTemplate(templateId string, user *model.User) error
DeleteTemplate marks a template as deleted with validation
func (*TemplateService) GetTemplate ¶ added in v0.19.0
func (s *TemplateService) GetTemplate(templateId string) (*model.Template, error)
GetTemplate retrieves a single template by ID
func (*TemplateService) GetTemplateUsage ¶ added in v0.19.0
func (s *TemplateService) GetTemplateUsage(templateId string) (total int, deployed int, err error)
GetTemplateUsage returns usage statistics for a template
func (*TemplateService) ListTemplates ¶ added in v0.19.0
func (s *TemplateService) ListTemplates(opts TemplateListOptions) ([]*model.Template, error)
ListTemplates returns a filtered list of templates based on the provided options
func (*TemplateService) UpdateTemplate ¶ added in v0.19.0
UpdateTemplate updates an existing template with validation
type Transport ¶
type Transport interface {
GossipGroup(group *model.Group)
GossipRole(role *model.Role)
GossipSpace(space *model.Space)
GossipTemplate(template *model.Template)
GossipTemplateVar(templateVar *model.TemplateVar)
GossipUser(user *model.User)
GossipToken(token *model.Token)
GossipVolume(volume *model.Volume)
GossipSpaceUsageSample(sample *model.SpaceUsageSample)
GossipAuditLog(entry *model.AuditLogEntry)
GossipAuthFailure(evt *authratelimit.Event)
GossipDeviceGrant(grant *devicegrant.Grant)
GossipSession(session *model.Session)
GossipScript(script *model.Script)
GossipSkill(skill *model.Skill)
GossipCommand(command *model.Command)
GossipEventSink(sink *model.EventSink)
GossipStackDefinition(stackDef *model.StackDefinition)
GossipResponse(response *model.Response)
GossipConversation(conv *model.Conversation)
GossipMCPServer(server *model.MCPServer)
GossipPoolDefinition(pool *model.PoolDefinition)
GossipPoolDrain(spaceID string)
GossipPoolUndrain(spaceID string)
GossipPoolLease(spaceID, userId string, expiresAtUnix int64)
GossipPoolLeaseClear(spaceID string)
BroadcastEvent(envelope *EventEnvelope)
NotifyEventDone(eventId string)
GetAgentEndpoints() []string
GetTunnelServers() []string
IsLeader() bool
LockResource(resourceId string) string
UnlockResource(resourceId, unlockToken string)
Nodes() []*gossip.Node
GetNodeByIDString(id string) *gossip.Node
EnqueueSpaceCleanup(space *model.Space)
}
func GetTransport ¶
func GetTransport() Transport
type UserService ¶
type UserService interface {
// User deletion operations
DeleteUser(user *model.User) error
RemoveUsersSessions(user *model.User)
RemoveUsersTokens(user *model.User)
// SSH key and space management
UpdateUserSpaces(user *model.User)
UpdateSpacesSSHKey(user *model.User)
UpdateSpaceSSHKeys(space *model.Space, user *model.User)
}
UserService defines operations that can be performed on users
func GetUserService ¶
func GetUserService() UserService
Source Files
¶
- agent_plugins.go
- command_resolver.go
- commands.go
- container.go
- conversations.go
- event_dispatch.go
- event_hooks.go
- event_script.go
- forward.go
- forward_target.go
- icons.go
- kvm.go
- node_selection.go
- plugin_call_library.go
- plugin_call_loopback.go
- plugin_dispatch.go
- plugin_env_pool.go
- pools.go
- script_resolver.go
- scriptling_env.go
- scriptling_result.go
- scripts.go
- skill_resolver.go
- skills.go
- spaces.go
- stack_vars.go
- templates.go
- transport.go
- user.go
- user_object.go
- web_host.go