Documentation
¶
Overview ¶
Package config contains configuration types for agnt.
Package config defines configuration types for agnt, parsed from .agnt.kdl files using KDL format. It also provides shell resolution, platform detection (WSL-aware), and port conflict utilities.
Key types:
- AgntConfig: top-level project configuration
- ScriptConfig: per-script autostart configuration
- ProxyConfig: per-proxy configuration with fallback-port support
Package config provides port detection for auto-started scripts.
Index ¶
- Constants
- Variables
- func FindAgntConfigFile(dir string) string
- func FindPIDsByPort(ctx context.Context, port int) []int
- func FindPIDsByPortTagged(ctx context.Context, port int) (linuxPIDs, windowsPIDs []int)
- func GlobalConfigPath() string
- func ProcessNameByPID(pid int) string
- func ProcessNamesByPIDs(ctx context.Context, pids []int) map[int]string
- func TopologicalSort(scripts map[string]*ScriptConfig) ([][]string, error)
- func ValidateDependencies(scripts map[string]*ScriptConfig) (warnings []string, err error)
- func WriteDefaultAgntConfig(path string) error
- func WriteDefaultConfig(path string) error
- type AIAdapterConfig
- type AIConfig
- type AgntConfig
- type AgntProjectMeta
- type AlertPatternConfig
- type AlertsConfig
- type AutoForwardConfig
- type ChannelConfig
- type CommandConfig
- type Config
- type DependsOnList
- type HealthPatterns
- type HookBashPattern
- type HookPromptPattern
- type HookRulesConfig
- type HooksConfig
- type KDLCommand
- type KDLConfig
- type KDLLanguage
- type KDLLanguages
- type KDLProjectConfig
- type KDLSettings
- type LanguageConfig
- type OutageHoldConfig
- func (c *OutageHoldConfig) GetJSCascadePatterns() []string
- func (c *OutageHoldConfig) GetRecoveryDebounce() time.Duration
- func (c *OutageHoldConfig) GetTransportErrThreshold() int
- func (c *OutageHoldConfig) GetTransportErrWindow() time.Duration
- func (c *OutageHoldConfig) GetWindow() time.Duration
- func (c *OutageHoldConfig) IsEnabled() bool
- type PortDetector
- type ProjectConfig
- type ProxyConfig
- type PushConfig
- type ResponseHookConfig
- type ScriptConfig
- type ScriptDependency
- type ScriptLifecycleHooks
- type SessionConfig
- type Settings
- type SetupConfig
- type ToastConfig
Constants ¶
const ( GlobalConfigFile = "config.kdl" ProjectConfigFile = ".agnt.kdl" )
KDL configuration file names
const AgntConfigFileName = ".agnt.kdl"
AgntConfigFileName is the name of the agnt configuration file.
const DefaultDependencyTimeout = 120 * time.Second
DefaultDependencyTimeout is the legacy default timeout for script dependencies. The current parser defaults to 0 (wait indefinitely until the parent context is cancelled or an explicit per-dep timeout is set in .agnt.kdl), so this constant is retained only for backward compatibility with internal/autostart and existing tests.
const DefaultRenudgeTTLDays = 7
DefaultRenudgeTTLDays is the fallback re-nudge window when no `setup` block (or a non-positive value) is configured.
Variables ¶
var DefaultJSCascadePatterns = []string{
"Failed to fetch",
"NetworkError",
"WebSocket",
"ERR_CONNECTION_REFUSED",
"ERR_NETWORK_CHANGED",
"ERR_INTERNET_DISCONNECTED",
"net::ERR_",
"Load failed",
"send was called before connect",
"@vite/client",
"ViteHotContext",
"failed to connect to websocket",
"[HMR]",
"Disconnected. Attempting to reconnect",
}
DefaultJSCascadePatterns is the substring set that flags a browser-JS error as a transport-layer cascade rather than a genuine app error.
Functions ¶
func FindAgntConfigFile ¶ added in v0.7.8
FindAgntConfigFile searches for .agnt.kdl starting from dir and walking up.
func FindPIDsByPort ¶ added in v0.12.28
FindPIDsByPort returns PIDs of processes listening on the given TCP port. Uses /proc/net/tcp on Linux or lsof on macOS.
On WSL, /proc/net/tcp only sees Linux-side listeners. When the Linux scan returns zero PIDs and we are running under WSL, we fall back to netstat.exe -ano to surface Windows-side listeners (browsers, Docker Desktop, IIS, etc.) holding the port. The fallback is conditional, not additive, because netstat.exe shells out and parses CSV (~50-150 ms), which would dominate the hot path of port preflight / autostart cleanup on the 99% case where the owner is a Linux process.
Callers that need to kill the returned PIDs should use FindPIDsByPortTagged instead — Windows-side PIDs require taskkill.exe (platform.KillWindowsPID), while Linux-side PIDs use syscall.Kill via the normal ProcessManager path. FindPIDsByPort remains the right call when you only need visibility (doctor, preflight detection, status display).
func FindPIDsByPortTagged ¶ added in v0.13.5
FindPIDsByPortTagged is the kill-routing-aware variant of FindPIDsByPort. Returns two slices: PIDs sourced from the Linux scan (/proc/net/tcp on Linux, lsof on macOS) and PIDs sourced from the Windows scan (netstat.exe on WSL when the Linux scan was empty). The split tells callers which kill path to use:
- Linux PIDs → syscall.Kill via ProcessManager.KillProcessByPort
- Windows PIDs → platform.KillWindowsPID (shells to taskkill.exe)
On macOS and non-WSL Linux hosts the windows slice is always nil. On native Windows builds (portdetect_windows.go) all PIDs are tagged as Windows-side because there is no Linux namespace to be in. The fallback shape — Linux scan first, Windows scan only when Linux is empty — matches FindPIDsByPort to preserve hot-path latency: netstat.exe shells out (~50-150ms) and we don't pay it when /proc/net/tcp answers.
func GlobalConfigPath ¶
func GlobalConfigPath() string
GlobalConfigPath returns the path to the global config file.
func ProcessNameByPID ¶ added in v0.12.36
ProcessNameByPID returns the process name for a given PID. Returns empty string if the PID doesn't exist or can't be read.
On WSL, when /proc lookup misses (the PID is a Windows-side process surfaced by FindPIDsByPort's netstat.exe fallback), we shell out to tasklist.exe as a one-shot resolution. The tasklist.exe call is skipped entirely when /proc resolves, so purely-Linux PIDs pay zero fallback cost.
For batch resolution of multiple rogue PIDs (e.g. doctor command), prefer ProcessNamesByPIDs which coalesces N PIDs into a single tasklist.exe invocation.
func ProcessNamesByPIDs ¶ added in v0.13.5
ProcessNamesByPIDs resolves a batch of PIDs to process names. Linux PIDs are resolved via /proc; PIDs that miss /proc are batched into a single tasklist.exe invocation on WSL. Returns a map keyed by PID; PIDs that resolve to nothing (no /proc entry, no tasklist.exe match, or running outside WSL) are simply absent from the map.
The batched tasklist.exe call is the cache discipline called for in the WSL-doctor task: N rogue PIDs cost at most one shell-out, not N.
func TopologicalSort ¶ added in v0.12.8
func TopologicalSort(scripts map[string]*ScriptConfig) ([][]string, error)
TopologicalSort sorts scripts into execution layers based on their dependencies. Returns layers where each layer's scripts can run in parallel, and all dependencies from prior layers are satisfied. Returns an error if a circular dependency is detected.
func ValidateDependencies ¶ added in v0.12.8
func ValidateDependencies(scripts map[string]*ScriptConfig) (warnings []string, err error)
ValidateDependencies checks dependency configuration for errors and warnings. Returns an error for fatal issues (unknown deps, cycles) and a list of warning messages for non-fatal issues (deps on non-autostart scripts).
func WriteDefaultAgntConfig ¶ added in v0.7.8
WriteDefaultAgntConfig writes a default configuration file with documentation.
func WriteDefaultConfig ¶
WriteDefaultConfig writes a default config file with documentation.
Types ¶
type AIAdapterConfig ¶ added in v0.12.44
type AIAdapterConfig struct {
// Disabled disables prompt injection for this agent entirely.
Disabled bool `kdl:"disabled"`
// FlagName overrides the CLI flag used for flag-based injection.
// Ignored by stdin-based adapters. Example: "--system-prompt".
FlagName string `kdl:"flag-name"`
// StdinDelayMs overrides the delay (in milliseconds) before
// injecting initial stdin. Ignored by flag-based adapters.
StdinDelayMs int `kdl:"stdin-delay-ms"`
}
AIAdapterConfig overrides the built-in behavior of a single [agentadapter.Adapter]. All fields are optional.
type AIConfig ¶ added in v0.11.4
type AIConfig struct {
// Skill is a skill/persona name to use (e.g., "code-review", "debugging")
Skill string `kdl:"skill"`
// Env are environment variables to set for AI commands
Env map[string]string `kdl:"env"`
// Context is a brief project description injected at the top of the system
// prompt, before the agnt tools list. Use it to tell the AI what the project
// is, which ports/URLs to use, and any other startup context.
// Example: "React + FastAPI app. Dev server: port 3000, API: port 8080."
Context string `kdl:"context"`
// SystemPrompt is a full system prompt that replaces the default
SystemPrompt string `kdl:"system-prompt"`
// AppendSystemPrompt is appended to the default system prompt
AppendSystemPrompt string `kdl:"append-system-prompt"`
// Adapters is the map of per-adapter injection overrides, keyed by
// lowercase agent name (e.g. "claude", "aider"). Empty / missing
// entries inherit the adapter's default behavior.
//
// See internal/agentadapter for the set of built-in adapters and
// docs/agent-adapters.md for a guide to adding a new one.
Adapters map[string]*AIAdapterConfig `kdl:"adapters"`
// HelpersCheatSheet controls whether the compact __devtool.*
// helpers cheat sheet is appended to the default system prompt.
// nil (the default) means "enabled"; set to an explicit false to
// omit the cheat sheet — useful when the agent is already primed
// via skill/prompt overrides and the extra ~40 lines are noise.
HelpersCheatSheet *bool `kdl:"helpers-cheat-sheet"`
}
AIConfig configures AI agent behavior for run and ai commands.
func (*AIConfig) CheatSheetEnabled ¶ added in v0.12.44
CheatSheetEnabled reports whether the helpers cheat sheet should be included. Default is true; explicit false disables it.
type AgntConfig ¶ added in v0.7.8
type AgntConfig struct {
// Project metadata (optional, for documentation/info only)
Project *AgntProjectMeta `kdl:"project"`
// Scripts to manage
Scripts map[string]*ScriptConfig `kdl:"scripts"`
// Proxies to manage
Proxies map[string]*ProxyConfig `kdl:"proxies"`
// AI configuration for run and ai commands
AI *AIConfig `kdl:"ai"`
// Hooks configuration
Hooks *HooksConfig `kdl:"hooks"`
// Toast notification settings
Toast *ToastConfig `kdl:"toast"`
// Alerts configuration for process output monitoring
Alerts *AlertsConfig `kdl:"alerts"`
// Channel configuration for MCP push-based event forwarding
Channel *ChannelConfig `kdl:"channel"`
// Session lifecycle configuration (daemon-side cleanup policies)
Session *SessionConfig `kdl:"session"`
// HookRules configures the `agnt hook check-bash` / `check-prompt`
// interceptors. Parsed here so the hookrules package can pull a
// single AgntConfig via LoadAgntConfig rather than re-parsing KDL.
HookRules *HookRulesConfig `kdl:"hook-rules"`
// Setup configures the first-run auto-setup flow for `agnt run`.
Setup *SetupConfig `kdl:"setup"`
}
AgntConfig represents the agnt configuration. All fields use standard KDL format with child nodes.
func DefaultAgntConfig ¶ added in v0.7.8
func DefaultAgntConfig() *AgntConfig
DefaultAgntConfig returns a config with sensible defaults.
func LoadAgntConfig ¶ added in v0.7.8
func LoadAgntConfig(dir string) (*AgntConfig, error)
LoadAgntConfig loads configuration from the specified directory. It looks for .agnt.kdl in the directory and its parents.
func LoadAgntConfigFile ¶ added in v0.7.8
func LoadAgntConfigFile(path string) (*AgntConfig, error)
LoadAgntConfigFile loads configuration from a specific file.
func ParseAgntConfig ¶ added in v0.7.8
func ParseAgntConfig(data string) (*AgntConfig, error)
ParseAgntConfig parses KDL configuration data using the official kdl-go parser. Only standard KDL format is supported.
func (*AgntConfig) BuildSystemPrompt ¶ added in v0.11.4
func (c *AgntConfig) BuildSystemPrompt() string
BuildSystemPrompt generates the system prompt based on configuration. If SystemPrompt is set, it returns that directly. Otherwise, it builds a prompt describing agnt features and configured services, then appends AppendSystemPrompt if set.
func (*AgntConfig) EffectivePortConflictPolicy ¶ added in v0.12.36
func (c *AgntConfig) EffectivePortConflictPolicy() string
EffectivePortConflictPolicy returns the port-conflict policy, defaulting to "prompt".
func (*AgntConfig) GetAutostartProxies ¶ added in v0.7.8
func (c *AgntConfig) GetAutostartProxies() map[string]*ProxyConfig
GetAutostartProxies returns proxies that should auto-start.
func (*AgntConfig) GetAutostartScripts ¶ added in v0.7.8
func (c *AgntConfig) GetAutostartScripts() map[string]*ScriptConfig
GetAutostartScripts returns scripts configured for autostart.
func (*AgntConfig) PortConflictPolicy ¶ added in v0.12.36
func (c *AgntConfig) PortConflictPolicy() string
PortConflictPolicy returns the raw port-conflict policy from config.
type AgntProjectMeta ¶ added in v0.11.1
type AgntProjectMeta struct {
Type string `kdl:"type"`
Name string `kdl:"name"`
PortConflict string `kdl:"port-conflict"`
}
AgntProjectMeta contains optional project metadata in .agnt.kdl.
type AlertPatternConfig ¶ added in v0.11.5
type AlertPatternConfig struct {
// Pattern is a regular expression to match against output lines.
Pattern string `kdl:"pattern"`
// Severity is "error", "warning", or "info".
Severity string `kdl:"severity"`
}
AlertPatternConfig defines a custom alert pattern in configuration.
type AlertsConfig ¶ added in v0.11.5
type AlertsConfig struct {
// Enabled controls whether alerts are active. Default: true.
Enabled *bool `kdl:"enabled"`
// Patterns defines custom alert patterns keyed by ID.
Patterns map[string]*AlertPatternConfig `kdl:"patterns"`
// Disable is a list of built-in pattern IDs to disable.
Disable []string `kdl:"disable"`
// BatchWindow is the batching window in seconds before delivering alerts.
// Default: 3.
BatchWindow int `kdl:"batch-window"`
// DedupeWindow is the deduplication window in seconds.
// Duplicate alerts within this window are suppressed. Default: 60.
DedupeWindow int `kdl:"dedupe-window"`
// AutoForward configures automatic forwarding of browser/proxy errors to the AI agent.
AutoForward *AutoForwardConfig `kdl:"auto-forward"`
// Push configures which push channels are active for alert delivery.
Push *PushConfig `kdl:"push"`
// Preset names a predefined push channel configuration (e.g., "claude-code", "universal").
// When set, it expands into a PushConfig. An explicit Push block takes precedence.
Preset string `kdl:"preset"`
// IncidentPipeline enables the new incident pipeline (Phase A dual-path rollout).
// When false (default): existing AlertHub MCPAlertSink/OverlayAlertSink path is
// active; incident.Bus runs in parallel for observability only (no pings sent).
// When true: MCPAlertSink + OverlayAlertSink are suppressed; incident.Bus Pinger
// emits instead. StreamSink is unaffected in both modes.
// KDL: alerts { incident-pipeline true }
IncidentPipeline bool `kdl:"incident-pipeline"`
// OutageHold configures the transport-signal-driven outage gate that holds
// transport / browser-JS errors during dev-server restarts that the
// process-state classifier cannot detect (e.g. dotnet watch keeps the
// supervisor process Running while the embedded HTTP/WS server bounces).
OutageHold *OutageHoldConfig `kdl:"outage-hold"`
}
AlertsConfig configures process output alert monitoring.
func (*AlertsConfig) GetPushConfig ¶ added in v0.12.36
func (c *AlertsConfig) GetPushConfig() *PushConfig
GetPushConfig returns the effective PushConfig, applying presets if set. If no alerts config exists, returns nil (which means all channels enabled). When Preset is set and Push is nil, the preset is expanded into a PushConfig. An explicit Push block takes precedence over a preset.
func (*AlertsConfig) IncidentPipelineEnabled ¶ added in v0.13.0
func (c *AlertsConfig) IncidentPipelineEnabled() bool
IncidentPipelineEnabled returns whether the incident pipeline is active. Defaults to false when AlertsConfig is nil or the field is unset.
func (*AlertsConfig) IsEnabled ¶ added in v0.11.5
func (c *AlertsConfig) IsEnabled() bool
IsEnabled returns whether alerts are enabled (defaults to true).
type AutoForwardConfig ¶ added in v0.12.36
type AutoForwardConfig struct {
// Enabled controls whether browser/proxy errors are auto-forwarded. Default: true.
Enabled *bool `kdl:"enabled"`
// Sources specifies which error sources to forward. Default: ["browser", "http"].
Sources []string `kdl:"sources"`
// Debounce is the minimum seconds between forwarded errors. Default: 10.
Debounce int `kdl:"debounce"`
// Severity is the minimum severity to forward: "error" or "warning". Default: "error".
Severity string `kdl:"severity"`
}
AutoForwardConfig configures automatic error forwarding to the AI agent.
func (*AutoForwardConfig) GetDebounceSeconds ¶ added in v0.12.36
func (c *AutoForwardConfig) GetDebounceSeconds() int
GetDebounceSeconds returns the debounce interval (defaults to 10).
func (*AutoForwardConfig) GetSeverity ¶ added in v0.12.36
func (c *AutoForwardConfig) GetSeverity() string
GetSeverity returns the minimum severity (defaults to "error").
func (*AutoForwardConfig) GetSources ¶ added in v0.12.36
func (c *AutoForwardConfig) GetSources() []string
GetSources returns the sources to forward (defaults to ["browser", "http"]).
func (*AutoForwardConfig) IsEnabled ¶ added in v0.12.36
func (c *AutoForwardConfig) IsEnabled() bool
IsEnabled returns whether auto-forward is enabled (defaults to true).
func (*AutoForwardConfig) ShouldForwardSource ¶ added in v0.12.36
func (c *AutoForwardConfig) ShouldForwardSource(source string) bool
ShouldForwardSource checks if a given source is in the forward list.
type ChannelConfig ¶ added in v0.12.44
type ChannelConfig struct {
// Enabled controls whether the channel is active. Default: false.
Enabled *bool `kdl:"enabled"`
// Events is an allowlist of event types to forward.
// Empty/omitted means all types. Valid values: "error", "diagnostic", "interaction".
Events []string `kdl:"events"`
// Severity is the minimum event severity to forward.
// Valid values: "trace", "debug", "info", "warning", "error".
// Default: "warning".
Severity string `kdl:"severity"`
// DedupeWindow is the per-event deduplication window in milliseconds.
// 0 disables deduplication. Default: 2000.
DedupeWindow int `kdl:"dedupe-window"`
// ReplyTool controls whether the channel-reply MCP tool is registered.
// Default: true.
ReplyTool *bool `kdl:"reply-tool"`
}
ChannelConfig configures the MCP push-based channel for event forwarding. When enabled, the daemon pushes events to connected MCP sessions via a dedicated channel tool. This is pure configuration plumbing — no runtime behavior change until later tasks wire consumers.
func (*ChannelConfig) GetDedupeWindow ¶ added in v0.12.44
func (c *ChannelConfig) GetDedupeWindow() int
GetDedupeWindow returns the deduplication window in milliseconds (defaults to 2000).
func (*ChannelConfig) GetEvents ¶ added in v0.12.44
func (c *ChannelConfig) GetEvents() []string
GetEvents returns the event type allowlist (defaults to empty = all types).
func (*ChannelConfig) GetSeverity ¶ added in v0.12.44
func (c *ChannelConfig) GetSeverity() string
GetSeverity returns the minimum severity (defaults to "warning").
func (*ChannelConfig) IsEnabled ¶ added in v0.12.44
func (c *ChannelConfig) IsEnabled() bool
IsEnabled returns whether the channel is enabled (defaults to false).
func (*ChannelConfig) ReplyToolEnabled ¶ added in v0.12.44
func (c *ChannelConfig) ReplyToolEnabled() bool
ReplyToolEnabled returns whether the reply tool is registered (defaults to true).
type CommandConfig ¶
type CommandConfig struct {
// Command is the executable name.
Command string `json:"command"`
// Args are the default arguments.
Args []string `json:"args"`
// Description is a human-readable description.
Description string `json:"description,omitempty"`
// Timeout is the command timeout in seconds.
Timeout int `json:"timeout,omitempty"`
// Persistent indicates this is a long-running process.
Persistent bool `json:"persistent,omitempty"`
// Env holds environment variables to set.
Env map[string]string `json:"env,omitempty"`
}
CommandConfig holds configuration for a single command.
func (*CommandConfig) ToCommandDef ¶
func (c *CommandConfig) ToCommandDef(name string) project.CommandDef
ToCommandDef converts a CommandConfig to a project.CommandDef.
type Config ¶
type Config struct {
// Version is the config file version.
Version string `json:"version"`
// Settings are global server settings.
Settings Settings `json:"settings"`
// Languages holds language-specific configurations.
Languages map[string]LanguageConfig `json:"languages"`
}
Config holds the complete server configuration.
func LoadConfigFile ¶
LoadConfigFile loads configuration from a specific file path.
func LoadGlobalConfig ¶
LoadGlobalConfig loads the global configuration from the default location.
func ParseKDLConfig ¶
ParseKDLConfig parses KDL configuration data.
func (*Config) GetLanguageCommands ¶
func (c *Config) GetLanguageCommands(lang string) []project.CommandDef
GetLanguageCommands returns command definitions for a language.
func (*Config) MergeProjectConfig ¶
func (c *Config) MergeProjectConfig(projConfig *ProjectConfig) *Config
MergeProjectConfig merges per-project config with global config.
type DependsOnList ¶ added in v0.12.8
type DependsOnList []ScriptDependency
DependsOnList is a list of script dependencies with custom KDL unmarshaling. Supports two KDL formats:
Arguments format (all deps get default or node-level timeout):
depends-on "api" "redis" depends-on "api" timeout=45
Child node format (per-dependency timeouts):
depends-on {
api timeout=30
redis timeout=60
}
func (*DependsOnList) UnmarshalKDL ¶ added in v0.12.8
func (d *DependsOnList) UnmarshalKDL(node *document.Node) error
UnmarshalKDL implements the kdl.Unmarshaler interface for custom parsing.
type HealthPatterns ¶ added in v0.12.23
type HealthPatterns struct {
Error string // Regex that indicates an error
Healthy string // Regex that clears the error state
}
HealthPatterns holds compiled error and healthy regex patterns for a script.
func DefaultHealthPatterns ¶ added in v0.12.23
func DefaultHealthPatterns() HealthPatterns
DefaultHealthPatterns returns the default error/healthy patterns. These cover common dev server frameworks so most users get good behavior without explicit configuration.
Covered frameworks (healthy): Vite, Next.js, Webpack, Go stdlib, dotnet run, dotnet watch, Flask, uvicorn, gunicorn, Django, Spring Boot, Gradle, Maven, Rails, PHP artisan/built-in, Vapor (Swift), Phoenix (Elixir).
Covered frameworks (error): Go panics, Node.js module/syntax errors, TypeScript compiler, Rust compiler, Python tracebacks, .NET exceptions, EADDRINUSE, segfaults, OOM, fatal errors.
type HookBashPattern ¶ added in v0.12.44
type HookBashPattern struct {
Pattern string `kdl:"pattern"`
Action string `kdl:"action"`
Replacement string `kdl:"replacement"`
Reason string `kdl:"reason"`
}
HookBashPattern is one KDL-side Bash rule. The Pattern field is the regex matched against the Bash command string. Action must be one of "allow", "soft-warn", or "block" (case-insensitive); empty defaults to "block" consistent with the builtin catalog. Replacement cites the recommended MCP invocation shown in the block message.
type HookPromptPattern ¶ added in v0.12.44
HookPromptPattern is one KDL-side prompt rule. The Pattern field is the case-insensitive regex matched against the user prompt text; Reminder is the body of the <system-reminder> emitted on match.
type HookRulesConfig ¶ added in v0.12.44
type HookRulesConfig struct {
// BypassEnv overrides the default AGNT_HOOK_BYPASS env-var name.
BypassEnv string `kdl:"bypass-env"`
// BashPatterns is a map from rule name to bash pattern rule. The
// rule name is used only for diagnostics (rules list output) and
// does not affect matching order relative to builtins.
BashPatterns map[string]*HookBashPattern `kdl:"bash-patterns"`
// PromptPatterns is a map from rule name to prompt pattern rule.
PromptPatterns map[string]*HookPromptPattern `kdl:"prompt-patterns"`
}
HookRulesConfig is the KDL override block for hook interception rules. It lives in .agnt.kdl as:
hook-rules {
bypass-env "AGNT_HOOK_BYPASS"
bash-patterns {
block-rm-rf { pattern "rm -rf /"; action "block"; replacement "n/a"; reason "dangerous" }
}
prompt-patterns {
start-server { pattern "start.*server"; reminder "use agnt.run" }
}
}
Rules are merged with the builtin catalog in hookrules.LoadForProject. Invalid regexes in this block are silently skipped on the hot path (the hook must fail-open) but surfaced by `agnt hook rules test`.
type HooksConfig ¶ added in v0.7.8
type HooksConfig struct {
// OnResponse controls what happens when Claude responds
OnResponse *ResponseHookConfig `kdl:"on-response"`
}
HooksConfig defines hook behavior.
type KDLCommand ¶
type KDLCommand struct {
Command string `kdl:"cmd"`
Args []string `kdl:"args"`
Timeout int `kdl:"timeout"`
Persistent bool `kdl:"persistent"`
Env map[string]string `kdl:"env"`
}
KDLCommand holds a command configuration.
type KDLConfig ¶
type KDLConfig struct {
Version string `kdl:"version"`
Settings KDLSettings `kdl:"settings"`
Languages KDLLanguages `kdl:"languages"`
}
KDLConfig represents the KDL configuration structure. Uses kdl struct tags for unmarshaling.
type KDLLanguage ¶
type KDLLanguage struct {
Markers []string `kdl:"markers"`
Priority int `kdl:"priority"`
PackageManagerDetect bool `kdl:"package-manager-detect"`
Commands map[string]*KDLCommand `kdl:"commands"`
}
KDLLanguage holds configuration for a specific language.
type KDLLanguages ¶
type KDLLanguages struct {
Go *KDLLanguage `kdl:"go"`
Node *KDLLanguage `kdl:"node"`
Python *KDLLanguage `kdl:"python"`
}
KDLLanguages holds language configurations.
type KDLProjectConfig ¶
type KDLProjectConfig struct {
Language string `kdl:"language"`
PackageManager string `kdl:"package-manager"`
Commands map[string]*KDLCommand `kdl:"commands"`
}
KDLProjectConfig holds per-project configuration.
type KDLSettings ¶
type KDLSettings struct {
DefaultTimeout int `kdl:"default-timeout"`
MaxOutputBuffer int `kdl:"max-output-buffer"`
GracefulTimeout int `kdl:"graceful-timeout"`
}
KDLSettings holds global settings from KDL.
type LanguageConfig ¶
type LanguageConfig struct {
// Markers are files that identify this project type.
Markers []string `json:"markers"`
// Priority determines detection order (higher = first).
Priority int `json:"priority"`
// Commands are the available commands for this language.
Commands map[string]CommandConfig `json:"commands"`
// PackageManagerDetect enables automatic package manager detection (Node.js).
PackageManagerDetect bool `json:"package_manager_detect,omitempty"`
}
LanguageConfig holds configuration for a specific language.
type OutageHoldConfig ¶ added in v0.13.7
type OutageHoldConfig struct {
// Enabled controls whether the hold buffer is active. Default: true.
Enabled *bool `kdl:"enabled"`
// WindowMs is how long a held event waits before being force-emitted
// when no recovery signal arrives. Default: 3000.
WindowMs int `kdl:"window-ms"`
// TransportErrThreshold is how many transport errors must occur within
// TransportErrWindowMs before the proxy enters synthetic outage. Default: 1.
TransportErrThreshold int `kdl:"transport-err-threshold"`
// TransportErrWindowMs is the sliding window for the threshold check.
// Default: 1000.
TransportErrWindowMs int `kdl:"transport-err-window-ms"`
// RecoveryDebounceMs is the minimum time after entering outage before
// recovery signals are honoured. Guards against single-request races
// where a 2xx arrives interleaved with a refused connection. Default: 500.
RecoveryDebounceMs int `kdl:"recovery-debounce-ms"`
// JSCascadePatterns is the case-insensitive substring list used to
// classify a browser-JS error as transport-cascade. Cascade entries are
// dropped on recovery; non-cascade entries are emitted. Default: the
// standard set covering "Failed to fetch", "NetworkError", "WebSocket",
// "ERR_CONNECTION_REFUSED", "ERR_NETWORK_CHANGED",
// "ERR_INTERNET_DISCONNECTED", "net::ERR_", "Load failed".
JSCascadePatterns []string `kdl:"js-cascade-patterns"`
}
OutageHoldConfig configures the per-proxy hold-buffer that suppresses transport-cascade noise during dev-server restarts.
Default behaviour (when nil or unset): hold buffer is enabled with a 3s window and the standard JS cascade pattern set. Set Enabled=false to fall back to the legacy drop-during-process-state-suppression behaviour.
func (*OutageHoldConfig) GetJSCascadePatterns ¶ added in v0.13.7
func (c *OutageHoldConfig) GetJSCascadePatterns() []string
GetJSCascadePatterns returns the configured cascade patterns or the default set if none are configured.
func (*OutageHoldConfig) GetRecoveryDebounce ¶ added in v0.13.7
func (c *OutageHoldConfig) GetRecoveryDebounce() time.Duration
GetRecoveryDebounce returns the recovery-signal debounce window. Defaults to 500ms.
func (*OutageHoldConfig) GetTransportErrThreshold ¶ added in v0.13.7
func (c *OutageHoldConfig) GetTransportErrThreshold() int
GetTransportErrThreshold returns the err count required to enter outage. Defaults to 1.
func (*OutageHoldConfig) GetTransportErrWindow ¶ added in v0.13.7
func (c *OutageHoldConfig) GetTransportErrWindow() time.Duration
GetTransportErrWindow returns the sliding-window duration for the threshold check. Defaults to 1s.
func (*OutageHoldConfig) GetWindow ¶ added in v0.13.7
func (c *OutageHoldConfig) GetWindow() time.Duration
GetWindow returns the hold-window duration. Defaults to 3s.
func (*OutageHoldConfig) IsEnabled ¶ added in v0.13.7
func (c *OutageHoldConfig) IsEnabled() bool
IsEnabled returns whether the hold buffer is active. Defaults to true.
type PortDetector ¶ added in v0.7.8
type PortDetector struct {
// contains filtered or unexported fields
}
PortDetector detects listening ports from processes.
func NewPortDetector ¶ added in v0.7.8
func NewPortDetector() *PortDetector
NewPortDetector creates a new port detector with common patterns.
func (*PortDetector) DetectFromOutput ¶ added in v0.7.8
func (pd *PortDetector) DetectFromOutput(output string) int
DetectFromOutput scans output text for port patterns. Returns the first port found, or 0 if none detected.
func (*PortDetector) DetectFromPID ¶ added in v0.7.8
func (pd *PortDetector) DetectFromPID(ctx context.Context, pid int) []int
DetectFromPID finds listening TCP ports for a process. Uses platform-native APIs: /proc/net/tcp on Linux, lsof on macOS, netstat on Windows. Returns all detected ports.
func (*PortDetector) WaitForPort ¶ added in v0.7.8
func (pd *PortDetector) WaitForPort(ctx context.Context, pid int, getOutput func() string, timeout time.Duration) int
WaitForPort waits for a port to be detected, either from output or PID. Returns the detected port or 0 if timeout expires.
type ProjectConfig ¶
type ProjectConfig struct {
// Language overrides the detected language.
Language string `json:"language,omitempty"`
// PackageManager overrides the detected package manager.
PackageManager string `json:"package_manager,omitempty"`
// Commands override default commands.
Commands map[string]CommandConfig `json:"commands,omitempty"`
}
ProjectConfig holds per-project configuration from .agnt.kdl.
func LoadProjectConfig ¶
func LoadProjectConfig(projectPath string) (*ProjectConfig, error)
LoadProjectConfig loads per-project configuration from .agnt.kdl.
func ParseProjectConfig ¶
func ParseProjectConfig(data string) (*ProjectConfig, error)
ParseProjectConfig parses per-project KDL configuration.
type ProxyConfig ¶ added in v0.7.8
type ProxyConfig struct {
// Autostart starts the proxy when session opens
Autostart bool `kdl:"autostart"`
// MaxLogSize is the max number of log entries to keep
MaxLogSize int `kdl:"max-log-size"`
// Script links this proxy to a script for URL detection from output
Script string `kdl:"script"`
// URLPattern filters which detected URLs should trigger this proxy.
// Regex pattern matched against detected URLs. Use to select specific ports
// when a script outputs multiple URLs (e.g., ":34115" to match Wails backend).
URLPattern string `kdl:"url-pattern"`
// URL is the full target URL (e.g., "http://localhost:3000")
URL string `kdl:"url"`
// Target is the backend URL (deprecated, use URL instead)
Target string `kdl:"target"`
// Port is the target port - shorthand for http://localhost:PORT
Port int `kdl:"port"`
// FallbackPort is used when script URL detection fails
FallbackPort int `kdl:"fallback-port"`
// Host is the target host (default: localhost)
Host string `kdl:"host"`
// Bind is the address the proxy listens on
// "127.0.0.1" (default) or "0.0.0.0" (all interfaces)
Bind string `kdl:"bind"`
// ListenPort is the explicit port the proxy binds to. When zero or
// unset, the hash-based stable allocator in
// proxy.DefaultPortForURL picks a port in the 10000-60000 range.
//
// When set, the proxy MUST bind to Bind:ListenPort or fail — the
// daemon does not silently fall back to an auto-assigned port, and
// the runtime Start() path honors StrictListenPort so a bind
// conflict surfaces as a visible error event instead of getting
// papered over with a random port. Intended for CORS origin
// registration, shareable dev URLs that must not drift across
// sessions, and reverse proxies to external hostnames that pin to
// a specific listen port.
ListenPort int `kdl:"listen-port"`
// SkipTLSVerify disables TLS certificate verification on the
// upstream (target) connection. Defaults to false — certs are
// verified. Set to true to proxy to targets with self-signed,
// expired, or otherwise untrusted certificates (common in local
// dev environments with wildcard self-signed certs). The listen
// side of the proxy is unaffected; this only controls the client
// TLS config used when dialing the upstream URL.
SkipTLSVerify bool `kdl:"skip-tls-verify"`
// AllowExternal permits binding to non-localhost addresses
// (0.0.0.0, ::). Required opt-in when Bind is set to a
// non-localhost value; otherwise proxym.Create rejects the
// bind to prevent accidental network exposure. Only surfaced
// via the MCP tool path (PROXY START JSON extension); .agnt.kdl
// autostart proxies must set `allow-external` explicitly for
// the same gate to open.
AllowExternal bool `kdl:"allow-external"`
// PublicURL is the externally-visible URL for tunnel services
// (e.g. "https://abc123.trycloudflare.com"). Informs the URL
// rewriter so Location headers and absolute links are
// rewritten to the public host instead of the bound listen
// addr. Mirrors proxy.ProxyConfig.PublicURL; surfaced via MCP
// tool JSON (`public_url`) and KDL (`public-url`).
PublicURL string `kdl:"public-url"`
// Websocket enables WebSocket proxying
Websocket bool `kdl:"websocket"`
// WaitFor lists script ids that must reach Running Healthy (or
// Running With Errors) before this proxy begins forwarding
// requests. While any entry is pending, the proxy binds and is
// visible to `proxy list`, but every incoming request receives a
// 503 with the `agnt_proxy_not_ready` sentinel body. When every
// listed script signals ready (URL detected, port bound, or
// ready-signal fired), the proxy flips to ready atomically.
//
// The proxy is a readiness gate, not a build gate. Per
// .claude/rules/daemon-lifecycle.md, a process that is bound and
// producing output (including compile errors) counts as "running"
// — the readiness signal fires as soon as the port is listening,
// regardless of whether the child is in a clean or errored state.
//
// Every entry must resolve to a declared script in the same
// `scripts {}` block; unknown names fail config parsing. Proxy →
// proxy dependencies are not supported.
WaitFor []string `kdl:"wait-for"`
}
ProxyConfig defines a reverse proxy to start.
func (*ProxyConfig) HasExplicitTarget ¶ added in v0.11.5
func (p *ProxyConfig) HasExplicitTarget() bool
HasExplicitTarget returns true if the proxy has an explicitly configured target (URL, Target, or Port) rather than being linked to a script for URL detection.
func (*ProxyConfig) ShouldAutostart ¶ added in v0.11.5
func (p *ProxyConfig) ShouldAutostart() bool
ShouldAutostart returns true if this proxy should start automatically. A proxy auto-starts if Autostart is explicitly true, or if it has an explicit target (URL/Target/Port) without being script-linked (script-linked proxies are created automatically when URLs are detected in script output).
type PushConfig ¶ added in v0.12.36
type PushConfig struct {
// MCPNotifications controls delivery via MCP session.Log().
// Works natively in Claude Desktop; may be dropped by other clients.
// Defaults to true when unset.
MCPNotifications *bool `kdl:"mcp-notifications"`
// PTYInjection controls delivery via stdin typing into the PTY.
// Universal channel that works in all clients (Claude Code, OpenCode, etc).
// Defaults to true when unset.
PTYInjection *bool `kdl:"pty-injection"`
}
PushConfig controls which push channels are active for delivering alerts to the AI client. When no push config is present, all channels are enabled (universal behavior).
func PresetPushConfig ¶ added in v0.12.36
func PresetPushConfig(name string) *PushConfig
PresetPushConfig returns a PushConfig for the named preset. Returns nil for unknown preset names.
func (*PushConfig) MCPNotificationsEnabled ¶ added in v0.12.36
func (c *PushConfig) MCPNotificationsEnabled() bool
MCPNotificationsEnabled returns whether MCP notification delivery is enabled. Defaults to true when the config is nil or the field is unset.
func (*PushConfig) PTYInjectionEnabled ¶ added in v0.12.36
func (c *PushConfig) PTYInjectionEnabled() bool
PTYInjectionEnabled returns whether PTY stdin injection is enabled. Defaults to true when the config is nil or the field is unset.
type ResponseHookConfig ¶ added in v0.7.8
type ResponseHookConfig struct {
// Toast shows a toast notification in the browser
Toast bool `kdl:"toast"`
// Indicator updates the bug indicator
Indicator bool `kdl:"indicator"`
// Sound plays a notification sound
Sound bool `kdl:"sound"`
}
ResponseHookConfig controls response notification behavior.
type ScriptConfig ¶ added in v0.7.8
type ScriptConfig struct {
// Run is a shell command string (executed via platform shell)
// On Unix: sh -c "..."
// On Windows: cmd.exe /c "..."
// Override with Shell field
Run string `kdl:"run"`
// Command is the executable name (used with Args)
Command string `kdl:"command"`
// Args are command arguments (used with Command)
Args []string `kdl:"args"`
// Shell overrides the shell used for "run" commands.
// Examples: "bash", "powershell", "cmd.exe", "sh"
// If empty, uses platform default (sh on Unix, cmd.exe on Windows)
Shell string `kdl:"shell"`
// ShellArgs overrides the shell arguments. Default: ["-c"] for sh/bash, ["/c"] for cmd.exe
ShellArgs []string `kdl:"shell-args"`
// Autostart starts the script when session opens
Autostart bool `kdl:"autostart"`
// URLMatchers are patterns for URL detection in output
URLMatchers []string `kdl:"url-matchers"`
// Env are environment variables for the script
Env map[string]string `kdl:"env"`
// Cwd is the working directory for the script
Cwd string `kdl:"cwd"`
// DependsOn lists scripts that must be ready before this script starts.
DependsOn DependsOnList `kdl:"depends-on"`
// Ports lists the ports this script uses. Used for pre-flight orphan cleanup
// and EADDRINUSE recovery. Multiple ports supported (e.g., API + WebSocket).
Ports []int `kdl:"ports"`
// AutoRestart enables automatic restart when the process exits.
// Default: false — user restarts manually from the overlay.
AutoRestart bool `kdl:"auto-restart"`
// Hooks defines optional shell commands run at process lifecycle transitions.
Hooks *ScriptLifecycleHooks `kdl:"hooks"`
}
ScriptConfig defines a script to run.
func (*ScriptConfig) ResolveShell ¶ added in v0.12.1
func (s *ScriptConfig) ResolveShell() (shell string, shellArgs []string)
ResolveShell returns the shell command and arguments for executing a "run" command. Priority: explicit Shell/ShellArgs config > WSL Windows-path detection > platform default.
The WSL Windows-path branch fixes the silent-failure case where the script lives on the Windows filesystem (cwd is /mnt/c/... or run is a .cmd / .bat / powershell-only command) but the daemon is running under WSL Linux. Without this branch the daemon hands the script to `sh -c`, sh fails to interpret Windows path separators or .cmd/.bat semantics, and the failure surfaces as a confusing "command not found" deep in the script.
type ScriptDependency ¶ added in v0.12.8
type ScriptDependency struct {
// Name is the name of the script this depends on.
Name string
// Timeout is how long to wait for the dependency to become ready.
// Zero means wait indefinitely (until the autostart context is cancelled
// or the dependency's ready signal arrives). A positive value enforces
// a hard upper bound on the wait — only set when the user explicitly
// configures `timeout=N` in .agnt.kdl.
Timeout time.Duration
}
ScriptDependency represents a dependency on another script.
type ScriptLifecycleHooks ¶ added in v0.13.4
type ScriptLifecycleHooks struct {
// OnStart fires after the process transitions to Running state.
OnStart string `kdl:"on-start"`
// OnStop fires after a clean process exit (user-initiated or expected).
OnStop string `kdl:"on-stop"`
// OnCrash fires after an unexpected exit (non-zero code, not user-initiated).
OnCrash string `kdl:"on-crash"`
// OnRestart fires before each auto-restart attempt.
OnRestart string `kdl:"on-restart"`
}
ScriptLifecycleHooks defines shell commands run at process lifecycle transitions. Each field is a shell command string executed via the platform shell (same as ScriptConfig.Run). Hooks run with a 5-second timeout and inherit the script's effective environment. Injected env vars: AGNT_EVENT, AGNT_SCRIPT_ID, AGNT_EXIT_CODE (stop/crash only).
type SessionConfig ¶ added in v0.12.41
type SessionConfig struct {
// OrphanPGIDScan controls whether daemon startup scans /proc for
// orphaned POSIX process groups (pgid leader dead, members still
// running) and kills them. Defaults to true.
//
// This handles the case where the daemon crashed or was restarted
// mid-session: the SessionRegistry is lost so slice-A session-pgid
// tracking cannot fire on cleanup. The startup scan is the crash-
// recovery fallback.
//
// Set to false to disable if the scan is interfering with other
// long-running session leaders on the system (e.g. a tmux session
// daemon that shares a pgid layout the scan cannot distinguish).
OrphanPGIDScan *bool `kdl:"orphan-pgid-scan"`
}
SessionConfig controls daemon-side session lifecycle behaviors.
The daemon reads this at startup to decide which cleanup steps run. Every field must stay optional so a project with no `session {}` block still gets sensible defaults from DefaultAgntConfig().
func (*SessionConfig) OrphanPGIDScanEnabled ¶ added in v0.12.41
func (c *SessionConfig) OrphanPGIDScanEnabled() bool
OrphanPGIDScanEnabled returns whether orphaned-pgid scanning is enabled at daemon startup. Defaults to true when the SessionConfig block is absent or the field is unset.
type Settings ¶
type Settings struct {
// DefaultTimeout is the default process timeout.
DefaultTimeout time.Duration `json:"default_timeout"`
// MaxOutputBuffer is the per-stream output buffer size.
MaxOutputBuffer int `json:"max_output_buffer"`
// GracefulTimeout is the graceful shutdown timeout.
GracefulTimeout time.Duration `json:"graceful_timeout"`
}
Settings holds global configuration settings.
type SetupConfig ¶ added in v0.13.10
type SetupConfig struct {
// RenudgeTTLDays is the number of days to suppress the setup nudge
// after a negative outcome. Defaults to 7 when unset or non-positive.
RenudgeTTLDays *int `kdl:"renudge-ttl-days"`
}
SetupConfig controls the first-run setup nudge for `agnt run`.
When `agnt run <agent>` is invoked in a project with no `.agnt.kdl`, the run command drives a one-time setup phase. If the user declines (no config is written), a timestamped marker is recorded and the nudge is suppressed until the re-nudge TTL elapses. Every field stays optional so a project with no `setup {}` block still gets sensible defaults.
setup {
renudge-ttl-days 7
}
func (*SetupConfig) RenudgeTTL ¶ added in v0.13.10
func (c *SetupConfig) RenudgeTTL() time.Duration
RenudgeTTL returns the re-nudge suppression window. Defaults to 7 days when the SetupConfig block is absent or the value is unset/non-positive.
type ToastConfig ¶ added in v0.7.8
type ToastConfig struct {
// Duration in milliseconds (default 4000)
Duration int `kdl:"duration"`
// Position: "top-right", "top-left", "bottom-right", "bottom-left"
Position string `kdl:"position"`
// MaxVisible is the max number of visible toasts (default 3)
MaxVisible int `kdl:"max-visible"`
}
ToastConfig configures toast notifications.