Documentation
¶
Overview ¶
Package daemon implements the long-running ttal manager-plane process.
The daemon starts all agent sessions (tmux for Claude Code, HTTP adapters for OpenCode/OpenClaw), bridges messages between Telegram and agent runtimes via a Unix socket, watches JSONL output files to forward agent responses to Telegram, and manages the worker lifecycle through fsnotify-based cleanup and PR watchers. It is managed by launchd and handles all inter-agent and human-agent messaging for every configured team from a single process.
Plane: manager
Index ¶
- func Install() error
- func IsRunning() (bool, int, error)
- func RegisterBotCommands(botToken string, allCommands []BotCommand) error
- func Restart() error
- func Run() error
- func Send(req SendRequest) error
- func SocketPath() (string, error)
- func Start() error
- func Stop() error
- func Uninstall() error
- type BotCommand
- type GetStatusRequest
- type QuestionBatch
- type SendRequest
- type SendResponse
- type StatusResponse
- type StatusUpdateRequest
- type TaskCompleteRequest
- type UsageData
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Install ¶
func Install() error
Install installs the launchd plist and creates a config template if needed.
func IsRunning ¶
IsRunning checks whether the daemon is running by inspecting the pid file. Uses fixed path at ~/.ttal/daemon.pid.
func RegisterBotCommands ¶
func RegisterBotCommands(botToken string, allCommands []BotCommand) error
RegisterBotCommands calls Telegram setMyCommands API to expose the command menu in the chat UI. Includes both static and discovered commands.
func Restart ¶
func Restart() error
Restart performs an atomic daemon restart using launchctl kickstart -k. This kills the running process and lets launchd relaunch it immediately, avoiding the race condition in a Stop+Start (bootout+bootstrap) sequence.
func Run ¶
func Run() error
Run starts the daemon in the foreground. This is what launchd calls. Config-driven: loads all teams from config.toml, no database required.
func Send ¶
func Send(req SendRequest) error
Send connects to the daemon socket and sends a message. Returns an error if the daemon is not running or if delivery fails. Auto-populates Team from TTAL_TEAM env if not set.
func SocketPath ¶
SocketPath returns the path to the daemon unix socket. TTAL_SOCKET_PATH overrides the default, which allows Docker workers to inject the host socket path via the container environment. Delegates to config.SocketPath() to keep a single source of truth.
Types ¶
type BotCommand ¶
type BotCommand struct {
Command string `json:"command"`
Description string `json:"description"`
OriginalName string `json:"-"` // original name before sanitization (for dispatch to agent)
}
BotCommand represents a Telegram bot command for the menu.
func AllCommands ¶
func AllCommands(discovered []BotCommand) []BotCommand
AllCommands returns the full command list: static commands + discovered dynamic commands.
func DiscoverCommands ¶
func DiscoverCommands(commandsPaths []string) []BotCommand
DiscoverCommands reads canonical command .md files from configured paths and returns BotCommand entries for Telegram registration.
type GetStatusRequest ¶
type GetStatusRequest struct {
Type string `json:"type"` // "getStatus"
Team string `json:"team,omitempty"` // team name (defaults to "default")
Agent string `json:"agent,omitempty"` // empty = all agents
}
Request is the top-level socket message envelope. GetStatusRequest queries agent status from the daemon. Wire format: {"type":"getStatus","agent":"kestrel"}
type QuestionBatch ¶
type QuestionBatch struct {
ShortID string
CorrelationID string
TeamName string
AgentName string
Runtime runtime.Runtime
Questions []runtime.Question
Answers map[int]string // questionIndex → selected answer text
CurrentPage int // 0-indexed
TelegramMsgID int
ChatID int64
BotToken string
CreatedAt time.Time
// contains filtered or unexported fields
}
QuestionBatch holds state for a pending multi-question interaction. All mutable fields (Answers, CurrentPage, TelegramMsgID) are protected by mu.
func (*QuestionBatch) AllAnswered ¶
func (b *QuestionBatch) AllAnswered() bool
AllAnswered returns true if every question has an answer.
type SendRequest ¶
type SendRequest struct {
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
Team string `json:"team,omitempty"`
Message string `json:"message"`
}
SendRequest is the JSON message sent to the daemon. Direction is determined by which fields are set:
From only: agent → human via Telegram To only: system/hook → agent via tmux From + To: agent → agent via tmux with attribution
Team disambiguates when agent names collide across teams. Auto-populated from TTAL_TEAM env if unset.
type SendResponse ¶
SendResponse is the JSON reply from the daemon.
type StatusResponse ¶
type StatusResponse struct {
OK bool `json:"ok"`
Agents []status.AgentStatus `json:"agents,omitempty"`
Error string `json:"error,omitempty"`
}
StatusResponse returns agent status data.
func QueryStatus ¶
func QueryStatus(team, agent string) (*StatusResponse, error)
QueryStatus connects to the daemon socket and queries agent status.
type StatusUpdateRequest ¶
type StatusUpdateRequest struct {
Type string `json:"type"` // "statusUpdate"
Team string `json:"team,omitempty"` // team name (defaults to "default")
Agent string `json:"agent"` // agent name
ContextUsedPct float64 `json:"context_used_pct"` // percentage of context used
ContextRemainingPct float64 `json:"context_remaining_pct"` // percentage remaining
ModelID string `json:"model_id"` // model identifier
SessionID string `json:"session_id"` // session identifier
}
StatusUpdateRequest writes agent context status to the daemon. Wire format: {"type":"statusUpdate","agent":"kestrel","context_used_pct":45.2,...}
type TaskCompleteRequest ¶ added in v1.0.0
type TaskCompleteRequest struct {
Type string `json:"type"` // "taskComplete"
TaskUUID string `json:"task_uuid"`
Team string `json:"team,omitempty"` // defaults to "default"
Spawner string `json:"spawner,omitempty"` // "team:agent", optional
Desc string `json:"desc,omitempty"` // task description for the notification message
PRID string `json:"pr_id,omitempty"` // PR number for the notification message
}
TaskCompleteRequest notifies the daemon that a task has been marked done. Wire format: {"type":"taskComplete","task_uuid":"...","team":"default",...}
type UsageData ¶ added in v1.0.0
type UsageData struct {
SessionUsage *float64 `json:"sessionUsage,omitempty"`
SessionResetAt string `json:"sessionResetAt,omitempty"`
WeeklyUsage *float64 `json:"weeklyUsage,omitempty"`
WeeklyResetAt string `json:"weeklyResetAt,omitempty"`
FetchedAt time.Time `json:"fetchedAt"`
Error string `json:"error,omitempty"`
}
UsageData holds the parsed Claude.ai usage response.