daemon

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2026 License: MIT Imports: 43 Imported by: 0

Documentation

Overview

Package daemon implements the long-running ttal manager-plane process.

The daemon starts all agent sessions (tmux for Claude Code), 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

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

func IsRunning() (bool, int, error)

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 via HTTP. 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

func SocketPath() (string, error)

SocketPath returns the path to the daemon unix socket. TTAL_SOCKET_PATH overrides the default. Delegates to config.SocketPath() to keep a single source of truth.

func Start

func Start() error

Start boots the daemon launchd service.

func Stop

func Stop() error

Stop stops the daemon launchd service.

func Uninstall

func Uninstall() error

Uninstall removes the launchd plist and cleans up daemon files.

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 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

type SendResponse struct {
	OK    bool   `json:"ok"`
	Error string `json:"error,omitempty"`
}

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 and queries agent status via HTTP.

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.

Jump to

Keyboard shortcuts

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