daemon

package
v0.87.0 Latest Latest
Warning

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

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

Documentation

Overview

Package daemon owns the one local, read-only `datatug serve` process that AI-agent mods use so their cards can link to the DataTug web UI (spec/features/cli/daemon). The CLI is the owner of that process: it records it in a state directory (pidfile, record, log) and stops it with Stop.

Index

Constants

View Source
const (
	// DefaultPort is the preferred agent port; MaxPort bounds the search for a free one.
	DefaultPort = 8989
	MaxPort     = 9009
	// Host is the only address the daemon binds.
	Host = "127.0.0.1"
	// IdleTimeout is how long the daemon runs without a request before it exits.
	IdleTimeout = 2 * time.Hour

	// Fixed failure phrases: they never carry a path, URL or credential.
	ErrPhraseNoPort   = "no free port between 8989 and 9009"
	ErrPhraseExited   = "server exited during start"
	ErrPhraseTimeout  = "server was not ready within 5s"
	ErrPhraseNoBinary = "cannot locate the datatug binary"
	ErrPhraseSpawn    = "cannot launch the server"
	ErrPhraseState    = "cannot write the daemon state directory"
)
View Source
const (
	KindTableMetadata = "table-metadata"
	KindTableRecords  = "table-records"
	KindRecord        = "record"

	// UISupport values: pending means the web UI has no route for the kind yet.
	UISupportAvailable = "available"
	UISupportPending   = "pending"

	// DefaultUIBase is the hosted web UI; DATATUG_UI_BASE replaces it.
	DefaultUIBase = "https://datatug.app"
	UIBaseEnv     = "DATATUG_UI_BASE"

	DefaultLimit = 50
	MaxLimit     = 1000
)

Link kinds, as printed by `daemon url`.

View Source
const DirEnv = "DATATUG_DAEMON_DIR"

DirEnv overrides the state directory (default ~/datatug/daemon).

View Source
const (
	// MaxLinkLength bounds a link: the mod SDK draws at most this many characters.
	MaxLinkLength = 2048
)

Variables

View Source
var ErrNotOwned = errors.New("no daemon started by this CLI")

ErrNotOwned is returned by Stop for a datatug API this CLI did not start.

Functions

func UIBase

func UIBase(port int) string

UIBase is the web UI address of the agent on port.

Types

type ErrNotRunning

type ErrNotRunning struct{ Phrase string }

ErrNotRunning is returned by Start, next to its Status, when no server runs.

func (ErrNotRunning) Error

func (e ErrNotRunning) Error() string
type Link struct {
	URL       string `json:"url"`
	Kind      string `json:"kind"`
	Running   bool   `json:"running"`
	UISupport string `json:"uiSupport"`
}

Link is the deep link of one card.

func BuildLink(st Status, req LinkRequest) (Link, error)

BuildLink builds the deep link of contract deep-link-contract for the agent reported by st: identity in the path, view parameters (limit, schema) in the query, the record key in the fragment so it is never sent to the web host. It never reaches the network.

type LinkRequest

type LinkRequest struct {
	Project, Env, DB, Table, Schema string
	View                            bool
	Records                         bool
	Limit                           int
	Record                          string // primary key as a JSON object
	// Code is the one-time code of the agent (agentaccess.MintCode), put first in the fragment of
	// every link; "" when the agent has none to give.
	Code string
}

LinkRequest names one card's target.

type Manager

type Manager struct {
	Dir   string
	Exe   func() (string, error)
	Probe func(port int) (version string, ok bool)
	// Dial says whether something accepts a TCP connection on 127.0.0.1:port. It sends no
	// HTTP request, so it never counts as activity for the server's idle timer.
	Dial     func(port int) bool
	PortFree func(port int) bool
	Alive    func(pid int) bool
	// Owns says whether pid is a `datatug serve` on port (guards against a reused pid).
	Owns      func(pid, port int) bool
	Terminate func(pid int) error
	// Spawn starts the detached server and returns its pid and a channel closed when it exits.
	Spawn func(exe string, args []string, logPath string) (pid int, exited <-chan struct{}, err error)
	Now   func() time.Time
	Sleep func(time.Duration)
	// StartWait bounds the readiness wait; Poll is its interval.
	StartWait time.Duration
	Poll      time.Duration
}

Manager holds the state directory and every seam over the OS, so tests drive the whole lifecycle without a real process or port.

func NewManager

func NewManager() *Manager

NewManager returns the Manager wired to the real OS.

func (*Manager) LogFile

func (m *Manager) LogFile() string

LogFile is where the daemon's stdout and stderr go.

func (*Manager) Start

func (m *Manager) Start(caller string) (Status, error)

Start ensures the daemon runs. The returned Status is always set; the error is ErrNotRunning when no server could be brought up.

func (*Manager) Status

func (m *Manager) Status() Status

Status reports the daemon without starting or stopping anything, and without sending an HTTP request to a server this CLI started (a request would reset its idle timer): the record, the pid and a TCP connect decide (no process-command check, which can fail in a sandbox and, on Windows, is an HTTP probe). A datatug API this CLI did not start (no record of it) is the one case that costs a single agent-info request, because a TCP connect cannot tell it from a foreign listener on the port.

func (*Manager) Stop

func (m *Manager) Stop() error

Stop ends the daemon this CLI started. A datatug API it did not start is never touched (ErrNotOwned); any other process is never signalled.

type Record

type Record struct {
	PID         int       `json:"pid"`
	Port        int       `json:"port"`
	URL         string    `json:"url"`
	StartedAt   time.Time `json:"startedAt"`
	StartedBy   string    `json:"startedBy"`
	Version     string    `json:"version"`
	Binary      string    `json:"binary"`
	IdleTimeout string    `json:"idleTimeout"`
}

Record is what the CLI persists about the daemon it started (daemon.json).

type Status

type Status struct {
	Running     bool   `json:"running"`
	URL         string `json:"url"`
	UIBase      string `json:"uiBase"`
	Port        int    `json:"port"`
	PID         int    `json:"pid"`
	StartedBy   string `json:"startedBy"`
	StartedAt   string `json:"startedAt,omitempty"`
	Version     string `json:"version"`
	LogFile     string `json:"logFile"`
	IdleTimeout string `json:"idleTimeout"`
	Error       string `json:"error,omitempty"`
}

Status is the machine-readable state printed by `daemon status|start`.

type UsageError

type UsageError struct{ Msg string }

UsageError is a bad `daemon url` input (exit code 2).

func (UsageError) Error

func (e UsageError) Error() string

Jump to

Keyboard shortcuts

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