Documentation
¶
Overview ¶
Package hooks provides a system for executing scripts on task events.
Index ¶
- Constants
- func ActionEnv(p Plugin, task *db.Task) []string
- func DefaultHooksDir() string
- func DefaultPluginsDir() string
- func EnsureHooksDir() (string, error)
- func FindAction(plugins []Plugin, pluginName, actionID string) (Plugin, Action, error)
- func PluginRoutineDirs(pluginsDir string) []string
- func PluginWorkflowDirs(pluginsDir string) []string
- func RunAction(ctx context.Context, p Plugin, a Action, task *db.Task) ([]byte, error)
- type Action
- type Plugin
- type Runner
- type Service
- type ServiceSet
Constants ¶
const ( EventTaskBlocked = "task.blocked" EventTaskDone = "task.done" EventTaskFailed = "task.failed" EventTaskStarted = "task.started" EventAuthRequired = "task.auth_required" // Executor session needs re-authentication )
Event types for hooks
const ActionTimeout = 60 * time.Second
ActionTimeout bounds how long a user-invoked action may run. Actions are synchronous (their output is shown to the user), so this is more generous than the fire-and-forget hook timeout.
const ManifestName = "plugin.yaml"
ManifestName is the file every plugin directory must contain to be loaded.
Variables ¶
This section is empty.
Functions ¶
func ActionEnv ¶ added in v0.3.18
ActionEnv builds the environment for a plugin action. task may be nil when an action is invoked without a task in context; the TASK_* vars are then omitted.
func DefaultHooksDir ¶
func DefaultHooksDir() string
DefaultHooksDir returns the default hooks directory path.
func DefaultPluginsDir ¶ added in v0.3.18
func DefaultPluginsDir() string
DefaultPluginsDir returns the plugins directory path. The TY_PLUGINS_DIR environment variable overrides the default (~/.config/task/plugins), which is handy for relocating plugins and for test isolation.
func EnsureHooksDir ¶
EnsureHooksDir creates the hooks directory if it doesn't exist.
func FindAction ¶ added in v0.3.18
FindAction locates a plugin and action by name/id across the given plugins.
func PluginRoutineDirs ¶ added in v0.3.19
PluginRoutineDirs returns the routines/ subdir of every installed plugin that ships one. The routine package folds these into its search path, so a plugin's routines become resolvable by `ty run <name>` and visible in `ty routines`.
func PluginWorkflowDirs ¶ added in v0.3.18
PluginWorkflowDirs returns the workflows/ subdir of every installed plugin that actually ships one. The pipeline registry feeds these into its workflow search path, so an installed plugin's workflows become resolvable by `ty pipeline -d`.
Types ¶
type Action ¶ added in v0.3.18
type Action struct {
ID string `yaml:"id"` // stable identifier, unique within the plugin
Label string `yaml:"label"` // human-facing label; defaults to ID if empty
Command string `yaml:"command"` // script path, relative to the plugin dir
}
Action is a user-triggered plugin command.
func (Action) DisplayLabel ¶ added in v0.3.18
DisplayLabel returns the label, falling back to the ID.
type Plugin ¶ added in v0.3.18
type Plugin struct {
Name string `yaml:"name"`
Version string `yaml:"version"`
Description string `yaml:"description"`
// Hooks maps a task event name (e.g. "task.done") to a script path,
// resolved relative to the plugin directory. Hooks fire automatically.
Hooks map[string]string `yaml:"hooks"`
// Actions are user-invoked commands (from `ty plugins run`, the detail-view
// picker, or the command palette), each backed by a script in the plugin dir.
Actions []Action `yaml:"actions"`
// Services are long-running processes the daemon supervises for the plugin's
// lifetime — a sidecar/service an extension used to run on its own (e.g. an MCP
// proxy, a sync loop). Started when the daemon comes up, stopped when it exits.
Services []Service `yaml:"services"`
// Dir is the absolute path to the plugin directory (not from the manifest).
Dir string `yaml:"-"`
// Workflows holds the names (filename stems) of the workflow definitions this
// plugin ships in its workflows/ subdir. Discovered by convention at load time,
// not declared in the manifest — a plugin is workflow cargo the moment it has a
// workflows/*.yaml. Populated for display; the definitions themselves are loaded
// by the pipeline registry via PluginWorkflowDirs.
Workflows []string `yaml:"-"`
// Routines holds the names of the routine definitions this plugin ships in its
// routines/ subdir (each a <name>/prompt.md). Discovered by convention, like
// workflows. Populated for display; the routine package resolves the definitions
// via PluginRoutineDirs. A routine is the right home for a plugin's periodic job
// (a poller, a digest): the daemon-supervised alternative, a service, is for
// processes that must stay up, not run-to-completion on a schedule.
Routines []string `yaml:"-"`
}
Plugin is a self-contained, droppable unit that reacts to task events.
A plugin is a directory under the plugins dir (default ~/.config/task/plugins/<name>/) containing a plugin.yaml manifest and the scripts it references. Unlike the legacy single-script hooks dir — where one file per event means two integrations collide — any number of plugins may each declare a handler for the same event, and all of them run.
func LoadPlugins ¶ added in v0.3.18
LoadPlugins discovers and validates every plugin under pluginsDir.
It is intentionally forgiving: a malformed or incomplete plugin is skipped (and reported via the returned warnings) rather than failing the whole load, so one bad community plugin can't break a user's task pipeline. A missing plugins dir is not an error — it just yields no plugins.
func (Plugin) RoutinesDir ¶ added in v0.3.19
RoutinesDir returns the plugin's routines subdir, whether or not it exists.
func (Plugin) ScriptFor ¶ added in v0.3.18
ScriptFor returns the absolute path to the script handling event, and whether the plugin handles that event at all.
func (Plugin) WorkflowsDir ¶ added in v0.3.18
WorkflowsDir returns the plugin's workflows subdir, whether or not it exists.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner executes hooks for task events.
func (*Runner) OnStatusChange ¶
OnStatusChange triggers appropriate hooks based on status transition.
type Service ¶ added in v0.3.19
type Service struct {
Name string `yaml:"name"` // stable label, unique within the plugin
Command string `yaml:"command"` // shell command to run (sh -c); the long-running process
Cwd string `yaml:"cwd"` // working dir relative to the plugin dir ("" = the plugin dir)
Env []string `yaml:"env"` // extra KEY=VALUE env entries for the process
}
Service is a long-running process a plugin ships and the daemon supervises. It's how an "extension" (a sidecar that used to run itself) folds into the plugin model: declare it here and the daemon starts/stops it. Command is run via `sh -c` from the plugin dir (or Cwd if set), so it can reference the plugin's own files.
type ServiceSet ¶ added in v0.3.19
type ServiceSet struct {
// contains filtered or unexported fields
}
ServiceSet is the collection of plugin services the daemon started. Hold onto it for the daemon's lifetime and call Stop on shutdown.
func StartServices ¶ added in v0.3.19
func StartServices(pluginsDir string, injectEnv []string, logger *log.Logger) *ServiceSet
StartServices starts every service declared by an installed plugin and returns a handle to stop them. Each service runs as `sh -c <command>` from its plugin dir (or Cwd, resolved relative to it), in its own process group so Stop can signal the whole tree. This is how a plugin folds a former "extension" sidecar under the daemon's lifecycle: it comes up with the daemon and goes down with it.
injectEnv is prepended to every service's environment (after the daemon's own environment, before the service's declared Env) — the daemon uses it to hand each service a stable way to find ty (TY_DB_PATH, TY_API_URL) without hardcoding paths or ports.
func (*ServiceSet) Count ¶ added in v0.3.19
func (s *ServiceSet) Count() int
Count reports how many services are running.
func (*ServiceSet) Stop ¶ added in v0.3.19
func (s *ServiceSet) Stop()
Stop signals every supervised service's process group with SIGTERM, waits briefly for a graceful exit, then SIGKILLs anything still alive.